这可能是一个非常基本的问题,但我无法找到答案: 当我使用批次训练使用Keras的网络时,控制台输出显示并在每个训练时期内不断更新训练集的当前损失值的显示。据我了解,这个损失值是根据当前批次计算的(作为整体损失的代理),并且可能与先前批次计算的损失值平均。 但是有两种方法可以获得当前批次的损失值:在更新参数之前或之后。有人可以告诉我哪两个是正确的?从我观察到的情况来看,我宁愿猜测它是在优化步骤之后。
我提出这个问题的原因是:我正在训练一个网络并且看到一种行为,其中训练损失(两次嵌入的MSE)将按预期降低(几个数量级),但验证损失保持不变。首先我认为这可能是由于过度拟合。因此,由于训练数据集非常大(200k图像),我决定减少纪元大小以便能够更频繁地看到评估的验证集,从而导致纪元小于trainingSetSize / batchSize。即便如此,我看到训练损失从纪元减少到纪元(验证损失仍然保持不变),我发现这很有趣,因为网络仍处于第一次看到训练数据的阶段。根据我的理解,这意味着我的设置中存在一些令人讨厌的错误,或者在执行优化步骤后显示了显示的训练损失。否则,新的,从未见过的批次和验证集的丢失应该至少类似。
即使我假设在每个优化步骤之后计算损失:假设我的网络没有按照验证集评估的建议进行任何有用的进展,当看到一个新的,从未见过的批处理时,它也应该表现得任意。然后,训练损失的整体减少只会归因于优化步骤(这对于手头的批次非常有利,但对于其他数据则不然,显然,这也是一种过度拟合)。这意味着,如果训练损失持续减少,则每批次的优化步骤变得更有效。我正在使用亚当优化器,我知道它是自适应的,但实际上是否有可能看到训练损失持续大幅减少,而实际上,网络没有学习任何有用的概括?
答案 0 :(得分:2)
在优化步骤之前计算损失。其原因在于效率,与反向传播的工作方式有关。
特别是,假设我们想要最小化||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
因此,如果我们在更新后评估损失,我们需要计算两次A(x, z)
,而如果我们在更新之前计算它,我们只需要计算一次。因此,在更新之前计算它的速度是原来的两倍。