3.1 Caffe最优求解过程

3.1.1 Solver介绍

Caffe的重中之重(核心)——Solver。负责对模型优化,让损失函数(loss function)达到全局最小。solver的主要作用就是交替调用前向(forward)算法和后向(backward)算法来更新参数,实际上就是一种迭代的优化算法。

到目前的版本,caffe提供了六种优化算法来求解最优参数,在solver配置文件中,通过设置type类型来选择。

• Stochastic Gradient Descent (type: "SGD")

• AdaDelta (type: "AdaDelta")

• Adaptive Gradient (type: "AdaGrad")
• Adam (type: "Adam")

• Nesterov’s Accelerated Gradient (type: "Nesterov")

• RMSprop (type: "RMSProp")

 

在每一次的迭代过程中,solver做了这几步工作:

1、调用forward算法来计算最终的输出值,以及对应的loss

2、调用backward算法来计算每层的梯度

3、根据选用的slover方法,利用梯度进行参数更新

4、记录并保存每次迭代的学习率、快照,以及对应的状态。

3.1.2 Solver参数配置

$ cd caffe/src/caffe/proto

$ vim caffe.proto

message SolverParameter {

// train_net_param, train_net, net_param, net

....

}

241 optional SolverType solver_type = 30 [default = SGD];

#结合实例讲解

net: "examples/mnist/lenet_train_test.prototxt"

//设置深度网络模型。每一个模型就是一个net,需要在一个专门的配置文件中对net进行配置,每个net

由许多的layer所组成。

//注意的是:文件的路径要从caffe的根目录开始,其它的所有配置都是这样,也可用train_net和test_net来对训练模型和测试模型分别设定:
train_net:"examples/mnist/lenet_train_test.prototxt"
test_net: “examples/mnist/lenet_test_test.prototxt"

test_iter: 100

//mnist数据中测试样本总数为10000,一次性执行全部数据效率很低,因此我们将测试数据分成几个批次来执行,每个批次的数量就是batch_size。假设我们设置batch_size为100,则需要迭代100次才能将10000个数据全部执行完。因此test_iter设置为100。执行完一次全部数据,称之为一个epoch。

test_interval: 500

//测试间隔,在训练集中每迭代500次,在测试集进行一次测试。

base_lr: 0.01 //设置基础学习率,在迭代中,可以对基础学习率进行调整。调整策略见Ir_policy

momentum: 0.9 //上一次梯度更新的权重

type: SGD //优化算法选择,这一行可以省掉,因为默认值是SGD,随机梯度下降法。

weight_decay: 0.0005 //权重衰减项,防止过拟合的一个参数。

lr_policy: "inv"

//调整策略,以下是可以设置的值和相应的学习率计算

fixed:  保持base_lr不变.

step:  如果设置为step,则还需要设置一个stepsize,  返回 base_lr * gamma ^ (floor(iter / stepsize)),其中iter表示当前的迭代次数

exp:   返回base_lr * gamma ^ iter, iter为当前迭代次数

inv:  如果设置为inv,还需要设置一个power, 返回base_lr * (1 + gamma * iter) ^ (- power)

multistep: 如果设置为multistep,则还需要设置一个stepvalue。这个参数和step很相似,step是均匀等间隔变化,而multistep则是根据stepvalue值变化

poly:  学习率进行多项式误差, 返回 base_lr (1 - iter/max_iter) ^ (power)

sigmoid: 学习率进行sigmod衰减,返回 base_lr ( 1/(1 + exp(-gamma * (iter - stepsize))))

gamma: 0.0001

power: 0.75

display: 100 //每训练100次,在屏幕上显示一次。如果设置为0,则不显示。

max_iter: 20000 //最大迭代次数,这个数设置太小,会导致没有收敛,精确度很低。设置太大,会导致震荡,浪费时间。

snapshot: 5000

snapshot_prefix: "examples/mnist/lenet"

// 将训练出来的model和solver状态进行保存,snapshot用于设置训练多少次后进行保存,默认为0,不保存。snapshot_prefix设置保存路径。

还可以设置snapshot_diff,是否保存梯度值,默认为false,不保存。

