我有一个非常基本的多类CNN模型,用于将车辆分为Tensorflow 2.0 tf.keras编写的4类[pickup, sedan, suv, van]
:
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))
我使用以下配置进行培训:
tf.keras.losses.CategoricalCrossentropy(from_logits=True)
optimizer=tf.optimizers.Adam
我有一个不平衡的数据集,其分布如下:
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图像,尽管与我的微调数据集相比,从不同角度拍摄的车辆图像
现在我要提出的问题来自以下观察结果:
在最后一个时期结束时,model.fit
返回的结果为:
model.evaluate
在训练后在我的坚持测试集上返回的结果给出了与上一个时期中相应的验证值相似的准确性和损失值,并且每个类别的精度值也与相应的准确性几乎相同验证精度。
较低但仍然足够高的验证精度使我相信,该模型可以推广,不存在过度拟合的问题。
我的第一个问题 是:验证损失如何比训练损失那么低?
此外,当我使用以下方法创建混淆矩阵时:
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
给出的准确性如何在训练和评估过程中如此小的值似乎表明我的模型的预测非常精确?
我使用预测方法是错误的,还是我对预期发生的事情的理论理解是完全错误的?
我在这里有点茫然,非常感谢您的反馈。感谢您阅读本文。
答案 0 :(得分:0)
我同意@gallen。有多种原因可能导致过度拟合,并且有几种防止过度拟合的方法。好的解决方案之一是在各层之间添加丢包。您可以看到stackoverflow answer和towardsdatascience article
答案 1 :(得分:0)
当然有点过拟合,但是让我们回答问题。
对于第一个问题,验证数据的数量少是一个原因,为什么它的损失比训练数据少,因为损失是y_true
和y_pred
中所有差异的总和。
关于第二个问题,即使验证没有显示出过度拟合的迹象,测试准确性又如何会低于预期?
验证集的分布必须与测试集相同,以免误导。
所以我的建议是分别检查训练,验证和测试数据集的分布。确保它们相同。
答案 2 :(得分:0)
您需要正确划分数据集,例如 70% 的训练和 30% 的验证,然后在作为测试数据的新数据集上检查您的模型,这可能会有所帮助,因为机器学习就是反复试验。