上文提到,到目前为止,caffe总共提供了六种优化方法:

  • Stochastic Gradient Descent (type: "SGD"),
  • AdaDelta (type: "AdaDelta"),
  • Adaptive Gradient (type: "AdaGrad"),
  • Adam (type: "Adam"),
  • Nesterov’s Accelerated Gradient (type: "Nesterov") and
  • RMSprop (type: "RMSProp")

Solver就是用来使loss最小化的优化方法。对于一个数据集D,需要优化的目标函数是整个数据集中所有数据loss的平均值。

其中,fW(x(i))计算的是数据x(i)上的loss, 先将每个单独的样本x的loss求出来,然后求和,最后求均值。 r(W)是正则项(weight_decay),为了减弱过拟合现象。

如果采用这种Loss 函数,迭代一次需要计算整个数据集,在数据集非常大的这情况下,这种方法的效率很低,这个也是我们熟知的梯度下降采用的方法。

在实际中,通过将整个数据集分成几批(batches), 每一批就是一个mini-batch,其数量(batch_size)为N<<|D|,此时的loss 函数为:
 

有了loss函数后,就可以迭代的求解loss和梯度来优化这个问题。在神经网络中,用forward pass来求解loss,用backward pass来求解梯度。

在caffe中,默认采用的Stochastic Gradient Descent(SGD)进行优化求解。后面几种方法也是基于梯度的优化方法(like SGD),因此本文只介绍一下SGD。其它的方法,有兴趣的同学,可以去看文献原文。

1、Stochastic gradient descent(SGD)

随机梯度下降(Stochastic gradient descent)是在梯度下降法(gradient descent)的基础上发展起来的,梯度下降法也叫最速下降法,具体原理在网易公开课《机器学习》中,吴恩达教授已经讲解得非常详细。SGD在通过负梯度和上一次的权重更新值Vt的线性组合来更新W,迭代公式如下:


 
其中,  是负梯度的学习率(base_lr),是上一次梯度值的权重(momentum),用来加权之前梯度方向对现在梯度下降方向的影响。这两个参数需要通过tuning来得到最好的结果,一般是根据经验设定的。如果你不知道如何设定这些参数,可以参考相关的论文。

在深度学习中使用SGD,比较好的初始化参数的策略是把学习率设为0.01左右(base_lr: 0.01),在训练的过程中,如果loss开始出现稳定水平时,对学习率乘以一个常数因子(gamma),这样的过程重复多次。

对于momentum,一般取值在0.5--0.99之间。通常设为0.9,momentum可以让使用SGD的深度学习方法更加稳定以及快速。

关于更多的momentum,请参看Hinton的《A Practical Guide to Training Restricted Boltzmann Machines》。

实例:

base_lr: 0.01
lr_policy: "step"
gamma: 0.1
stepsize: 1000
max_iter: 3500
momentum: 0.9

lr_policy设置为step,则学习率的变化规则为 base_lr * gamma ^ (floor(iter / stepsize))

即前1000次迭代,学习率为0.01; 第1001-2000次迭代,学习率为0.001; 第2001-3000次迭代,学习率为0.00001,第3001-3500次迭代,学习率为10-5

上面的设置只能作为一种指导,它们不能保证在任何情况下都能得到最佳的结果,有时候这种方法甚至不work。如果学习的时候出现diverge(比如,你一开始就发现非常大或者NaN或者inf的loss值或者输出),此时你需要降低base_lr的值(比如,0.001),然后重新训练,这样的过程重复几次直到你找到可以work的base_lr。

2、AdaDelta

AdaDelta是一种”鲁棒的学习率方法“,是基于梯度的优化方法(like SGD)。

具体的介绍文献:

M. Zeiler ADADELTA: AN ADAPTIVE LEARNING RATE METHOD. arXiv preprint, 2012.

示例:

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

从最后两行可看出,设置solver type为Adadelta时,需要设置delta的值。

3、AdaGrad

自适应梯度(adaptive gradient)是基于梯度的优化方法(like SGD)

具体的介绍文献:

Duchi, E. Hazan, and Y. Singer. Adaptive Subgradient Methods for Online Learning and Stochastic Optimization. The Journal of Machine Learning Research, 2011.

示例:

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"

4、Adam

是一种基于梯度的优化方法(like SGD)。

具体的介绍文献:

