参考网址:
http://sebastianruder.com/optimizing-gradient-descent/index.html#gradientdescentvariants
http://caffe.berkeleyvision.org/tutorial/solver.html
在caffe中实现了六种优化方法,如下:
- Stochastic Gradient Descent (type: “SGD”)
- AdaDelta (type: “AdaDelta”)
- Adaptive Gradient (type: “AdaGrad”)
- Adam (type: “Adam”)
- Nesterov’s Accelerated Gradient (type: “Nesterov”)
RMSprop (type: “RMSProp”)
通常对于一个数据集D,需要优化下面的目标函数。
如果采样上述的优化手段,需要计算整个数据集,效率是非常低的,因此将数据分成不同的批次进行训练。公式如下:
1、随机梯度下降(SGD)
caffe实现的采用的是SGD+momentum的配置,相比普通的SGD,这种配置可以极大提高收敛速度。
需要设置参数momentum和学习率。在深度学习中使用SGD,比较好的初始化参数的策略是把学习率设为0.01左右,训练过程中,如果loss出现稳定水平时,学习乘以一个常数因子,这样的过程重复多次。momentum一般设为0.9。./examples/imagenet/alexnet_solver.prototxt文件如下:
base_lr: 0.01 # begin training at a learning rate of 0.01 = 1e-2
lr_policy: "step" # learning rate policy: drop the learning rate in "steps"
# by a factor of gamma every stepsize iterations
gamma: 0.1 # drop the learning rate by a factor of 10
# (i.e., multiply it by a factor of gamma = 0.1)
stepsize: 100000 # drop the learning rate every 100K iterations
max_iter: 350000 # train for 350K iterations total
momentum: 0.9
这里的学习策略 lr_policy是:step,即:https://stackoverflow.com/questions/30033096/what-is-lr-policy-in-caffe
base_lr * gamma ^ (floor(iter / stepsize)),100000次迭代为0.1 * 0.01, 200k-300k为 0.1 * 0.1 *0.01。
上面的策略只是一种指导,在实际训练中如果loss出现NaN的情况,这时因为梯度变得非常大,超出了浮点表示的范围,因此可以减少学习率大小。参考https://zhuanlan.zhihu.com/p/25110930
2、AdaGrad
AdaGrad是一种自适应梯度的优化方法,前面的SGD方法所有参数都是同一学习率,而AdaGrad则对每个参数都采用不同的学习率。公式如下:
Gt∈Rd×d是一个对角矩阵,每个对角线位置i,i的值累加到t次迭代的对应参数 θi 梯度平方和。ϵ是平滑项,防止除零操作,一般取值1e−8。去掉平方根操作算法的表现会大打折扣。
使用例程如下:
net: "examples/mnist/mnist_autoencoder.prototxt"
test_state: { stage: 'test-on-train' }
test_iter: 500
test_state: { stage: 'test-on-test' }
test_iter: 100
test_interval: 500
test_compute_loss: true
base_lr: 0.01
lr_policy: "fixed"
display: 100
max_iter: 65000
weight_decay: 0.0005
snapshot: 10000
snapshot_prefix: "examples/mnist/mnist_autoencoder_adagrad_train"
# solver mode: CPU or GPU
solver_mode: GPU
type: "AdaGrad"
AdaGrad的缺点是当学习率逐渐递减,到训练后期则无法学习到新的参数。
3、AdaDelta
AdaDelta是一种“鲁棒的学习率方法”,是一种基于SGD的方法,由于在AdaGrad中,Gt参数theta梯度平方和,学习率是一个单调递减的过程,Adadelta把历史梯度累积窗口限制到固定的大小w,而不是累积所有梯度平方和。计算过程中动态平均值E[gt]仅仅取决于当前的梯度值与上一刻的梯度值。
学习率更新替换掉AdaGrad策略,使用下式作为学习率更新方法。
net: "examples/mnist/lenet_train_test.prototxt"
test_iter: 100
test_interval: 500
base_lr: 1.0
lr_policy: "fixed"
momentum: 0.95
weight_decay: 0.0005
display: 100
max_iter: 10000
snapshot: 5000
snapshot_prefix: "examples/mnist/lenet_adadelta"
solver_mode: GPU
type: "AdaDelta"
delta: 1e-6
4、Adam
Adam也是一种自适应学习率的方法,与Adadelta不同的是使用动量进行学习率衰减,公式如下:
mt与vt分别是梯度的带权平均和带权有偏方差,初始为0向量,Adam的作者发现他们倾向于0向量(接近于0向量),特别是在衰减因子(衰减率)β1,β2接近于1时。为了改进这个问题,对mt与vt进行偏差修正(bias-corrected)
然后更新学习率:
论文中建议默认值:β1=0.9,β2=0.999,ϵ=10−8。论文中将Adam与其它的几个自适应学习速率进行了比较,效果均要好。
5、NAG
Nesterov 的加速梯度法(Nesterov’s accelerated gradient)作为凸优化中最理想的方法,其收敛速度非常快。
6、RMSprop
选择何种优化方法?
如果你输入的特征是稀疏的,使用自适应学习率的优化方法,可以获得不错的效果。
RMSprop是Adagrad的一种扩展,与Adadelta类似,但是改进版的Adadelta使用RMS去自动更新学习速率,并且不需要设置初始学习速率。而Adam是在RMSprop基础上使用动量与偏差修正。RMSprop、Adadelta与Adam在类似的情形下的表现差不多。Kingma[15]指出收益于偏差修正,Adam略优于RMSprop,因为其在接近收敛时梯度变得更加稀疏。因此,Adam可能是目前最好的SGD优化方法。
有趣的是,最近很多论文都是使用原始的SGD梯度下降算法,并且使用简单的学习速率退火调整(无动量项)。现有的已经表明:SGD能够收敛于最小值点,但是相对于其他的SGD,它可能花费的时间更长,并且依赖于鲁棒的初始值以及学习速率退火调整策略,并且容易陷入局部极小值点,甚至鞍点。因此,如果你在意收敛速度或者训练一个深度或者复杂的网络,你应该选择一个自适应学习速率的SGD优化方法