Python Lasagne 教程:验证错误低于训练错误

机器算法验证 机器学习 神经网络 Python 退出
2022-04-09 04:19:52

在 Lasagne 教程(此处和此处的源代码)中,在 MNIST 数据集上训练了一个简单的多层感知器。数据分为训练集和验证集,训练计算每个时期的验证误差,表示为每批次的平均交叉熵误差。

但是,验证误差总是低于训练误差。为什么会这样?训练误差不应该更低,因为它是网络训练的数据吗?这可能是 dropout 层的结果(在训练期间启用,但在验证错误计算期间禁用)?

前几个时期的输出:

Epoch 1 of 500 took 1.858s
  training loss:                1.233348
  validation loss:              0.405868
  validation accuracy:          88.78 %
Epoch 2 of 500 took 1.845s
  training loss:                0.571644
  validation loss:              0.310221
  validation accuracy:          91.24 %
Epoch 3 of 500 took 1.845s
  training loss:                0.471582
  validation loss:              0.265931
  validation accuracy:          92.35 %
Epoch 4 of 500 took 1.847s
  training loss:                0.412204
  validation loss:              0.238558
  validation accuracy:          93.05 %
1个回答

这是一个可能的解释(但是很可能是错误的),也许您可​​以尝试修改他们的教程代码以查看这是否有效?

对于小批量下降方法,我们模型的参数在每个小批量后更新。请务必注意,在您发布的代码中,每个小批量的训练误差是使用一组不同的权重计算的。

另一方面,请注意,对于验证错误,它是使用相同的权重集计算的。

也许更重要的是,MLP 正在接受 Dropout 训练。同样,当我们计算训练错误时,与验证错误不同,我们不会关闭 Dropout。特别要注意,在验证函数的代码中,我们有 Deterministic = True ,而训练函数中没有。

特别注意,使用 Dropout 的目的是防止过度拟合,即训练误差低于验证误差。为此,我们看到 Dropout 做得很好,因为如今即使是相对较浅的模型也很容易过拟合 MNIST 数据集。

因此,您可以尝试以下方法:在每个 epoch 训练之后,在训练集和验证集上运行 val_fn。这将以通过训练集进行额外的完整前向传递为代价。但是对于 MNIST 和像 MLP 这样的简单模型,它不会在计算方面花费太多,而且可能值得你动手修改一些 Lasagne 代码以及建立一些关于 minibatch + Dropout 训练的一般直觉.