Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

学习率

前两章,我们用梯度下降法进行了第一次模型训练。方向是对的,但一步把权重从 [0.5, 0.5] 更新到了 [6854, 14147],损失值随之爆炸,模型训练失败。

问题的根源在于:梯度只告诉我们下坡的方向,却不能决定步子应该迈多大。

梯度很大,只说明当前这个方向的坡度很陡,并不意味着应该迈一大步。步子太大,会直接越过山谷,冲到对面的坡上,反而比出发点更高。这种现象称为发散。


解决办法是引入一个比例系数,把每次更新的步幅等比例缩小,这个系数称为学习率(Learning Rate),记作 η\eta。

加入学习率后,梯度下降的更新公式变为:

wnew=wold−η⋅∂L∂ww_{\text{new}} = w_{\text{old}} - \eta \cdot \frac{\partial L}{\partial w}
bnew=bold−η⋅∂L∂bb_{\text{new}} = b_{\text{old}} - \eta \cdot \frac{\partial L}{\partial b}

学习率需要仔细选择:

  • 太大:更新步幅过大,损失值左右震荡,甚至发散;

  • 太小:更新步幅过小,损失值下降极慢,需要大量训练才能收敛;

  • 合适:损失值稳定地逐步下降,最终收敛到最优解附近。

超参数

学习率是我们遇到的第一个超参数(Hyperparameter)。

模型参数(权重和偏置)是模型自动学习的对象:每次训练后,它们会根据梯度被更新。

超参数则不同:它们不会被模型训练更新,而是需要我们在训练开始前根据经验和实验进度设定。学习率控制的是训练步幅,后续章节还会遇到其他超参数。

不断测试、调整超参数以获得最佳训练效果的过程,称为调参(Hyperparameter Tuning)。调参分为两类,通常会结合使用:

  • 手动调参:训练前根据测试数据和经验,手动设置超参数;

  • 自动调参:训练过程中由程序代码根据训练进度调整超参数。

优化器

随着学习率的引入,实践中通常会使用优化器(Optimizer)来统一管理学习率的使用(参数更新)和自动调参。

张量

数据

模型

随着优化器的使用,我们不再需要模型的反向函数来逐个更新参数。转而提供一个新的属性:

  • parameters(参数列表):包括本模型所有需要更新的参数。对于一个线性模型来说,就是权重和偏置。

损失函数(均方误差)

优化器(随机梯度下降)

我们实现的第一个优化器是随机梯度下降(Stochastic Gradient Descent,SGD)优化器。它的作用非常简单,就是每次模型训练(一次前向传播和一次反向传播)后,立即根据反向传播计算出的梯度,结合学习率,来更新所有参数的数值。

创建一个优化器,我们需要知道:

  • parameters(参数列表):网络模型所有需要更新的参数,比如模型的权重和偏置。需要注意的是,这里只包括可训练的参数,中间值、预测值这些虽然也是张量,在反向传播中也会计算它们的梯度,但并不需要优化器来更新它们的数值;

  • lr(学习率):参数更新的比例系数。

步进函数

步进函数(step)实现优化器最基本的功能:更新参数。

随机梯度下降优化器的步进函数很简单:在参数更新前,先将梯度乘以学习率来减小每次梯度下降的步幅。

超参数

学习率

随机梯度下降优化器非常简单实用,但是不具备自动调参的功能。因此我们主要依靠手动调参。

学习率的手动调参是一个摸索实验的过程。通常我们会根据采用的模型选择一个初始值,比如:0.01。然后根据模型训练的结果增大(比如:0.1)或者减小(比如:0.001)学习率。

💡 提示:我们这里采用了一个非常小的学习率,就是手动调参的结果。主要原因是我们没有对训练数据进行标准化(Standardization)处理,导致梯度计算结果偏大。

建模

我们需要创建一个优化器的实例,创建时需要传入模型参数列表和学习率超参数。

训练

模型训练中,我们不再调用模型的反向函数(已经取消),而是调用优化器的步进函数(step)来完成参数更新。

推理

prediction:	Tensor([53.18309379])

评估

loss:	Tensor(12503.020514375934)

从评估结果可以看到,损失值从 1,026,548,766,283 缩小到了 12,503。不仅回到了正常范围内,而且小于模型训练前的 14,872。这说明学习率的引入是有效的,而且我们(手动调参)选择的数值也是合理的。

课后练习

  1. 父节点列表(parents)和参数列表(parameters)的设计,使得计算图的遍历、反向传播和参数更新都可以自动化完成。尝试把不同的参数从父节点列表或者参数列表中移除,观察反向传播的结果如何?

  2. 分别把学习率改成 0.001、0.0001、0.000001,各训练一次,观察损失值的变化和学习率的关系。