Tensorflow Keras - 训练时准确率高,预测时准确率低
Posted
技术标签:
【中文标题】Tensorflow Keras - 训练时准确率高,预测时准确率低【英文标题】:Tensorflow Keras - High accuracy during training, low accuracy during prediction 【发布时间】:2020-10-17 13:39:48 【问题描述】:我有一个非常基本的多类 CNN 模型,用于将车辆分为 4 类[pickup, sedan, suv, van]
,我使用 Tensorflow 2.0 tf.keras 编写了该模型:
he_initialiser = tf.keras.initializers.VarianceScaling()
model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(32, kernel_size=(3,3), input_shape=(3,128,128), activation='relu', padding='same', data_format='channels_first', kernel_initializer=he_initialiser))
model.add(tf.keras.layers.Conv2D(32, kernel_size=(3,3), activation='relu', padding='same', data_format='channels_first', kernel_initializer=he_initialiser))
model.add(tf.keras.layers.MaxPooling2D((2, 2), data_format=cfg_data_fmt))
model.add(tf.keras.layers.Conv2D(64, kernel_size=(3,3), activation='relu', padding='same', data_format='channels_first', kernel_initializer=he_initialiser))
model.add(tf.keras.layers.Conv2D(64, kernel_size=(3,3), activation='relu', padding='same', data_format='channels_first', kernel_initializer=he_initialiser))
model.add(tf.keras.layers.MaxPooling2D((2, 2), data_format=cfg_data_fmt))
model.add(tf.keras.layers.Conv2D(128, kernel_size=(3,3), activation='relu', padding='same', data_format='channels_first', kernel_initializer=he_initialiser))
model.add(tf.keras.layers.Conv2D(128, kernel_size=(3,3), activation='relu', padding='same', data_format='channels_first', kernel_initializer=he_initialiser))
model.add(tf.keras.layers.MaxPooling2D((2, 2), data_format='channels_first'))
model.add(tf.keras.layers.Flatten(data_format='channels_first'))
model.add(tf.keras.layers.Dense(128, activation='relu', kernel_initializer=he_initialiser))
model.add(tf.keras.layers.Dense(128, activation='relu', kernel_initializer=he_initialiser))
model.add(tf.keras.layers.Dense(4, activation='softmax', kernel_initializer=he_initialiser))
我使用以下配置进行训练:
图像尺寸:3x128x128(平面数据) 时期数:45 批量大小:32 损失函数:tf.keras.losses.CategoricalCrossentropy(from_logits=True)
优化器:optimizer=tf.optimizers.Adam
训练数据大小:占所有数据的 67.5%
验证数据大小:所有数据的 12.5%
测试数据大小:所有数据的 20%
我有一个不平衡的数据集,其分布如下:
pickups: 1202
sedans: 1954
suvs: 2510
vans: 196
出于这个原因,我使用了类权重来缓解这种不平衡:
pickup_weight: 4.87
sedan_weight: 3.0
suv_weight: 2.33
van_weight: 30.0
这似乎是一个小数据集,但我将其用于微调,因为我首先在这些类别的 16k 图像的更大数据集上训练模型,尽管与我的微调数据集相比,车辆图像是从不同角度拍摄的.
现在我的问题源于以下观察:
在最后一个epoch结束时,model.fit
返回的结果是:
model.evaluate
在训练后在我的保留测试集上返回的结果给出了与上一个 epoch 中相应的验证值相似的准确度和损失值,并且每个类的精度值也几乎与相应的验证精度相同.
较低但仍然足够高的验证准确度让我相信没有过度拟合问题,因为模型可以泛化。
我的第一个问题是验证损失怎么会比训练损失低这么多?
此外,当我使用以下方法创建混淆矩阵时:
test_images = np.array([x[0].numpy() for x in list(labeled_ds_test)])
test_labels = np.array([x[1].numpy() for x in list(labeled_ds_test)])
test_predictions = model.predict(test_images, batch_size=32)
print(tf.math.confusion_matrix(tf.argmax(test_labels, 1), tf.argmax(test_predictions, 1)))
我得到的结果是:
tf.Tensor(
[[ 42 85 109 3]
[ 72 137 177 4]
[ 91 171 228 11]
[ 9 12 16 1]], shape=(4, 4), dtype=int32)
这表明准确率只有 35%!!
我的第二个问题因此是这样的:model.predict
给出的准确度怎么会如此之小,而在训练和评估期间,这些值似乎表明我的模型是它的预测相当准确?
我使用的预测方法是错误的,还是我对预期会发生什么的理论理解完全错误?
我在这里有点茫然,非常感谢任何反馈。感谢您阅读本文。
【问题讨论】:
当训练准确率很高,而预测准确率很低时,这肯定是过拟合的迹象。我建议调查过度拟合的原因和解决方案。 【参考方案1】:我同意@gallen。有几个原因会导致过拟合以及几种防止过拟合的方法。一个好的解决方案是在层之间添加 dropout。你可以看到*** answer和towardsdatascience article
【讨论】:
【参考方案2】:当然存在过度拟合,但让我们回答问题。
对于第一个问题,由于损失是y_true
和y_pred
中所有差异的总和,因此验证数据的数量少是其损失小于训练数据的原因。
至于第二个问题,即使验证没有显示任何过度拟合的迹象,测试准确度怎么会低于预期?
验证集的分布必须与测试集的分布相同,以免错过领先。
所以我的建议是分别检查训练、验证和测试数据集的分布。确保它们相同。
【讨论】:
【参考方案3】:您需要正确划分数据集,例如 70% 的训练和 30% 的验证,然后将新数据集作为测试数据检查您的模型,这可能会有所帮助,因为机器学习就是反复试验。
【讨论】:
以上是关于Tensorflow Keras - 训练时准确率高,预测时准确率低的主要内容,如果未能解决你的问题,请参考以下文章
使用Python,Keras和TensorFlow训练第一个CNN
训练准确性增加,然后偶尔突然下降。使固定? [Keras] [TensorFlow 后端]
为啥在同一数据集上使用 tensorflow 和 keras 重新训练的 Inception V3 显示出不同的准确性?
TensorFlow 低级模型(没有 Keras 和 Sklearn) - 每一步都获得损失 = 0 和准确度 = 100%