【问题标题】:Approximately periodic jumps in TensorFlow model lossTensorFlow 模型损失的近似周期性跳跃
【发布时间】:2020-05-20 09:39:49
【问题描述】:

我正在使用tensorflow.keras 在图像识别问题中训练 CNN,使用 Adam minimiser 来最小化自定义损失(一些代码在问题的底部)。我正在试验我需要在我的训练集中使用多少数据,并认为我应该研究我的每个模型是否正确收敛。然而,当绘制不同训练集分数的损失与训练时期数时,我注意到损失函数中大约有周期性的峰值,如下图所示。在这里,不同的行将不同的训练集大小显示为我的总数据集的一小部分。

随着我减小训练集的大小(蓝色 -> 橙色 -> 绿色),这些尖峰的频率似乎会降低,但幅度似乎会增加。直观地说,我会将这种行为与跳出局部最小值的最小化器联系起来,但我对 TensorFlow/CNN 的经验不足,无法知道这是否是解释这种行为的正确方法。同样,我不能完全理解训练集大小的变化。

谁能帮我理解这种行为?我应该担心这些功能吗?

from quasarnet.models import QuasarNET, custom_loss
from tensorflow.keras.optimizers import Adam

...

model = QuasarNET(
        X[0,:,None].shape, 
        nlines=len(args.lines)+len(args.lines_bal)
        )

loss = []
for i in args.lines:
    loss.append(custom_loss)

for i in args.lines_bal:
    loss.append(custom_loss)

adam = Adam(decay=0.)
model.compile(optimizer=adam, loss=loss, metrics=[])

box, sample_weight = io.objective(z,Y,bal,lines=args.lines, 
        lines_bal=args.lines_bal)

print( "starting fit")
history = model.fit(X[:,:,None], box,
        epochs = args.epochs,
        batch_size = 256,
        sample_weight = sample_weight)

【问题讨论】:

  • 添加你用来训练模型的代码,可能你正在使用循环学习率或类似的东西
  • @HitLuca 我现在添加了一些代码 - 学习率是 Adam 优化器的默认值(我相信是 0.001)。默认情况下这是否具有循环行为?
  • 不,默认情况下学习率不是循环的,它不在您的代码中。您添加了 lr 衰减,因此可能会影响您的跳跃损失。就像我一直做的那样,如果在某个时候你的项目开始通过烧蚀进行奇怪的东西测试,我的意思是删除对结果影响最大的组件,并用一个虚拟的替换它。看看它是否解决了它,你可以确定问题就在那里。在这种情况下,尝试用单层 NN 替换您的 QasarNET。如果它仍然跳来跳去,请尝试使用您预测常数的虚拟数据集。 - 继续
  • 继续 - 还是?尝试删除优化器参数等。在某些时候项目将开始工作。从那以后,您只需要一个一个地还原您的更改,直到没有任何奇怪的事情发生。我的赌注是 QasarNET 或数据集在某种程度上很奇怪
  • @HitLuca 感谢您的想法,非常感谢。上图中的模型已将衰减设置为零(我现在已经编辑了代码以显示这一点)所以我认为这不是原因。我认为逐渐解构事物的想法可能是最好的方法,我很快就会尝试。

标签: python tensorflow machine-learning keras conv-neural-network


【解决方案1】:

经过一位同事的讨论,我相信我们已经解决了这个问题。默认情况下,Adam minimiser 使用与其最近历史中梯度的方差成反比的自适应学习率。当损失开始变平时,梯度的方差会减小,因此最小化器会提高学习率。这可能会非常剧烈地发生,导致最小化器“跳”到参数空间中更高的损失点。

您可以通过在初始化 minimiser (http://www.satyenkale.com/papers/amsgrad.pdf) 时设置 amsgrad=True 来避免这种情况。这可以防止学习率以这种方式增加,从而导致更好的收敛。下面的(有点基本的)图显示了正常设置的损失与训练时期数的关系,如在原始问题(norm loss)中与在最小化器(amsgrad loss)中设置amsgrad=True 时的损失相比。

显然,amsgrad=True 的损失函数表现得更好,并且随着更多时期的训练,应该会导致稳定的收敛。

【讨论】:

    猜你喜欢
    • 2019-07-19
    • 1970-01-01
    • 2017-10-02
    • 1970-01-01
    • 2018-08-03
    • 2018-02-09
    • 2021-08-23
    • 2016-07-18
    • 2011-02-11
    相关资源
    最近更新 更多