为什么验证准确率会波动?
如果我正确理解了准确度的定义,那么准确度(正确分类的数据点的百分比)的累积性要低于 MSE(均方误差)。这就是为什么你看到你loss
的速度在迅速增加,而准确性却在波动。
直观地说,这基本上意味着,示例的某些部分是随机分类的,这会产生波动,因为正确随机猜测的数量总是波动的(想象一下硬币应该总是返回“正面”时的准确性)。基本上对噪声的敏感性(当分类产生随机结果时)是过度拟合的常见定义(参见维基百科):
在统计和机器学习中,最常见的任务之一是将“模型”拟合到一组训练数据中,以便能够对一般未经训练的数据做出可靠的预测。在过拟合中,统计模型描述的是随机误差或噪声,而不是潜在的关系
过度拟合的另一个证据是你的损失正在增加,损失的测量更精确,如果它没有被 sigmoids/阈值压扁,它对嘈杂的预测更敏感(这似乎是你对损失本身的情况)。直观地说,您可以想象网络对输出过于确定(当它错误时)的情况,因此在随机错误分类的情况下,它给出的值远离阈值。
关于您的情况,您的模型没有正确规范化,可能的原因:
- 数据点不够,容量太大
- 订购
- 没有/错误的特征缩放/归一化
- 学习率:太大,所以SGD跳得太远,错过了局部最小值附近的区域。这将是“欠拟合”(对数据本身不敏感)的极端情况,但可能会通过扰乱来自输入的数据在输出上产生(某种)“低频”噪声 - 与过拟合的直觉相反,它将是就像预测硬币时总是猜正面一样。正如@JanKukacka 指出的那样,到达“太接近”最小值的区域可能会导致过度拟合,因此如果太小,它会对数据中的“高频”噪声敏感。应该介于两者之间。
可能的解决方案:
- 获得更多数据点(或人为地扩展现有数据点的集合)
- 使用超参数(例如增加/减少容量或正则化项)
- 正则化:尝试 dropout、early-stopping 等
这个问题很老,但由于尚未指出而发布此问题:
可能性 1:您正在对您的训练集或验证集应用某种预处理(零意义、规范化等),但不是另一个.
可能性 2:如果您构建了一些在训练和从头开始推理期间执行不同的层,您的模型可能会错误地实现(例如,批量标准化的移动均值和移动标准差是否在训练期间得到更新?如果使用 dropout,权重是否在推理?)。如果您的代码从头开始实现这些东西并且不使用 Tensorflow/Pytorch 的内置函数,则可能会出现这种情况。
可能性 3: 正如每个人都指出的那样,过度拟合。我发现其他两个选项更有可能在您的特定情况下,因为您的验证准确度从 epoch 3 开始停留在 50%。通常,如果这种情况发生在稍后阶段,我会更担心过度拟合(除非您有一个非常具体的问题在眼前)。
您对二元分类问题的验证准确度(我假设)在 50% 左右“波动”,这意味着您的模型给出了完全随机的预测(有时它会正确猜测更多样本,有时会少一些样本)。一般来说,你的模型并不比掷硬币好。
验证损失更稳定的原因是它是一个连续函数:它可以区分正样本的预测 0.9 比预测 0.51 更正确。为了准确起见,您将这些连续的 logit 预测四舍五入到并简单地计算正确预测的百分比。现在,由于您的模型在猜测,它很可能预测所有样本的值接近 0.5,假设一个样本在一个时期后得到 0.49,在下一个时期得到 0.51。从损失的角度来看,预测的不正确性没有太大变化,而准确性即使对这些微小的差异也很敏感。
无论如何,正如其他人已经指出的那样,您的模型正在经历严重的过度拟合。我的猜测是您的问题太复杂了,即很难从您的数据中提取所需的信息,而这种简单的端到端训练的 4 层 conv-net 没有机会学习它。