D. Kingma, J. Ba. Adam: A Method for Stochastic Optimization. International Conference for Learning Representations, 2015.

5、NAG

Nesterov 的加速梯度法(Nesterov’s accelerated gradient)作为凸优化中最理想的方法,其收敛速度非常快。

具体的介绍文献:

I. Sutskever, J. Martens, G. Dahl, and G. Hinton. On the Importance of Initialization and Momentum in Deep Learning. Proceedings of the 30th International Conference on Machine Learning, 2013.

示例:

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: "step"
gamma: 0.1
stepsize: 10000
display: 100
max_iter: 65000
weight_decay: 0.0005
snapshot: 10000
snapshot_prefix: "examples/mnist/mnist_autoencoder_nesterov_train"
momentum: 0.95
# solver mode: CPU or GPU
solver_mode: GPU
type: "Nesterov"

6、RMSprop

RMSprop是Tieleman在一次 Coursera课程演讲中提出来的,也是一种基于梯度的优化方法(like SGD)

具体的介绍文献:

T. Tieleman, and G. Hinton. RMSProp: Divide the gradient by a running average of its recent magnitude. COURSERA: Neural Networks for Machine Learning.Technical report, 2012.

示例:

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: "RMSProp"
rms_decay: 0.98

最后两行,需要设置rms_decay值。

SGD

x+= -learning_rate*dx

Momentum

Momentum可以使SGD不至于陷入局部鞍点震荡,同时起到一定加速作用。
Momentum最开始有可能会偏离较远(overshooting the target),但是通常会慢慢矫正回来。

v = mu*v - learning_rate*dx
x+= v

Nesterov momentum

基本思路是每次不在x位置求dx,而是在x+mu*v处更新dx,然后在用动量公式进行计算
相当于每次先到动量的位置,然后求梯度更新
vt=&mu;vt?1?&epsilon;▽f(&theta;t?1+&mu;vt?1)
&theta;t=&theta;t?1+vt
计算▽f(&theta;t?1+&mu;vt?1)不太方便,做如下变量替换:?t?1=&theta;t?1+&mu;vt?1,并带回上述公式可以得到
vt=&mu;vt?1+&epsilon;▽f(?t?1)
?t?1=?t?1?&mu;vt?1+(1+&mu;)vt

v_prev = v
v = mu*v-learning_rate*dx
x += -mu*v_prev+(1+mu)*v 

AdaGrad

使用每个变量的历史梯度值累加作为更新的分母,起到平衡不同变量梯度数值差异过大的问题

cache += dx**2
x += -learning_rate*dx/(np.sqrt(cache)+1e-7)

RMSProp

在AdaGrad基础上加入了decay factor,防止历史梯度求和过大

cache = decay_rate*cache + (1-decay_rate)*dx**2
x += -learning_rate*dx/(np.sqrt(cache)+1e-7)

ADAM

初始版本:类似于加入动量的RMSProp

m = beta1*m + (1-beta1)*dx
v = beta2*v + (1-beta2)*(dx**2)
x += -learning_rate*m / (np.sqrt(v)+1e-7)

真实的更新算法如下:

m = beta1*m + (1-beta1)*dx
v = beta2*v + (1-beta2)*(dx**2)
mb = m/(1-beta1**t)   # t is step number
vb = v/(1-beta2**t)
x += -learning_rate*mb / (np.sqrt(vb)+1e-7)

mb和vb起到最开始的时候warm up作用,t很大之后(1-beta1**t) =1

Second Order optimization methods

second-order taylor expansion:
J(&theta;)&asymp;J(&theta;0)+(&theta;?theta0)T+12(&theta;?&theta;0)TH(&theta;?&theta;0)
&theta;?=&theta;0?H?1▽&theta;J(&theta;0)

Quasi_newton methods (BFGS) with approximate inverse Hessian matrix L-BFGS (limited memory BFGS)
Does not form/store the full inverse Hessian.
Usually works very well in full batch, deterministic mode

实际经验

ADAM通常会取得比较好的结果,同时收敛非常快相比SGD L-BFGS适用于全batch做优化的情况 有时候可以多种优化方法同时使用,比如使用SGD进行warm up,然后ADAM 对于比较奇怪的需求,deepbit两个loss的收敛需要进行控制的情况,比较慢的SGD比较适用


tensorflow 不同优化算法对应的参数

SGD

