神经网络参数优化器
- 待优化参数w
- 损失函数loss
- 学习率lr
- 每次迭代一个batch
- t表示当前迭代的总次数
关注量
下面是我们t时刻需要关注的量:
- 如何计算t时刻损失函数关于当前参数的梯度$g_t=\nabla loss=\frac {\alpha loss}{\alpha w_t}$
- 如何计算t时刻一阶动量$m_t$和二阶动量$V_t$
- 一阶:和梯度相关
- 二阶:和梯度的平方相关
- 如何计算t时刻下降的梯度
$$\eta_{t}=lr * m_t/ \sqrt{V_{t}}$$
- 如何计算t+1时刻的参数
$$w_{t+1} = w_{t} - \eta_{t}=w_t - lr * m_t/ \sqrt{V_{t}}$$
SGD
常用的梯度下降方法。此时满足:
$m_t=g_t;V_t=1$
梯度满足:
$$\eta_{t}=lr * m_t/ \sqrt{V_{t}}=lr*g_t$$
t+1时刻的参数满足:
$$w_{t+1} = w_{t} - \eta_{t}=w_t - lr * g_t$$
单层网络的更新参数代码:
1 | w1.assign_sub(lr * grads[0]) |
SGDM
在SGD的基础上增加一阶动量。
$$m_t=\beta * m_{t-1} + (1-\beta)*g_{t}$$
$$V_t = 1$$
其中$\beta$是个超参数,接近1,经验值是0.9
$$\eta_{t}=lr * m_t/ \sqrt{V_{t}}=lr*(\beta * m_{t-1} + (1-\beta)*g_{t})$$
t+1时刻的参数满足:
$$w_{t+1} = w_{t} - \eta_{t}=w_t - lr * (\beta * m_{t-1} + (1-\beta)*g_{t})$$
python代码实现的过程:
1 | m_w, m_b = 0,0 # 设置两个初始值 |
Adagrad
在SGD的基础上增加了二阶动量
$m_t=g_t;V_t=\sum t_{i=1}{g_i}2$
梯度满足:
$$\eta_{t}=lr * m_t/ \sqrt{V_{t}}=lr*g_t / (\sum t_{i=1}{g_i}2)$$
t+1时刻的参数满足:
$$w_{t+1} = w_{t} - \eta_{t}=w_t - lr * g_t / (\sum t_{i=1}{g_i}2)$$
python实现单层网络的更新参数代码:
1 | v_w, v_b = 0, 0 |
RMSProp
在SGM的基础上增加二阶动量
$$m_t=g_t$$
$$V_t=\beta V_{t-1} + (1-\beta)*g_t^2$$
梯度满足:
$$\eta_{t}=lr * m_t/ \sqrt{V_{t}}=lr*g_t / \sqrt{\beta V_{t-1} + (1-\beta)*g_t^2}$$
t+1时刻的参数满足:
$$w_{t+1} = w_{t} - \eta_{t}=w_t - lr * g_t / \sqrt{\beta V_{t-1} + (1-\beta)*g_t^2}$$
python实现单层网络的更新参数代码:
1 | v_w, v_b = 0, 0 |
Adam
同时结合SGDM一阶动量和RMSProp的二阶动量
$$m_t=\beta * m_{t-1} + (1-\beta)*g_{t}$$
修正一阶动量的偏差:
$$\hat{m_t} = \frac{m_t}{1 - \beta_1^t}$$
$$V_t = \beta_2*V_{t-1} + (1-\beta_2)*g_t^2 $$
修正二阶动量的偏差:
$$\hat{V_t} = \frac{V_t}{1 - \beta_2^t}$$
那么最终更新的参数为:
梯度满足:
$$\eta_{t}=lr * \hat m_t/ \sqrt{\hat V_{t}}=lr*\frac{m_t}{1 - \beta_1^t} / \sqrt {\frac{V_t}{1 - \beta_2^t}}$$
t+1时刻的参数满足:
$$w_{t+1} = w_{t} - \eta_{t}=w_t - lr*\frac{m_t}{1 - \beta_1^t} / \sqrt {\frac{V_t}{1 - \beta_2^t}}$$