Caffe现在提供了六种优化算法:
- Stochastic Gradient Descent (type: SGD)
- AdaDelta (type: AdaDelta)
- Adaptive Gradient (type: AdaGrad)
- Adam (type: Adam)
- Nesterov's Accelerated Gradient (type: Nesterov)
- RMSprop (type: RMSPorp)
假设一个数据集,其数据总量为D, 那么这整个数据集的loss的平均值是:
其中, 前面第一部分就是求所有数据损失值的平均值, 第二部分是正则项, lamda是正则项系数, 用于防止过拟合.
如果数据量很小的话,用上面的公式还可以计算. 但是如果数据量D非常大, 那么计算一次Loss将耗费很长的时间.
所以这时候提出了 batch(批) 这个概念, 将所有数据集D分割成很多个小的batch, 记为N.
在一次前向计算和后向计算中, 我们只提取一个batch数量的数据, 然后只更新这一batch数据的loss,
然后我们可以重复的, 多次的提取一个batch数据来进行计算.
在caffe中, 默认的优化算法是SGD, 也就是随机梯度下降算法.
一. Stochastic Gradient Descent (SGD)
随机梯度下降算法是在梯度下降算法的基础上发展起来的, 梯度下降算法也叫最速下降算法.
简要一句话说明SGD的原理就是当前参数W(t+1) 等于 上一次更新后的参数Wt 和 当前权重更新值 的线性组合.
而我们实际在caffe中使用的时候都是加上冲量法的.
其中, α 是学习率(base_lr), μ 是上一次梯度值的权重, 就是冲量(momentum).
学习率是要不断下降才能让模型不断优化的. 学习率可以理解为步长, 优化模型就是翻山越岭的从最陡方向出发找最低谷. 如果步子太大了,容易跨过最低谷, 如果步子太小, 找的太慢, 而且容易陷入其他非最低谷出不来了. 在solver文件中, 学习率下降策略lr_policy有很多, 以后我会详细讲的, 知道有这么回事就好.
上面说的最陡方向, 其实就是负的梯度方向.
冲量就是在保证loss稳定的情况下,尽量加速其下降. 对于SGD, 这个一般默认设置为0.9, 在某些特殊情况, 当学习率下降到很小的时候, 可以将冲量设置为 0.99, 提高训练效果.
二. AdaDelta
Paper地址: https://arxiv.org/pdf/1212.5701.pdf
AdaDelta是一种具有适应性的学习率方法, 也是基于梯度下降发展出来的. 这个算法不需要手动调优学习率, 并且对噪音有很好的鲁棒性.
下面是几点这个方法的优点:
1. 不用手动设置学习率.
2. 对超参数初始化不敏感.
3. 对于每一维度, 分别有一个动态的学习率.
4. 对大梯度, 噪音, 和结构选择有很好的鲁棒性.
5. 对本地和分布式环境的适应性都很好.
原作者一开始想对梯度下降法做很多改动, 最大的想法就是应用牛顿法, 使用二阶导的代价函数,即Hessian海森矩阵:
其中Δxt 是参数变化量, Ht是Hessian海森矩阵, 相当于学习率, 即步长. gt就是梯度, 决定下降方向. 这时候学习率是由海森矩阵决定的, 所以我们就不用手动的设置学习率了.
但是, 海森矩阵在计算上是非常复杂和麻烦的, 所以作者借着海森矩阵这个思路, 想到加强对一阶导数使用或者用估算海森矩阵结果的方法.
最终是选择了加强一阶导数使用的方法, 近似模拟二阶牛顿法
基本思路还是跟SGD一样, 实际的变化量是 冲量和上一次变化量的乘积减去基础学习率乘以当前梯度值(这里基础学习率是1.0, 而且保持不变.)
AdaDelta冲量一般设置成0.95
solver中delta一般设置成1e-6
base_lr必须设置为1.0
lr_policy必须设置为fixed.
-------------------------下面是具体算法实现步骤--------------------------------------------------------------------------------------------------------------
paper中作者跟AdaGrad方法做了大量的对比, 作者提出AdaDelta方法主要解决了AdaGrad的两个缺点. 一是解决了随着训练的进行, 学习率会持续衰减的问题. 我认为作者想表达的意思就是随着训练的进行, 如果学习率持续降低, 到后期对优化的影响会降到很低导致优化不完全. 二就是解决的需要手动设置初始学习率的问题.
2012年 Schaul&S. Zhang&LeCun 提出了AdaGrad-like 算法, 我这里提到这个算法是因为和AdaDelta算法有相似的地方.
其中, diag(Ht) 是海森矩阵的对角矩阵, E[gt-w:t]是从当前t算起前w次迭代梯度的期望值, 分母就是从当前t算起前w次迭代梯度平方的期望值
这样取前w次梯度的好处是不会让梯度消失
好了回到AdaDelta, 这个方法没有只是取前w次迭代梯度, 而是取所有迭代的梯度.
其中, ρ是衰减常量, 在caffe中通过设置momentum来设置这个参数. 通过这个公式, 我们算出当前iteration 所有梯度平方的期望值.
我们需要上面结果的平方跟用于参数更新, 这里用RMS(root mean square 均方根)表示:
其中, RMS[g]t表示当前iteration下, 梯度g 的均方根值, ε是一个常数(就是solver中参数delta), 平滑项, 为了保证输出结果不为零, 因为后面这个结果是要做分母的.
最后参数的变化量公式:
上面的方法就是Tieleman&Hinton的RMSProp.
后来的Zeiler考虑到units的问题, Δx是用来更新参数x的, 所以他们的units必须要一致.
说说我的理解, 上面的公式中, gt的units应该是跟x正相关的. RMS[g]t的units也是跟x正相关的.
但是一相除, 就变成了unitless 这种情况了.
所以在看下面公式, 在分子上加上了上一次迭代的参数变化量的RMS, 将units又找了回来.
这个units到底怎么理解我还有困惑, 我觉得应该可以理解为 "单位"
并且加入上一次迭代, 会增加最终结果的鲁棒性, 不会发生突变.
分子分母RMS中的ε取相同的值
实际步长, 也可以认为是学习率, 跟当前梯度和上一次参数变化量相关
所以不同层, 不同维度的参数的学习率也是不同的. 可以用"因人而异"来形容.
而不是SGD那样所有参数的学习率是相同的.
AdaDelta在训练初期和中期, 速度很快. 但是到后期容易陷入局部最优.这一点没有SGD效果好.
-------------------------------------------------------------------------------------------------------------------------------------------------------------
三. AdaGrad
Adaptive Gradient 自适应梯度算法, 借鉴了L2 Regularizer
其中, 分母是从1开始到t的所有梯度和的平方根, η是基础学习率.
权值初始化对AdaGrad影响敏感, 如果权值初始化过大, 梯度很大, 调节幅度会很小.
训练中后期, 梯度很容易逼近0 ,提前结束训练.
适合处理稀疏梯度
实际使用公式是:
solver中 base_lr 一般设置不大, 可参考使用0.01
lr_policy 必须设置为"fixed"
momentum 对应公式中ε
四. Adam
Adaptive Moment Estimation
同样也是基于梯度的优化方法.
只需要一阶梯度信息, 并且占用很少的内存.
通过估计梯度的一阶矩 和 二阶矩 去动态的调整每个参数的学习率.
其中, mt是对梯度的一阶矩估计, nt是对梯度的二阶矩估计. 上面带拐的是对其自身的校正.
u一般取0.9
v一般取0.999
ε一般取1e-8.
五. NAG
Nesterov's Accelerated Gradient
Nesterov的改进是让之前的动量直接影响到当前的动量
其中, η是基础学习率, μ是动量(冲量)
momentum首先计算一个梯度, 短的蓝色向量. 然后在加速更新梯度的方向进行一个大的跳跃, 长的蓝色向量.
nesterov项先在以前的加速梯度方向进行一个大的跳跃, 棕色向量
最后计算梯度, 进行校正, 绿色向量.
solver中base_lr一般为0.01, gamma为0.1
lr_policy一般为"step", stepsize视情况而定.
momentum一般为0.95
六. RMSprop
这个算法公式在上面AdaDelta中已经写出来了, RMSprop是AdaDelta的中间形式.
solver中base_lr看情况为1.0或者0.001
lr_policy一般为"fixed"
rms_decay一般为0.98
momentum一般为0.95
七. 选择优化方法和优化策略
1. RMSprop解决了AdaGrad训练中后期梯度消失的问题.
2. AdaDelta中参数的学习率与初始学习率无关. 而RMSprop中参数学习率与初始学习率有关.
3. Adam比RMSprop增加了偏差校正和动量(注意RMSprop中参数momentum的数值是作用在求期望的过程中,不算动量.)
4. 如果输入数据是 稀疏的, 最好使用自适应学习速率的优化方法(AdaGrad, AdaDelta, RMSprop和Adam).因为在优化过程中它们会自动调整学习率.
5. 如果关心优化速度, 那么自适应学习速率方法会比较快. Adam可能是当前最好的优化方法. 但很多大牛还是使用原始的SGD并且不用动量项.
6. Shuffle: 每次迭代时随机打乱数据样本顺序
7. Curriculum Learn: 把训练样本按某种有意义的方式排序, 对逐步解决困难问题有帮助.
8. 归一化参数初始值.
9. Early Stopping, 这个结合可视化技术来看. 取过拟合前的模型来用.
10. 在损失函数中添加正则化项.
11. Dropout, 测试阶段不要用Dropout
12. 并行与分布式优化方法: Hogwild, Downpour SGD, Delay-tolerant Algorithms for SGD, Elastic Averaging SGD, 工具使用Tensor Flow.