也可以设置snapshot_format,保存的类型。有两种选择:HDF5 和BINARYPROTO ,默认为BINARYPROTO

 

solver_mode: CPU

 

3.1.3 Solver 优化方式

• Stochastic Gradient Descent (type: "SGD"):即随机梯度下降,是梯度下降的batch版本

SGD

对于训练数据集,我们首先将其分成n个batch,每个batch包含m个样本。我们每次更新都利用一个batch的数据,而非整个训练集。即:

其中, 为学习率, 为x在t时刻的梯度。

好处:

当训练数据太多时,利用整个数据集更新往往时间上不显示。batch的方法可以减少机器的压力,并且可以更快地收敛。

当训练集有很多冗余时(类似的样本出现多次),batch方法收敛更快。以一个极端情况为例,若训练集前一半和后一半梯度相同。那么如果前一半作为一个batch,后一半作为另一个batch,那么在一次遍历训练集时,batch的方法向最优解前进两个step,而整体的方法只前进一个step。

缺点:

SGD方法的一个缺点是,其更新方向完全依赖于当前的batch,因而其更新十分不稳定。

 

• AdaDelta (type: "AdaDelta"):Adadelta是对Adagrad的扩展,最初方案依然是对学习率进行自适应约束,但是进行了计算上的简化。

AdaDelta

Adagrad会累加之前所有的梯度平方,而Adadelta只累加固定大小的项,并且也不直接存储这些项,仅仅是近似计算对应的平均值。即:

在此处Adadelta其实还是依赖于全局学习率,经过一定处理,经过牛顿迭代法之后:

其中,E代表求期望。

此时,Adadelta已经不用依赖于全局学习率了。

特点:

训练初中期,加速效果不错,很快

训练后期,反复在局部最小值附近抖动

 


• Adaptive Gradient (type: "AdaGrad")

AdaGrad

Adagrad其实是对学习率进行了约束。即:

此处,对 从1到t进行一个递推形成一个约束项regularizer, , 用来保证分母非0。

 

特点:

前期gt 较小的时候, regularizer较大,能够放大梯度

后期gt 较大的时候,regularizer较小,能够约束梯度

适合处理稀疏梯度

缺点:

由公式可以看出,仍依赖于人工设置一个全局学习率η 设置过大的话,会使regularizer过于敏感,对梯度的调节太大,中后期,分母上梯度平方的累加将会越来越大,使gradient→0 ,使得训练提前结束。


• Adam (type: "Adam"):本质上是带有动量项的RMSprop,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。

Adam

其中,mt ,nt 分别是对梯度的一阶矩估计和二阶矩估计,可以看作对期望E|gt| ,E|g2t| 的估计;mt^ ,nt^ 是对mt ,nt 的校正,这样可以近似为对期望的无偏估计。
可以看出,直接对梯度的矩估计对内存没有额外的要求,而且可以根据梯度进行动态调整,而−mt^nt^√+ϵ 对学习率形成一个动态约束,而且有明确的范围。

Adam的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。

特点:

结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点

对内存需求较小

为不同的参数计算不同的自适应学习率

也适用于大多非凸优化

适用于大数据集和高维空间


• Nesterov’s Accelerated Gradient (type: "Nesterov"):nesterov项在梯度更新时做一个校正,避免前进太快,同时提高灵敏度。

Nesterov


可以看出,mt−1 并没有直接改变当前梯度gt ,所以Nesterov的改进就是让之前的动量直接影响当前的动量。即:

 

momentum首先计算一个梯度(短的蓝色向量),然后在加速更新梯度的方向进行一个大的跳跃(长的蓝色向量)。

nesterov项首先在之前加速的梯度方向进行一个大的跳跃(棕色向量),计算梯度然后进行校正(绿色梯向量)。


• RMSprop (type: "RMSProp"):可以算作Adadelta的一个特例。

RMSProp

时,

就变成了求梯度平方和的平均数。

如果再求根的话,就变成了RMS(均方根):

此时,这个RMS就可以作为学习率 的一个约束:

特点:

• 其实RMSprop依然依赖于全局学习率

• RMSprop算是Adagrad的一种发展,和Adadelta的变体,效果趋于二者之间

• 适合处理非平稳目标

• 对于RNN效果很好

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值