caffe最优化方法
上文提到,到目前为止,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
x+= -learning_rate*dx
Momentum
Momentum可以使SGD不至于陷入局部鞍点震荡,同时起到一定加速作用。
Momentum最开始有可能会偏离较远(overshooting the target),但是通常会慢慢矫正回来。
- v = mu*v - learning_rate*dx
- x+= v
v = mu*v - learning_rate*dx
x+= v
Nesterov momentum
基本思路是每次不在x位置求dx,而是在x+mu*v处更新dx,然后在用动量公式进行计算
相当于每次先到动量的位置,然后求梯度更新
vt=μvt?1?ε▽f(θt?1+μvt?1)
θt=θt?1+vt
计算▽f(θt?1+μvt?1)不太方便,做如下变量替换:?t?1=θt?1+μvt?1 ,并带回上述公式可以得到
vt=μvt?1+ε▽f(?t?1)
?t?1=?t?1?μvt?1+(1+μ)vt
- v_prev = v
- v = mu*v-learning_rate*dx
- x += -mu*v_prev+(1+mu)*v
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)
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)
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)
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)
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(θ)≈J(θ0)+(θ?theta0)T+12(θ?θ0)TH(θ?θ0)
θ?=θ0?H?1▽θJ(θ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’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
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
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”
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”
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
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
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
</div></div>
caffe最优化方法相关推荐
- 最优化方法系列:Adam+SGD-AMSGrad 重点
https://blog.csdn.net/wishchin/article/details/80567558 自动调参的Adam方法已经非常给力了,不过这主要流行于工程界,在大多数科学实验室中,模型 ...
- caffe 下一些参数的设置
weight_decay防止过拟合的参数,使用方式: 1 样本越多,该值越小 2 模型参数越多,该值越大 一般建议值: weight_decay: 0.0005 lr_mult,decay_mult ...
- Caffe框架GPU与MLU计算结果不一致请问如何调试?
Caffe框架GPU与MLU计算结果不一致请问如何调试? 某一检测模型移植到Cambricon Caffe上时,发现无法检测出结果,于是将GPU和MLU的运行结果输出并保存后进行对比,发现二者计算结果 ...
- 常用深度学习框——Caffe/TensorFlow / Keras/ PyTorch/MXNet
常用深度学习框--Caffe/TensorFlow / Keras/ PyTorch/MXNet 一.概述 近几年来,深度学习的研究和应用的热潮持续高涨,各种开源深度学习框架层出不穷,包括Tensor ...
- visual studio2010-2015编译部署caffe
Windows版本caffe,编译所需三方库,项目工程,生成静态库和动态库,安装运行说明文档,分类任务示例demo. 下载地址:下载地址
- 标准caffe中实现darknet相关层。caffe和darknet模型的相互转换和加速(分类、检测、分割)
caffe实现darknet中的相关层,主要是yolo层和upsample层等: 实现yolo网络的训练和测试(分类.检测和分割): 提供darknet模型转caffe模型: 实现bn层合并和yolo ...
- 基于caffe的度量学习实现(Siamese network Triplet network)
基于caffe的度量学习实现,主要是孪生网络和三元组网络(Siamese network & Triplet network)实现图像的分类和度量. 包含数据集制作脚本,训练测试脚本和pyth ...
- 经典网络LeNet-5介绍及代码测试(Caffe, MNIST, C++)
LeNet-5:包含7个层(layer),如下图所示:输入层没有计算在内,输入图像大小为32*32*1,是针对灰度图进行训练和预测的.论文名字为" Gradient-Based Learni ...
- 在Caffe中调用TensorRT提供的MNIST model
在TensorRT 2.1.2中提供了MNIST的model,这里拿来用Caffe的代码调用实现,原始的mnist_mean.binaryproto文件调整为了纯二进制文件mnist_tensorrt ...
- 使用Caffe基于cifar10进行物体识别
在http://blog.csdn.net/fengbingchun/article/details/72953284中对cifar10进行train,这里通过train得到的model,对图像进行识 ...
最新文章
- python如何最适合web开发中的人工智能?
- 云效(原RDC)如何构建一个基于Maven的Java项目
- NSOperation下载网络图片(四)
- 基于深度卷积神经网络进行人脸识别的原理是什么?
- C++调用Python实例
- AutoLayout bug集合
- opencv python教程-OpenCV4 Python 最新中文版官方教程来了(附下载)
- 设计模式C++实现_2_简单工厂模式
- 2012,字王强势回归
- L_01 网络字节顺序
- keyup常用事件_KeyUp 事件
- vs2019安装包显示网络未链接_BBO最新5.19版下载及WBF世界网络赛指引
- idea更换源_在Intelij IDEA中修改阿里Maven源
- 快手无水印解析API
- linux中的段定义的,Linux中的段
- 松下plcgr7安装序列号_向上一阶段跃进,松下 SZ5/SX2 对比、体验与心得
- 《城市化》(顾朝林)-1
- 视频剪辑完成,应该如何给视频配音?三种配音方法快来学
- 【重要】 性能测试设计能力解决方案
- 不同应用选择荧光染料 -CY7 ALK脂溶性Sulfo-Cyanine7 alkyne 结构式应用
热门文章
- 全面改革个税关乎民生和正义
- Oracle SYSAUX 表空间 说明
- CMWAP和CMNET 的主要区别与适用范围
- odoo网页上传本地视频
- python 100天 pdf 最新版_GitHub - Nolan2018/Python-100-Days: Python - 100天从新手到大师
- 解决安装Visual Studio 2010 SP1时被NDP40-KB2468871.exe补丁卡死以及mscorsvw.exe进程CPU占用率高的问题...
- python 百度人脸 sdk_深更半夜实现python百度api人脸识别
- 使用MapReduce实现k-means算法
- 关系型数据库 遵循ACID原则
- 腾达路由器显示远程服务器无响应,腾达路由器设置及可能出现的问题