深度学习 - 2019年2月20日

笔记

CS231n课程笔记6.1:优化迭代算法之SGD,Momentum,Netsterov Momentum,AdaGrad,RMSprop,Adam

各种不同的优化器

SGD的三个问题

  • 根据梯度值的大小决定步长,所以如果各个维度的步长相差很大,就会不断震荡,而且收敛缓慢,在高维空间上这个问题会更严重;
  • 在局部极小值(local minima)和鞍点(saddle point)上的问题,在高维空间里一般是鞍点的问题,虽然鞍点梯度不为0,但由于斜率很小,导致更新梯度的步长很小;
  • 当采用mini-batch时,在使用全局的数学估计时,会不可避免的添加一些噪音,从而导致损失值和总体相差较远,从而导致梯度更新的方向变化频繁。

SGD + Momentum

SGD:

1
2
3
while True:
dx = compute_gradient(x)
x -= learning_rate * dx

SGD+Momentum:

1
2
3
4
5
vx = 0
while True:
dx = compute_gradient(x)
vx = rho * vx + dx
x -= learning_rate * vx

Nesterov Momentum

在使用梯度计算实际速度方向时,使用的是“下一点”的梯度。由于计算不方便,使用了等量替换的方式,从而方便了计算。

AdaGrad

1
2
3
4
5
grad_squared = 0
while True:
dx = compute_gradient(x)
grad_squared += dx * dx
x -= learning_rate * dx / (np.sqrt(grad_squared) + 1e-7)

解决问题:在梯度较小的地方可以加速学习,在梯度较大的地方可以减缓学习。

存在问题:梯度平方项不断累加,导致最后步长变小,学习速度降低。

RMSProp

1
2
3
4
5
grad_squared = 0
while True:
dx = compute_gradient(x)
grad_squared = decay_rate * grad_squared + (1 - decay_rate) * dx * dx
x -= learning_rate * dx / (np.sqrt(grad_squared) + 1e-7)

加入了衰减率,一般取值为0.9、0.99、0.999从而解决了步长到后期过小的问题。

Adam

Adam: A Method for Stochastic Optimization, 2015

1
2
3
4
5
6
7
8
9
10
11
12
first_moment = 0
second_moment = 0
for t in range(1, num_iterations):
dx = compute_gradient(x)
# Momentum
first_moment = beta1 * first_moment + (1 - beta1) * dx
# RMSProp
second_moment = beta2 * second_moment + (1 - beta2) * dx * dx
# Bias correction 刚开始时这两个动量可能会太小,导致步长过大,从而需要进行修正
first_unbias = first_moment / (1 - beta1 ** t)
second_unbias = second_moment / (1 - beta2 ** t)
x -= learning_rate * first_unbias / (np.sqrt(second_unbias) + 1e-7))

二阶优化器

上述都是一阶优化器(First-Order Optimization),也有二阶优化器,使用到二阶偏导(牛顿参数更新法,没有学习率)。

但二阶优化器使用到的Hessian矩阵,计算逆时的时间复杂度是O(N^3),所以不适用于深度学习。

另外一个不适用的原因:深度学习是一个非凸问题,且随机性大。

二阶优化器在凸优化问题上有很好的表现,但不适用于深度学习。

另外,Model Ensembles可以带来大约2%的性能提升。