一阶动量定义梯度下降的方向,二阶动量定义下降的步长。
1、SGD(不含动量常用的梯度下降法)
m = g(梯度), v = 1(常量)
参数更新
w1.assign_sub(lr * grad[0])
b1.assign_sub(lr * grad[1])
2、SGDM(在SGD的基础上增加了一阶动量)
m = βm + (1-β)g(梯度方向上的指数滑动平均值),v = 1(常量)
w和b初始一阶动量均为0
m_w, m_b = 0, 0
β超参数,经验值是0.9
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)
3、Adagrad (在SGD的基础上增加了二阶动量)
m = g(梯度),v = Σg²(梯度平方的累计和)
设二阶动量初始值为0
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))
4、RMSProp(在SGD的基础上增加了二阶动量)
m = g(梯度),v = βv +(1-β)g²(各时刻梯度方向的指数滑动平均)
设二阶动量初始值为0
v_w, v_b = 0, 0
β超参数,经验值是0.9
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))
5、Adam(同时结合了SGDM的一阶动量和RMSProp二阶动量,并增加了两个修正项,把修正后的一阶动量和二阶动量带入参数更新公式)
m = βm + (1-β)g,v = βv +(1-β)g²
m(修正项)=m/1-βt,v(修正项)=m/1-βt
初始化参数
m_w, m_b = 0, 0
v_w, v_b = 0, 0
beta1, beta2 = 0.9, 0.999
delta_w, delta_b = 0, 0
更新的总batch数
global_step = 0
计算一阶动量
m_w = beta1 * m_w + (1 - beta1) * grads[0]
m_b = beta1 * m_b + (1 - beta1) * grads[1]
计算二阶动量
v_w = beta2 * v_w + (1 - beta2) * tf.square(grads[0])
v_b = beta2 * v_b + (1 - beta2) * tf.square(grads[1])
计算修正项
m_w_correction = m_w / (1 - tf.pow(beta1, int(global_step)))
m_b_correction = m_b / (1 - tf.pow(beta1, int(global_step)))
v_w_correction = v_w / (1 - tf.pow(beta2, int(global_step)))
v_b_correction = v_b / (1 - tf.pow(beta2, int(global_step)))
将修正项代入公式,参数更新
w1.assign_sub(lr * m_w_correction / tf.sqrt(v_w_correction))
b1.assign_sub(lr * m_b_correction / tf.sqrt(v_b_correction))