我正在做fast-ai,SGD的课程,我看不懂.....
这减去了系数(学习率 * 梯度)...
但是为什么需要减法呢?
这是代码:
def update():
y_hat = x@a
loss = mse(y_hat, y)
if t % 10 == 0: print (loss)
loss.backward()
with torch.no_grad():
a.sub_(lr * a.grad)
看图片。它显示了损失函数
J
作为参数 W
的函数。这是一个简化的表示,其中 W
是唯一的参数。因此,对于凸损失函数,曲线如图所示。
请注意,学习率为正。在左侧,梯度(该点与曲线相切的线的斜率)为负,因此学习率和梯度的乘积为负。因此,从
W
中减去乘积实际上会增加 W
(因为 2 个负数变为正数)。在这种情况下,这很好,因为损失减少了。
另一方面(右侧),梯度为正,因此学习率和梯度的乘积为正。因此,从
W
中减去乘积会减少 W
。在这种情况下,这也很好,因为损失减少了。
我们可以将同样的事情扩展到更多数量的参数(显示的图表将是更高维的并且不容易可视化,这就是为什么我们最初采用单个参数
W
)和其他损失函数(甚至非凸的,虽然它不会总是收敛到全局最小值,但肯定会收敛到最近的局部最小值)。
注意:这个解释可以在deeplearning.ai Andrew Ng的课程中找到,但我找不到直接链接,所以我写了这个答案。
我假设
a
代表基于 y_hat = x @ a
的模型参数。这是必要的,因为随机梯度下降算法的目标是找到损失函数的最小值。因此,您可以采用梯度 w.r.t.你的模型参数,并在梯度方向上稍微更新它们。
想想从山上滑下来的类比:如果景观代表你的损失,那么梯度就是最陡下降的方向。为了到达底部(即最小化损失),您需要从您站立的位置向最陡下降的方向迈出一小步。
sub
中的sub_
表示减去,_
中的sub_
将通过从a
中减去
lr* a.grad
的值(即lr *损失w.r.t
a
)来改变参数
a
。.
假设:
a
= 3
a.grad
= 1 # 损失梯度一个
lr
= 0.1
因此,
a.sub_(lr*a.grad)
将使a
的值为2.9
然而,
如果您选择这样做:
a
= a
-lr*a.grad
然后它将“旧”
a
的值分配给这个“新”a
。
这个新的 a
可能不具有 requires_grad
为 True。因此,您随后需要手动编写这一行a.requires_grad_()
才能成功实现梯度下降。