为什么模型可以在 tensorflow(2.x)中以错误的尺寸安装 numpy 数组?

Why model could be fitted with numpy array in wrong dimensions in tensorflow(2.x)?

当我学习用tensorflow.keras.Model(tensorflow.version=2.0.0)建立模型时,我按照下面的方式编译我的模型:

import tensorflow as tf
x = tf.keras.layers.Input(shape=(2,))
y = tf.keras.layers.Dense(3, activation='softmax')(x)
model = tf.keras.Model(x,y)
model.compile(
    loss='binary_crossentropy',
    optimizer=tf.keras.optimizers.Adam(1e-4),
    metrics=['accuracy']
)

当我需要使用model.fit方法时,我做了一些尝试:

尝试 1:

model.fit(
    x=[[1,1],[2,2]],
    y=[[1,1,1],[2,2,2]],
    epochs=3
)

应该是正确的,所以运行结果是。

尝试 2:

model.fit(
    x=[[1,1],[2,2]],
    y=[[1,1],[2,2]],
    epochs=3
)

由于 y 的尺寸无法适应模型的输出,此代码应该会引发错误,并且我得到了一个 ValueError,例如 Dimensions must be equal, but are 2 and 3 for 'loss/dense_loss/mul' (op: 'Mul') with input shapes: [?,2], [?,3]。还是和预期的一样。

尝试 3:

model.fit(
    x=[[1,1],[2,2]],
    y=[[1],[2]],
    epochs=3
)

所以我认为这段代码也应该像Attempt 2一样线程错误,但是为什么模型可以拟合这样的训练数据?模型学到了什么?

我尝试了 运行 你来自 "Attempt 3" 的代码,但在使用 tensorflow==2.1.0-rc1 时遇到错误:

import tensorflow as tf
print(tf.__version__)
x = tf.keras.layers.Input(shape=(2,))
y = tf.keras.layers.Dense(3, activation='softmax')(x)
model = tf.keras.Model(x,y)
model.compile(
    loss='binary_crossentropy',
    optimizer=tf.keras.optimizers.Adam(1e-4),
    metrics=['accuracy']
)
model.fit(
    x=[[1,1],[2,2]],
    y=[[1],[2]],
    epochs=3
)
2.1.0-rc1
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-7-ab313c8f2b57> in <module>()
     12     x=[[1,1],[2,2]],
     13     y=[[1,1],[2,2]],
---> 14     epochs=3
     15 )

7 frames
/tensorflow-2.1.0/python3.6/tensorflow_core/python/keras/engine/training_utils.py in check_loss_and_target_compatibility(targets, loss_fns, output_shapes)
    808           raise ValueError('A target array with shape ' + str(y.shape) +
    809                            ' was passed for an output of shape ' + str(shape) +
--> 810                            ' while using as loss `' + loss_name + '`. '
    811                            'This loss expects targets to have the same shape '
    812                            'as the output.')

ValueError: A target array with shape (2, 2) was passed for an output of shape (None, 3) while using as loss `binary_crossentropy`. This loss expects targets to have the same shape as the output.

我很惊讶这将允许您在另一个 tf2 版本中进行训练——模型具有与您的 class 不同维度的输出层是没有意义的。你能澄清一下你从 "Attempt 3" 得到的输出吗(也许分享一个 colab)?

这可能是因为你选择了损失函数? BinaryCrossentropy 应该在只有两个标签 classes(假设为 0 和 1)时使用,这通常与单个输出相关联(例如 Dense(1))。换句话说,对于每个示例,每个预测都应该有一个浮点值。

如果使用 sparse_categorical_crossentropy:

,您也许可以让模型编译并拟合来自尝试三的数据
model.compile(
    loss='sparse_categorical_crossentropy',
    optimizer=tf.keras.optimizers.Adam(1e-4),
    metrics=['accuracy']
)

截至目前,您的损失似乎与您的输出维度不匹配。