pytorch-优化器算法
优化器算法
[TOC]
0. 基础
1. 导入
1 | import torch.optim as optim |
2. 常用的优化器
- SGD/Momentum SGD
- Adam/AdamW
- AdaGrad
- RMS prop
3. 使用框架
- 生成优化器
1 | import torch.optim as optim |
- 同一个模型定义不同的优化器
1 | import torch |
- 使用优化器
1 | for input, target in dataset: |
1. SGD/Momentum SGD
SGD:随机梯度优化,最简单常用的优化器,卷积神经网络时代比较好用,transformer时代被AdamW取代。
1.1 SGD原理
1. 计算梯度: ft是模型函数,θt − 1是上一步的参数,∇θ是向量梯度计算,λ是权重衰减系数
gt = ∇θft(θt − 1)
gt = gt + λθt − 1
2. 梯度更新:λ是权重衰减系数,γ是学习率
θt = θt − 1 − γgt
1.2 Momentum SGD原理
1. 计算梯度: 和SGD一样计算权重衰减后的梯度
gt = ∇θft(θt − 1)
gt = gt + λθt − 1
2. 计算动量:mt是当前动量,mt − 1上一步的动量,β是动量系数
m0 = g0
mt = βmt − 1 + (1 − β)gt
目前新的版本使用1 − τ 代替1 − β,τ作为动量抑制系数
mt = βmt − 1 + (1 − τ)gt
3. 梯度更新:γ是学习率
gt = bt
θt = θt − 1 − γgt
1.3 代码
1 | class SGD(Optimizer): |
参数:
- params:待优化的模型参数,通过model.parameters()获得
- lr:学习率γ
- momentum:梯度动量系数μ
- dampening:动量抑制τ
- eps:分母的添加项,增加数值稳定性1e-8
- weight_decay:权重衰减系数,正则化系数λ
2. Adam/AdamW
2.1 Adam
1. 计算梯度: ft是模型函数,θt − 1是上一步的参数,∇θ是向量梯度计算,λ是权重衰减系数
gt = ∇θft(θt − 1)
gt = gt + λθt − 1
2. 计算动量:mt是当前动量,mt − 1上一步的动量,β1是动量系数
mt = β1mt − 1 + (1 − β1)gt
3. 计算二阶动量:bt是当前动量,bt − 1上一步的动量,μ是动量系数
vt = β2vt − 1 + (1 − β2)gt2
4. 快速启动:由于初始时$m_0=0, v_0=0, $,m和v更新很慢,需要很多步才能到正常值,需要进行偏差修正
$$\hat{m_t}=m_t/(1-\beta^t_1)$$
$$\hat{v_t}=v_t/(1-\beta^t_2)$$
5. 梯度更新:γ是学习率 $$\theta_t = \theta_{t-1} -\gamma \hat{m_t}/(\sqrt {\hat v_t} + \epsilon)$$
2.2 AdamW
AdamW是对Adam的修正,修改了权重衰减的位置,权重衰减放到了最后的损失位置,而不是最开始的梯度位置。
1. 计算梯度: ft是模型函数,θt − 1是上一步的参数,∇θ是向量梯度计算,λ是权重衰减系数
gt = ∇θft(θt − 1)
2. 计算动量:mt是当前动量,mt − 1上一步的动量,β1是动量系数
mt = β1mt − 1 + (1 − β1)gt
3. 计算二阶动量:bt是当前动量,bt − 1上一步的动量,μ是动量系数
vt = β2vt − 1 + (1 − β2)gt2
4. 快速启动:由于初始时$m_0=0, v_0=0, $,m和v更新很慢,需要很多步才能到正常值,需要进行偏差修正
$$\hat{m_t}=m_t/(1-\beta^t_1)$$
$$\hat{v_t}=v_t/(1-\beta^t_2)$$
5. 梯度更新:γ是学习率
θt = θt − 1 − γλθt − 1
$$\theta_t = \theta_{t-1} -\gamma \hat{m_t}/(\sqrt {\hat v_t} + \epsilon)$$
3. AdaGrad/RMS prop
相当于动量系数β1为0的Adam,根据参数之前的梯度作为当前参数的权重