optimizer = tf.train.GradientDescentOptimizer(learning_rate=self.learning_rate)

Momentum

optimizer = tf.train.MomentumOptimizer(lr, 0.9)

AdaGrad

optimizer = tf.train.AdagradientOptimizer(learning_rate=self.learning_rate)

RMSProp

optimizer = tf.train.RMSPropOptimizer(0.001, 0.9)

ADAM

optimizer = tf.train.AdamOptimizer(learning_rate=self.learning_rate, epsilon=1e-08)

部分局部参数需要查找tensorflow官方文档

直接进行优化
train_op = optimizer.minimize(loss)
获得提取进行截断等处理
gradients, v = zip(*optimizer.compute_gradients(loss))
gradients, _ = tf.clip_by_global_norm(gradients, self.max_gradient_norm)
train_op = optimizer.apply_gradients(zip(gradients, v), global_step=self.global_step)


Caffe 不同优化算法参数

caffe的优化需要在solver.prototxt中指定相应的参数

type代表的是优化算法

比较坑的是不同的版本之间type会有变化(ADAM or Adam),需要看具体代码
* Stochastic Gradient Descent (type: “SGD”),
* AdaDelta (type: “AdaDelta”),
* Adaptive Gradient (type: “AdaGrad”),
* Adam (type: “Adam”),
* Nesterov&rsquo;s Accelerated Gradient (type: “Nesterov”) and
* RMSprop (type: “RMSProp”)

SGD

base_lr: 0.01
lr_policy: "step"    # 也可以使用指数,多项式等等
gamma: 0.1
stepsize: 1000
max_iter: 3500
momentum: 0.9

AdaDelta

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

AdaGrad

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"

Nesterov

base_lr: 0.01
lr_policy: "step"
gamma: 0.1
weight_decay: 0.0005
momentum: 0.95
type: "Nesterov"

ADAM

train_net: "nin_train_val.prototxt"
base_lr: 0.001
###############
##### step:base_lr * gamma ^ (floor(iter / stepsize))
#lr_policy: "step"
#gamma: 0.1
#stepsize: 25000
##### multi-step:
#lr_policy: "multistep"
#gamma: 0.5
#stepvalue: 1000
#stepvalue: 2000
#stepvalue: 3000
#stepvalue: 4000
#stepvalue: 5000
#stepvalue: 10000
#stepvalue: 20000
###### inv:base_lr * (1 + gamma * iter) ^ (- power)
# lr_policy: "inv"
# gamma: 0.0001
# power: 2
##### exp:base_lr * gamma ^ iter
# lr_policy: "exp"
# gamma: 0.9
##### poly:base_lr (1 - iter/max_iter) ^ (power)
# lr_policy: "poly"
# power: 0.9
##### sigmoid:base_lr ( 1/(1 + exp(-gamma * (iter - stepsize))))
# lr_policy: "sigmoid"
# gamma: 0.9
#momentum: 0.9
solver_type: ADAM
momentum: 0.9
momentum2: 0.999
delta: 1e-8
lr_policy: "fixed"display: 100
max_iter: 50000
weight_decay: 0.0005
snapshot: 5000
snapshot_prefix: "./stage1/sgd_DeepBit1024_alex_stage1"
solver_mode: GPU

RMSProp

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: "RMSProp"
rms_decay: 0.98

深度学习caffe:最优化方法相关推荐

  1. caffe模型文件解析_深度学习 Caffe 初始化流程理解(数据流建立)

    深度学习 Caffe 初始化流程理解(数据流建立) 之前在简书的文章,搬迁过来 ^-^ 本文是作者原创,如有理解错误,恳请大家指出,如需引用,请注明出处. #Caffe FeatureMap数据流的建 ...

  2. 深度学习caffe(4)——caffe配置(GPU)

    电脑:win7  64位,NVIDIA GeForce GTX1080 Ti,visual studio 2013. 深度学习caffe(1)--windows配置caffe(vs2013+pytho ...

  3. 人工智能深度学习Caffe框架介绍,优秀的深度学习架构

    在深度学习领域,Caffe框架是人们无法绕过的一座山.这不仅是因为它无论在结构.性能上,还是在代码质量上,都称得上一款十分出色的开源框架.更重要的是,它将深度学习的每一个细节都原原本本地展现出来,大大 ...

  4. 【机器学习PAI实践十】深度学习Caffe框架实现图像分类的模型训练

    背景 我们在之前的文章中介绍过如何通过PAI内置的TensorFlow框架实验基于Cifar10的图像分类,文章链接:https://yq.aliyun.com/articles/72841.使用Te ...

  5. caffe图像分类教程_跟我上手深度学习: 五分钟尝试第一个深度学习(Caffe)训练和图像分类(详细图文步骤)...

    申请深度学习的开发环境 Supervessel超能云(www.ptopenlab.com)上可以免费申请深度学习的开发环境.用户可以免费注册一个用户帐号,无须任何信用卡信息,就可以申请. 申请了用户帐 ...

  6. 深度学习Caffe 入门理解使用教程

    2019独角兽企业重金招聘Python工程师标准>>> 1.首先caffe 安装我就不解释了 如果有人安装不会的话 可以加我qq 1050316096 ,我会按照使用方式来介绍,首先 ...

  7. 深度学习caffe实战(一)验证码识别

    狭义上讲验证码识别是将验证码图像转化成字符串值,传统方法常常先对验证码图像进行字符分割,再对验证码进行识别,劣势在于字符分割方法往往针对不同风格的验证码需要做修改,某些验证码加入噪声或线条,字符位置不 ...

  8. 深度学习caffe的代码怎么读?

    知乎用户 ,Caffe / Torch7 / CNN 知乎用户.任逸风.陈文 等人赞同 我是从Torch7转移到Caffe的人,仅供参考,当你阅读前你应该具备一些有关DL的基础知识,本文集中写Caff ...

  9. 深度学习Caffe实战笔记(6)Windows caffe平台用Siamese网络跑自己的数据

    终于到了介绍如何使用Siamese网络跑自己的数据了,在网上.论坛上.群里关于用Siamese网络的资料很多,但是实战的资料很少,难道是因为太容易了吗?反正博主查阅了各种地方,几乎没有找到Siames ...

  10. 深度学习 Caffe 初始化流程理解(数据流建立)

    之前在简书的文章,搬迁过来 ^-^ 本文是作者原创,如有理解错误,恳请大家指出,如需引用,请注明出处. #Caffe FeatureMap数据流的建立 ##用语解释 FeatureMap: 输入的图片 ...

最新文章

  1. 所有人问「贴吧之父」俞军
  2. nginx 和php连接数,nginx限制ip连接数和带宽
  3. 第03讲. 原理探究,了解爬虫的基本原理
  4. JS-元素的样式操作-文本内容-位置
  5. NBA Top Shot过去24小时二级市场交易额突破630万美元
  6. Mac下安装MySQL(Mac 10.12)
  7. linux切分文件指定行_vim技巧:在不同文件buffer间切换,在多窗口跳转和改变窗口大小...
  8. java 使用websocket_Java使用WebSocket
  9. oracle 中 的 =,oracle中=是什么意思
  10. UE4 时光倒流(蓝图)
  11. 卸载Visual Studio 2015并安装Visual Studio 2019
  12. 浅谈自适应滤波器---(快速RLS算法)
  13. 【工大SCIR】对话中的情感分析与生成简述
  14. STM32——串口概念及应用
  15. camtasiastudio最新版本2022喀秋莎标准版
  16. 远程访问云服务器CentOS下 jupyter服务 【保姆级教程】
  17. 亚马逊AWS云架构支柱与数字化转型
  18. STM32之GPIO工作模式
  19. 射线法判断点是否在多边形内-JAVA
  20. 为什么笔记本电脑电源适配器基本是19V供电

热门文章

  1. 机械硬盘的改进想法:一臂多头
  2. 鼠标被计算机无法识别怎么办,win7系统usb鼠标无法识别怎么解决 电脑usb鼠标无法识别解决方法...
  3. 产业研发用房是什么意思_【企业】米东中小微创业产业园:筑巢引凤栖 花开蝶自来...
  4. java过滤器验证app用户token_SpringCloud笔记之Zuul过滤器PreFilter实现token校验(简单样例)...
  5. centos下mysql执行命令_CentOS下mysql数据库常用命令总结
  6. ipad如何连接电脑_台式电脑如何连接蓝牙耳机
  7. 数据上传需要什么硬件_搭建云服务器需要什么硬件配置
  8. Angular使用echarts
  9. 解决ubuntu 用anaconda 安装R 语言后,无法安装R语言package的问题
  10. zabbix客户端部署