【PyTorch学习笔记】15:动量(momentum),学习率衰减

动量(momentum)

简述

之前学习的用梯度更新参数 w w w的公式:
w k + 1 = w k − α ⋅ ∇ f ( w k ) w_{k+1}=w_k - \alpha \cdot \nabla f(w_k) wk+1=wkαf(wk)
其中 α \alpha α是学习率。

现用
z k + 1 = β ⋅ z k + ∇ f ( w k ) w k + 1 = w k − α ⋅ z k + 1 z_{k+1}=\beta \cdot z_k + \nabla f(w_k) \\ w_{k+1}=w_k - \alpha \cdot z_{k+1} zk+1=βzk+f(wk)wk+1=wkαzk+1
来代替。即相当于原式子又减去了一个 α ⋅ β ⋅ z k \alpha \cdot \beta \cdot z_k αβzk这一项。其中 z z z表征了上次更新的方向和大小,而 ∇ f ( w ) \nabla f(w) f(w)则是梯度,所以新的式子综合考虑了梯度下降的方向和上次更新的方向,用 β \beta β来决定了惯性的大小。

优点

(1)不仅考虑了当前的梯度下降的方向,还综合考虑了上次更新的情况,使得学习器学习过程的幅度和角度不会太尖锐,特别是遇到来回抖动的情况时大有好转。
(2)当遇到局部极小值时,因为设置了惯性,所以可能可以冲出局部最小值,这样就更可能找到一个全局最小值。

使用

某些优化器(如Adam)内置了momentum,所以没有这个参数,对多数优化器直接设置就可以了,传进去的参数是 β \beta β的取值。其取值越大则考虑之前的更新方向的程度就越大,取值为0时即相当于没有惯性。

optimizer = optim.SGD(net.parameters(), lr=learning_rate, momentum=0.78)

这里试了一下,仅添加了这个动量的参数,没加正则化项,最后得到的performance比之前好:
【PyTorch学习笔记】15:动量(momentum),学习率衰减_第1张图片

Test set: Average loss: 0.0009, Accuracy: 9475.0/10000 (95%)

Learning Rate Decay

在使用梯度更新参数时,学习率如果选取太小的话,学习过程会很慢;’如果学习率选取太大,那么很可能会出现来回抖动的情况,这时最终的模型可能很难收敛,而且看起来和"梯度弥散"的情况也很像(但其实不是)。

选取合适的固定的学习率是很难的, 可以在训练的一开始选取比较大的学习率加快训练过程,然后逐渐让其衰减到比较小的值,最终让模型收敛。

ReduceLROnPlateau

Plateau是平原的意思,这个类即用来监控某个量,当其在训练过程中多次没有发生下降(或上升,取决于mode参数)时,就减少学习率。首先,在定义优化器时:

from torch.optim.lr_scheduler import ReduceLROnPlateau

optimizer = ......
# 传入优化器让学习率受其管理,当连续200次没有减少loss时就会减少学习率(乘以0.7)
scheduler = ReduceLROnPlateau(optimizer, mode="min", patience=200, factor=0.7)

在每次训练时,改用这个scheduler来执行.step()方法,并传入要监控的量,这里即是传入计算出的loss:

		optimizer.step()
		# 传入要监控的量,每调用一次step就会监控一次loss
		# 前面定义时的mode="min"即是监控量没有减少时触发减小lr的操作的
		scheduler.step(loss)

在前面(带动量)的基础上运行了一下,performance没有什么提升,可能是有一点over-fitting了:
【PyTorch学习笔记】15:动量(momentum),学习率衰减_第2张图片

Test set: Average loss: 0.0011, Accuracy: 9353.0/10000 (94%)

StepLR

这个就和监控量没关系了,是固定的每执行step_size.step()方法,就把学习率乘以gamma即可。

定义优化器时:

from torch.optim.lr_scheduler import StepLR

optimizer = ......
# 每跑800个step就把学习率乘以0.9
scheduler = StepLR(optimizer, step_size=800, gamma=0.9)

训练时(注意不用传监控量进去了):

		optimizer.step()
		scheduler.step()

运行结果:
【PyTorch学习笔记】15:动量(momentum),学习率衰减_第3张图片

Test set: Average loss: 0.0010, Accuracy: 9411.0/10000 (94%)

你可能感兴趣的:(#,PyTorch)