3.2.2 陡坡速降
使用梯度下降法升级之后的train()函数如下:
这个版本的train()函数要比前述旧版的train()函数简洁得多。梯度下降法不需要任何if语句,我们只需要初始化w,然后沿着梯度的反方向重复迈步前进即可(请记住,梯度是指向上坡的,但我们要走的是下坡)。超参数lr仍然存在,但是现在它告诉我们每一步的步长应该与相应的梯度值成比例。
在进行梯度下降的迭代计算过程中,我们需要决定何时停止这种迭代计算。旧版的train()函数是在达到最大迭代次数时返回,或者是在不能进一步减少损失函数值的时候返回,出现二者之一的情况即停止迭代计算。从理论上讲,在梯度下降法的迭代计算过程中,损失函数值可以永远在减少,并且以越来越小的步伐向最小值缓慢移动,而不会完全达到最小值。那么,我们应该在什么时候停止迈出这些越来越小的步伐呢?
我们可以在梯度足够小的时候停止迭代计算,因为这意味着此时非常接近最小值。然而,上述代码遵循着一种不那么精确的方法:当你调用train()时,就告诉它要运行多少次迭代。虽然更多的迭代会产生更低的损失函数值,但是由于损失函数递减得更慢,从某种意义上讲,我们可以断定不值得花费很长时间等待这种微小的额外准确率。
在本书后面第15章的内容中,你将学习如何为超参数选择合适的值,比如最大迭代次数和lr大小。我们在这里只是尝试了一些不同的超参数取值,似乎产生了一个足够低、足够精确的损失函数值:
我们通过运行这段代码得到的结果如下:
经过每次迭代计算,损失函数的值都会下降,这是理所当然的。经过100次迭代之后,梯度下降法的结果已经非常接近最小值,以至于你无法看到最后两个损失函数值之间的差异。看起来我们的梯度下降法正在发挥作用。
但需要等一下,这里我们只使用了参数w。现在我们把参数b放回去,看看会发生什么事情。