1.问题
问题描述:在进行神经网络训练时,发现验证集的准确率比训练集还要高,觉得太不正常了,不知道问题出在哪里。我们训练模型的方式就是在训练集上最小化损失。因此,模型在训练集上有着更好的表现,才应该是正常的现象。因为原来训练的时候验证集的准确率都比训练集准确率低很多,这一下反过来,觉得有点蒙。
2.原因
在查找资料后,网络上普遍给出以下几种原因:
2.1模型正则化过多:
比如训练时Dropout过多,和验证时的模型相差较大,验证时是不会有Dropout的。Dropout能基本上确保测试集的准确性最好,优于训练集的准确性。Dropout迫使神经网络成为一个非常大的弱分类器集合,这就意味着,一个单独的分类器没有太高的分类准确性,只有当把他们串在一起的时候他们才会变得更强大。而且在训练期间,Dropout将这些分类器的随机集合切掉,因此,训练准确率将受到影响;在测试期间,Dropout将自动关闭,并允许使用神经网络中的所有弱分类器,因此,测试精度提高。
我只用了一次Dropout,去掉之后效果不明显。
2.2欠拟合
前几次一直在欠拟合,随着训练周期的增加,在训练集上的准确率又超过了测试集上的。
本来只训练了5轮,于是将epochs设置为20,发现后面轮次测试集准确率低于训练集,略低于。
Epoch 1/20
179/179 [==============================] - 6s 23ms/step - loss: 3.2855 - accuracy: 0.1603 - val_loss: 2.0219 - val_accuracy: 0.4047
Epoch 2/20
179/179 [==============================] - 4s 21ms/step - loss: 0.8360 - accuracy: 0.8041 - val_loss: 0.2702 - val_accuracy: 0.9605
Epoch 3/20
179/179 [==============================] - 4s 21ms/step - loss: 0.1305 - accuracy: 0.9837 - val_loss: 0.0828 - val_accuracy: 0.9930
Epoch 4/20
179/179 [==============================] - 4s 21ms/step - loss: 0.0499 - accuracy: 0.9948 - val_loss: 0.0498 - val_accuracy: 0.9943
Epoch 5/20
179/179 [==============================] - 4s 21ms/step - loss: 0.0360 - accuracy: 0.9959 - val_loss: 0.0350 - val_accuracy: 0.9953
Epoch 6/20
179/179 [==============================] - 4s 21ms/step - loss: 0.0227 - accuracy: 0.9970 - val_loss: 0.0289 - val_accuracy: 0.9959
Epoch 7/20
179/179 [==============================] - 4s 21ms/step - loss: 0.0189 - accuracy: 0.9976 - val_loss: 0.0267 - val_accuracy: 0.9965
Epoch 8/20
179/179 [==============================] - 4s 22ms/step - loss: 0.0159 - accuracy: 0.9972 - val_loss: 0.0293 - val_accuracy: 0.9943
Epoch 9/20
179/179 [==============================] - 4s 21ms/step - loss: 0.0144 - accuracy: 0.9979 - val_loss: 0.0185 - val_accuracy: 0.9969
Epoch 10/20
179/179 [==============================] - 4s 21ms/step - loss: 0.0118 - accuracy: 0.9977 - val_loss: 0.0221 - val_accuracy: 0.9963
Epoch 11/20
179/179 [==============================] - 4s 21ms/step - loss: 0.0115 - accuracy: 0.9977 - val_loss: 0.0182 - val_accuracy: 0.9967
Epoch 12/20
179/179 [==============================] - 4s 21ms/step - loss: 0.0130 - accuracy: 0.9978 - val_loss: 0.0268 - val_accuracy: 0.9937
Epoch 13/20
179/179 [==============================] - 4s 21ms/step - loss: 0.0546 - accuracy: 0.9881 - val_loss: 0.0627 - val_accuracy: 0.9859
Epoch 14/20
179/179 [==============================] - 4s 22ms/step - loss: 0.0217 - accuracy: 0.9952 - val_loss: 0.0268 - val_accuracy: 0.9943
Epoch 15/20
179/179 [==============================] - 4s 22ms/step - loss: 0.0095 - accuracy: 0.9981 - val_loss: 0.0153 - val_accuracy: 0.9975
Epoch 16/20
179/179 [==============================] - 4s 22ms/step - loss: 0.0095 - accuracy: 0.9982 - val_loss: 0.0167 - val_accuracy: 0.9969
Epoch 17/20
179/179 [==============================] - 4s 21ms/step - loss: 0.0082 - accuracy: 0.9984 - val_loss: 0.0142 - val_accuracy: 0.9969
Epoch 18/20
179/179 [==============================] - 4s 22ms/step - loss: 0.0075 - accuracy: 0.9986 - val_loss: 0.0134 - val_accuracy: 0.9975
Epoch 19/20
179/179 [==============================] - 4s 22ms/step - loss: 0.0093 - accuracy: 0.9982 - val_loss: 0.0140 - val_accuracy: 0.9971
Epoch 20/20
179/179 [==============================] - 4s 23ms/step - loss: 0.0200 - accuracy: 0.9950 - val_loss: 0.0255 - val_accuracy: 0.9945
2.3数据集太小
这样会导致数据集切分的时候不均匀,也就是说训练集和测试集的分布不均匀,如果模型能够正确地捕捉到数据内部的分布模式的话,就有可能造成训练集的内部方差大于验证集,会造成训练集的误差更大,这个时候就需要重新划分数据集,使其分布一样。
2.4小批量统计的滞后性
训练集的准确率是每个batch之后产生的,而验证集的准确率一般是一个epoch后产生的,验证时的模型是训练一个个batch之后的,有一个滞后性,可以说就是用训练得差不多的模型用来验证,当然准确率要高一点。(这个解释我没有get到,因为batch之后的准确率在不断变化,最终取得是最后一次batch的准确率,与一个epoch应该是一致的)
2.5数据预处理
训练集的数据做了一系列的预处理,如旋转、仿射、模糊、添加噪点等操作,过多的预处理导致训练集的分布产生了变化,所以使得训练集的准确率低于验证集
参考文献:
[1]模型训练时测试集上正确率大于训练集
[2]【深度学习】2-模型在测试集的准确率大于训练集
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。