【发布时间】:2021-02-01 01:20:39
【问题描述】:
这是 tf 2.3.0。在训练期间,报告的 SparseCategoricalCrossentropy 损失和 sparse_categorical_accuracy 的值似乎很遥远。我查看了我的代码,但还没有发现任何错误。这是要重现的代码:
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
x = np.random.randint(0, 255, size=(64, 224, 224, 3)).astype('float32')
y = np.random.randint(0, 3, (64, 1)).astype('int32')
ds = tf.data.Dataset.from_tensor_slices((x, y)).batch(32)
def create_model():
input_layer = tf.keras.layers.Input(shape=(224, 224, 3), name='img_input')
x = tf.keras.layers.experimental.preprocessing.Rescaling(1./255, name='rescale_1_over_255')(input_layer)
base_model = tf.keras.applications.ResNet50(input_tensor=x, weights='imagenet', include_top=False)
x = tf.keras.layers.GlobalAveragePooling2D(name='global_avg_pool_2d')(base_model.output)
output = Dense(3, activation='softmax', name='predictions')(x)
return tf.keras.models.Model(inputs=input_layer, outputs=output)
model = create_model()
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4),
loss=tf.keras.losses.SparseCategoricalCrossentropy(),
metrics=['sparse_categorical_accuracy']
)
model.fit(ds, steps_per_epoch=2, epochs=5)
这是打印出来的:
Epoch 1/5
2/2 [==============================] - 0s 91ms/step - loss: 1.5160 - sparse_categorical_accuracy: 0.2969
Epoch 2/5
2/2 [==============================] - 0s 85ms/step - loss: 0.0892 - sparse_categorical_accuracy: 1.0000
Epoch 3/5
2/2 [==============================] - 0s 84ms/step - loss: 0.0230 - sparse_categorical_accuracy: 1.0000
Epoch 4/5
2/2 [==============================] - 0s 82ms/step - loss: 0.0109 - sparse_categorical_accuracy: 1.0000
Epoch 5/5
2/2 [==============================] - 0s 82ms/step - loss: 0.0065 - sparse_categorical_accuracy: 1.0000
但是,如果我仔细检查 model.evaluate,并“手动”检查准确性:
model.evaluate(ds)
2/2 [==============================] - 0s 25ms/step - loss: 1.2681 - sparse_categorical_accuracy: 0.2188
[1.268101453781128, 0.21875]
y_pred = model.predict(ds)
y_pred = np.argmax(y_pred, axis=-1)
y_pred = y_pred.reshape(-1, 1)
np.sum(y == y_pred)/len(y)
0.21875
model.evaluate(...) 的结果与“手动”检查的指标一致。但如果你盯着训练中的损失/指标,它们看起来很遥远。因为从来没有抛出错误或异常,所以很难看出哪里出了问题。
此外,我创建了一个非常简单的案例来尝试重现这一点,但它实际上在这里无法重现。请注意,batch_size == 数据长度,因此这不是小批量 GD,而是全批量 GD(以消除与小批量损失/指标的混淆:
x = np.random.randn(1024, 1).astype('float32')
y = np.random.randint(0, 3, (1024, 1)).astype('int32')
ds = tf.data.Dataset.from_tensor_slices((x, y)).batch(1024)
model = Sequential()
model.add(Dense(3, activation='softmax'))
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4),
loss=tf.keras.losses.SparseCategoricalCrossentropy(),
metrics=['sparse_categorical_accuracy']
)
model.fit(ds, epochs=5)
model.evaluate(ds)
正如我在评论中提到的,一个嫌疑人是批量规范层,对于无法重现的情况,我没有。
【问题讨论】:
-
这是什么
tf.__version__? -
我想我可以用colab.research.google.com/github/keras-team/keras-io/blob/… 重现这个,我删除了 dropout 和 data_aug 以避免潜在的混淆。该笔记本中的损失/指标是不同的。我开始怀疑是否有一个良性的直截了当的解释
-
@NicolasGervais 2.3.0,我是在 google colab 上完成的
-
我怀疑这与模型中存在批处理规范层有关。我认为它的行为会有所不同,具体取决于 is_training 是否为真。
-
在重现这个错误时,我使用了非常非常小的数据集,我想知道批量规范是否会导致进度条上打印的损失/指标与小型集的真实数据存在如此大的偏差。指标比损失更可怕(我知道损失是小批量与整个批次),因为我认为它是通过 update_state(...) 调用“累积”的。
标签: tensorflow keras cross-entropy