【发布时间】: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返回的结果是:
- 训练准确率0.9229
- 3.5055的训练损失
- 验证准确率0.7906
- 验证损失0.9382
- pickup 类的训练精度为 0.9186
- 轿车类的训练精度0.9384
- suv 类的训练精度为 0.9196
- van 类的训练精度为 0.8378
- pickup 类的验证精度为 0.7805
- 轿车类的验证精度0.8026
- suv 类的验证精度为 0.0.8029
- van 类的验证精度为 0.4615
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 给出的准确度怎么会如此之小,而在训练和评估期间,这些值似乎表明我的模型是它的预测相当准确?
我使用的预测方法是错误的,还是我对预期会发生什么的理论理解完全错误?
我在这里有点茫然,非常感谢任何反馈。感谢您阅读本文。
【问题讨论】:
-
当训练准确率很高,而预测准确率很低时,这肯定是过拟合的迹象。我建议调查过度拟合的原因和解决方案。
标签: python tensorflow machine-learning keras deep-learning