1.momentum(动量):
原来参数更新公式如下:
新的公式如下:
可以看到新的公式的参数更新其实是比之前的公式多减去了一项(αβzk),也就是说此时不仅考虑了梯度变化的信息还多考虑了zk这一个信息,其中z表征了上次更新的方向和大小,∇f(w)是梯度,所以新的式子综合考虑了梯度下降的方向和上次更新的方向,用β来决定了惯性的大小。
通过上述两幅图可以直观地看到,考虑动量之后,学习效果明显变好,模型在没考虑动量时求得的局部最小值点处并没有停止,而是会找的全局最优解。
pytorch中只需要设置momentum参数即可完成,不过在其他优化器比如Adam中已经内置了动量机制,所以也就没有momentum参数。optimizer = optim.SGD(net.parameters(), lr=learning_rate, momentum=0.78)
2.learning rate dacay(学习率衰减):
对于深度学习模型来说,选取一个合适的学习率是很困难的,因此这里我们不考虑设置一个固定的学习率,而是在训练的一开始选取比较大的学习率加快训练过程,然后逐渐让其衰减到比较小的值,最终使得模型得到收敛。
上述模型训练过程了,LOSS发生了巨变,这是因为此时学习率变小了使得模型到达了之前学习率较大时无法到达的一个点,这里就很好的说明了学习率的微调效果是很好的。
- ReduceLROnPlateau
这个类即用来监控,当其在训练过程中多次没有发生变化(下降或上升)时,就调整学习率。
net = MLP()
optimizer = optim.SGD(net.parameters(), lr=learning_rate)
# 传入优化器让学习率受其管理
# mode参数是表示变化情况,min为变小
# patience参数,耐心值,表示当连续多少次没发生变化,就会调整学习率
# factor参数,是学习率调整系数
# 此处的设置表示当连续100次loss没有减少就会减少学习率(乘以0.8)
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer,mode="min", patience=100, factor=0.8)
然后在每次训练过程中,使用scheduler.step(loss)
方法执行。
optimizer.step()
scheduler.step(loss)
- StepLR
固定的每执行step_size
个.step()
方法,就把学习率乘以gamma
即可。
定义优化器时:
# Assuming optimizer user lr=0.05 for all groups
# lr=0.05 if epoch < 30
# lr=0.005 if 30 <= epoch < 60
# lr=0.0005 if 60 <= epoch < 90
# ......
# 每跑30个step就把学习率乘以0.1
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1)
训练时(此事不再需要传进去监控量了):
scheduler.step()