Answers:
不知道您的实际方法(例如交叉验证方法,性能指标,数据拆分方法等)很难确定。
一般来说,训练错误几乎总是会低估您的验证错误。但是,验证误差有可能小于训练误差。您可以通过两种方式来考虑:
这就是为什么真正评估模型训练方法很重要的原因。如果您不对数据进行适当的培训,那么结果将导致令人困惑的结论,即使不是简单的错误。
我认为模型评估分为四个不同的类别:
拟合不足-验证和培训错误高
过拟合–验证误差高,训练误差低
适合度高–验证误差低,略高于训练误差
未知拟合度-验证错误低,训练错误“高”
我说“未知”适合,因为结果与机器学习的工作原理相反。机器学习的本质是预测未知数。如果您比“学习”的知识更能预测未知数,则AFAIK训练和验证之间的数据必须有所不同。这可能意味着您要么需要重新评估数据拆分方法,添加更多数据,要么可能需要更改性能指标(您实际上是在测量所需的性能吗?)。
编辑
为了解决OP对先前的python 千层面问题的引用。
这表明您有足够的数据,不需要交叉验证,而只需训练,验证和测试数据子集。现在,如果您查看烤宽面条教程,您会发现在页面顶部看到了相同的行为。我很难相信如果奇怪的话作者会发布这样的结果,但我们不只是假设它们是正确的,而是让我们进一步看。我们最感兴趣的部分是训练循环部分,在底部的正上方,您将看到如何计算损耗参数。
该培训的损失是在计算出整个训练数据集。同样,在整个验证数据集上计算验证损失。训练集通常至少是验证(80-20)的4倍。假设误差是在所有样本上计算得出的,则可以预期损失约为验证集损失度量的4倍。但是,您会注意到,随着培训的继续,培训损失和验证损失正在接近。这是有意的,好像您的训练错误开始变得低于验证错误一样,您将开始过拟合模型!!!
我希望这可以澄清这些错误。
一种可能性:如果您在网络中使用辍学正则化层,则验证错误小于训练错误是合理的。因为通常在训练时退出会被激活,而在验证集上进行评估时会被取消激活。在后一种情况下,您可以获得更流畅的功能(通常意味着更好)。
我没有足够的观点来评论@DK的答案,但是现在作为Keras文档的常见问题解答来回答:
“为什么培训损失比测试损失高得多?
Keras模型具有两种模式:训练和测试。在测试时会关闭诸如Dropout和L1 / L2权重正则化等正则化机制。
此外,训练损失是每批训练数据损失的平均值。由于您的模型会随着时间而变化,因此,前几个时期的损失通常高于最后几个时期的损失。另一方面,一个时期的测试损失是使用模型计算的,因为它处于该时期的末尾,因此损失较低。”
我的2美分:即使没有辍学层,我也遇到了同样的问题。就我而言-批处理规范层是罪魁祸首。当我删除它们时,训练损失变得类似于验证损失。之所以发生这种情况,可能是因为在训练期间,批次范数使用给定输入批次的均值和方差,这在批次之间可能会有所不同。但是在评估过程中,批次规范使用运行均值和方差,这两者都反映了整个训练集的属性,比训练期间单个批次的均值和方差要好得多。至少,这就是在pytorch中实现批处理规范的方式
通过某种方式组合@cdeterman和@DK的答案的另一种可能性是,如果您使用某种数据增强机制。事实数据的增强通常仅对训练集而不是对验证集进行(对于辍学正则化),这可能导致验证集包含比训练集中的情况更容易预测的案例。
@cdeterman和@DK有很好的解释。我还要再说一个理由- data leakage
。训练数据的某些部分与测试数据“密切相关”。
潜在的例子:假设您有1000只狗和1000只猫,每只宠物有500张相似的照片(有些主人喜欢以非常相似的姿势拍摄他们的宠物的照片)。因此,如果您随机进行70/30分割,则会使火车数据泄漏到测试数据中。
目前,基于随机梯度的方法几乎始终是深度学习的首选算法。这意味着数据将成批输入,计算梯度并更新参数。这意味着您还可以在选择每个批次时计算数据损失。在此框架下,有两种方式如何损失的计算,我能想到的可能会导致这种现象的训练误差大于验证错误更大。在下面,我表明Keras实际上似乎是通过这些方式计算样本内误差的。
1.)训练误差是在整个时期内平均的,而不是在时期末一次平均,但是验证误差仅在时期末。请注意,验证错误具有完全更新的优势,而训练错误包括更新次数较少的错误计算。当然,渐近地,这种效果通常应该消失。
2.)在批量更新之前计算训练误差。在基于随机梯度的方法中,梯度会有些噪声。当人们在爬山时,很有可能减少所有训练样本计算得出的整体损失。但是,当一个模式非常接近该模式时,相对于批次中的样本,更新方向将为负。但是,由于我们围绕某个模式反弹,这意味着平均而言,我们必须选择一个相对于样本输出为正的方向批次。现在,如果我们要针对给定批次中的样本进行更新,则意味着它们已经被潜在的许多未包含在其中的批次更新所推动,通过计算更新前的损失,这就是随机的方法已将参数推向最有利于数据集中其他样本的位置,从而使我们在预期损失上的偏差较小。
请注意,虽然渐近,但(1)的效果消失了,(2)的效果没有消失!下面我显示Keras似乎同时执行(1)和(2)。
(1)表明指标是每个时期的平均批次,而不是最后一次全部。请注意,在第一个时期,样本内准确性与val_accuracy的巨大差异有利于val_accuracy。这是因为一些样本内错误是通过很少的批处理更新来计算的。
>>> model.fit(Xtrn, Xtrn, epochs = 3, batch_size = 100,
... validation_data = (Xtst, Xtst))
Train on 46580 samples, validate on 1000 samples
Epoch 1/3
46580/46580 [==============================] - 8s 176us/sample
- loss: 0.2320 - accuracy: 0.9216
- val_loss: 0.1581 - val_accuracy: 0.9636
Epoch 2/3
46580/46580 [==============================] - 8s 165us/sample
- loss: 0.1487 - accuracy: 0.9662
- val_loss: 0.1545 - val_accuracy: 0.9677
Epoch 3/3
46580/46580 [==============================] - 8s 165us/sample
- loss: 0.1471 - accuracy: 0.9687
- val_loss: 0.1424 - val_accuracy: 0.9699
<tensorflow.python.keras.callbacks.History object at 0x17070d080>
(2)显示错误是在更新每个批次之前计算的。请注意,对于时代1,当我们使用batch_size = nRows
(即一批中的所有数据)时,对于时代1,样本内误差约为0.5(随机猜测),但验证误差为0.82。因此,样本内误差是在批量更新之前计算的,而验证误差是在批量更新之后计算的。
>>> model.fit(Xtrn, Xtrn, epochs = 3, batch_size = nRows,
... validation_data = (Xtst, Xtst))
Train on 46580 samples, validate on 1000 samples
Epoch 1/3
46580/46580 [==============================] - 9s 201us/sample
- loss: 0.7126 - accuracy: 0.5088
- val_loss: 0.5779 - val_accuracy: 0.8191
Epoch 2/3
46580/46580 [==============================] - 6s 136us/sample
- loss: 0.5770 - accuracy: 0.8211
- val_loss: 0.4940 - val_accuracy: 0.8249
Epoch 3/3
46580/46580 [==============================] - 6s 120us/sample
- loss: 0.4921 - accuracy: 0.8268
- val_loss: 0.4502 - val_accuracy: 0.8249