繁体   English   中英

Tensorflow Keras - 训练时精度高,预测时精度低

[英]Tensorflow Keras - High accuracy during training, low accuracy during prediction

我有一个非常基本的多类 CNN model 用于将车辆分为 4 类[pickup, sedan, suv, van] ,我使用 Tensorflow 2.0 tf.Z063009BB15C0272BD0C:701CFDFDFDF

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
  • 损失 function: tf.keras.losses.CategoricalCrossentropy(from_logits=True)
  • 优化器: optimizer=tf.optimizers.Adam
  • 训练数据大小:所有数据的 67.5%
  • 验证数据大小:所有数据的 12.5%
  • 测试数据大小:所有数据的 20%

我有一个不平衡的数据集,它具有以下分布:

pickups: 1202
sedans: 1954
suvs: 2510
vans: 196

出于这个原因,我使用了 class 权重来减轻这种不平衡:

pickup_weight: 4.87
sedan_weight: 3.0
suv_weight: 2.33
van_weight: 30.0

这似乎是一个小数据集,但我使用它进行微调,因为我首先在这些类别的 16k 图像的更大数据集上训练 model,尽管与我的微调数据集相比,车辆图像是从不同角度拍摄的。

现在我的问题源于以下观察:

在最后一个 epoch 结束时, model.fit返回的结果给出:

  • 训练精度为0.9229
  • 训练损失3.5055
  • 验证准确度为0.7906
  • 验证损失0.9382
  • class的训练精度为0.9186
  • class轿车的训练精度为0.9384
  • class suv的训练精度为0.9196
  • class van的训练精度为0.8378
  • class拾音器的验证精度为0.7805
  • class轿车的验证精度为0.8026
  • class suv的验证精度为0.0.8029
  • class van的验证精度为0.4615

model.evaluate在训练后我的保留测试集上返回的结果给出了与最后一个时期的相应验证值相似的准确度和损失值,并且每个 class 的精度值也几乎与相应的验证精度相同。

较低但仍然足够高的验证准确度使我相信没有过度拟合问题,因为 model 可以概括。

我的第一个问题是验证损失怎么会比训练损失低这么多?

此外,当我使用以下方法创建混淆矩阵时:

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给出的准确度怎么会如此之小?

我使用预测方法是错误的,还是我对预期会发生的事情的理论理解完全错误?

我在这里有点茫然,非常感谢任何反馈。 感谢您阅读本文。

我同意@gallen。 有几个原因会导致过拟合以及几种防止过拟合的方法。 一个好的解决方案是在层之间添加 dropout。 你可以看到stackoverflow的答案朝向数据科学的文章

当然存在过度拟合,但让我们回答问题。

对于第一个问题,由于损失是y_truey_pred中所有差异的总和,所以验证数据的数量少是为什么它的损失小于训练数据的原因。

至于第二个问题,即使验证没有显示任何过度拟合的迹象,测试准确度怎么会低于预期?

验证集的分布必须与测试集相同,以免错过领先。

所以我的建议是分别检查训练、验证、测试数据集的分布。 确保它们相同。

您需要正确划分数据集,例如 70% 的训练和 30% 的验证,然后在新数据集上检查 model 作为测试数据,这可能会有所帮助,因为机器学习都是关于反复试验的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM