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