这可能是一个非常基本的问题,但是我无法找到答案:
当我使用Keras批量训练网络时,控制台输出会显示并在每个训练时期不断更新训练集当前损失值的显示。据我了解,该损失值是针对当前批次计算的(作为总损失的代理),并且可能与先前批次计算的损失值进行平均。但是,有两种方法可以获取当前批次的损失值:在更新参数之前或之后。有人可以告诉我这两个是正确的吗?根据我的观察,我宁愿猜测是在优化步骤之后。
我问这个问题的原因:我正在训练一个网络,看到这样的行为:训练损失(两个嵌入的MSE)将按预期减少(几个数量级),但是验证损失保持不变。首先,我认为这可能是由于过度拟合。因此,由于训练数据集非常大(200k张图像),因此我决定减小历元大小,以便能够更频繁地查看验证集,从而使历元小于trainingSetSize / batchSize。即使那样,我仍然看到训练损失从一个时期到另一个时期减少(验证损失仍然保持不变),由于网络仍处于第一次看到训练数据的阶段,我发现这很有趣。以我的理解,这意味着我的设置中存在一些讨厌的错误,或者在执行优化步骤后显示了显示的训练损失。否则,新的,从未见过的批次和验证集的损失至少应表现相似。
即使我假设损失是在每个优化步骤之后计算得出的:假设我的网络没有按照验证集评估的建议进行任何有益的改进,但在看到一个新的,从未见过的批次时,它也应该表现出任意性。然后,训练损失的整体减少将仅归因于优化步骤(这对手头的批次非常有用,但对于其他数据则不然,显然,这也是一种过拟合)。这意味着,如果训练损失不断减少,则每批次的优化步骤将更加有效。我使用的是我知道是自适应的Adam优化器,但实际上是否有可能看到训练损失连续且大量减少,而实际上,网络没有学到任何有用的概括?
最佳答案
在优化步骤之前计算损失。其原因是效率,并且与反向传播的工作方式有关。
特别是,假设我们要最小化||A(x, z) - y||^2
w.r.t. z
。然后,当我们执行反向传播时,我们需要评估此计算图:
A(x, z) -> grad ||. - y||^2 -> backpropagate
现在,如果我们在此添加“评估损失”并在更新参数之前评估损失,则计算图将如下所示
> grad ||. - y||^2 -> backpropagate
/
A(x, z)
\
> ||. - y||^2
另一方面,如果我们在更新损失后评估损失,则该图将如下所示
A(x, z) -> grad ||. - y||^2 -> backpropagate -> A(x, z) -> ||. - y||^2
因此,如果我们在更新后评估损耗,则需要计算两次,而在更新之前进行计算,则只需计算一次。因此,在更新之前对其进行计算的速度提高了一倍。