【问题标题】:Is there a difference between multiple times loss.backward() and loss.backward() after multiplying loss by n in Pytorch?在 Pytorch 中将 loss 乘以 n 后,多次 loss.backward() 和 loss.backward() 之间有区别吗?
【发布时间】:2020-05-27 08:24:20
【问题描述】:

这两个代码有区别吗?

1

Loss.backward(retain_graph=True)
Loss.backward(retain_graph=True)
Loss.backward()
optimizer.step

2

Loss = 3 * Loss
Loss.backward()
optimizer.step

当我在最后一个backward()之后检查参数的梯度时,两个代码之间没有区别。但是,训练后的测试准确率会有一点差异。

我知道这并不常见,但这与我正在做的研究有关。

【问题讨论】:

  • 理论上应该没有区别。由于有限的浮点精度,但是在梯度方面可能会出现微小的差异(特别是如果您的网络非常深)。因此,对于性能和数值稳定性而言,您应该更喜欢选项 2。显然,选项 1 在图表中回溯的频率是选项 2 的三倍,因此这样做需要三倍的时间。
  • 测试是否是浮点精度的原因,你可以对sn-p 2(或1)运行两次推理,看看这两次运行的测试精度是否也不同。

标签: python pytorch loss


【解决方案1】:

对我来说,它看起来非常不同。

计算损失三次不会做任何事情(第一个代码 sn-p)。您只需保留之前计算的梯度。 (检查你的叶张量 .grad() 属性的值)。

然而,第二个代码 sn-p 只是将梯度乘以三,从而加快了梯度下降。对于标准的梯度下降优化器,这就像将学习率乘以 3。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    在选项 1 中,每次调用 .backward() 时,都会计算梯度。 3 次调用后,当您执行optimizer.step 时,会添加渐变,然后相应地更新权重。

    在选项 2 中,您将损失乘以一个常数,因此梯度也将乘以该常数。

    因此,将梯度值相加 3 次并将梯度值乘以 3 将导致相同的参数更新。

    请注意,我假设浮点精度不会造成损失(如 cmets 中所述)。

    【讨论】:

      猜你喜欢
      • 2019-05-27
      • 2021-12-31
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 2020-04-02
      • 2018-07-20
      • 2021-10-22
      • 1970-01-01
      相关资源
      最近更新 更多