大家好,欢迎来到专栏《调参实战》,虽然当前自动化调参研究越来越火,但那其实只是换了一些参数来调,对参数的理解和调试在机器学习相关任务中是最基本的素质,在这个专栏中我们会带领大家一步一步理解和学习调参。 本次主要讲述图像分类项目中的优化方法的调参实践,这次与上一期学习率调参的内容是一脉相承的。 作者&编辑 | 言有三 本文资源与结果展示 本文篇幅:3100字 背景要求:会使用Python和任一深度学习开源框架 附带资料:Caffe代码和数据集一份 同步平台:有三AI知识星球(一周内) 1 项目背景与准备工作 上一期我们基于图像分类任务,对学习率的几种常见的方式进行了调参学习,这一期我们来实验不同的优化方法的原理差异以及它们的性能比较。 本次项目开发需要以下环境: (1) Linux系统,推荐ubuntu16.04或者ubuntu18.04。使用windows系统也可以完成,但是使用Linux效率更高。 (2) 最好拥有一块显存不低于6G的GPU显卡,如果没有使用CPU进行训练速度较慢。 (3) 安装好的Caffe开源框架。 本次的数据集和基准模型与上一期内容相同,大家如果不熟悉就去查看上一期的内容,链接如下: 2 优化方法原理与实践 下面我们对各类优化算法的基本原理进行讲解,并进行实践。由于本文目标不是为了从零开始讲清楚优化算法,所以有些细节会略过。 2.1 标准梯度下降算法 梯度下降算法,即通过梯度的反方向来进行优化,批量梯度下降(Batch gradient descent)用公式表述如下: 写成伪代码如下: for i in range(nb_epochs): 上面的梯度下降算法公式用到了数据集所有的数据,这在解决实际问题时通常是不可能,比如ImageNet1000有100G以上的图像,内存装不下,速度也很慢。 我们需要在线能够实时计算,比如一次取一个样本,于是就有了随机梯度下降(Stochastic gradient descent),简称SGD,公式如下: 写成伪代码如下: for i in range(nb_epochs): SGD方法缺点很明显,梯度震荡,所以就有了后来大家常用的小批量梯度下降算法(Mini-batch gradient descent),公式如下: 伪代码如下: for i in range(nb_epochs): 平时当我们说SGD算法,实际上指的就是mini-batch gradient descent算法。 SGD算法的主要问题是学习率大小和策略需要手动选择,优化迭代比较慢,因此有很多方法对其进行改进。 2.2 动量法(momentum) 梯度下降算法是按照梯度的反方向进行参数更新,但是刚开始的时候梯度不稳定,方向改变是很正常的,梯度有时候一下正一下反,导致做了很多无用的迭代。而动量法做的很简单,相信之前的梯度。如果梯度方向不变,就越发更新的快,反之减弱当前梯度。 公式表达如下: 与SGD的对比如下: 动量法至今仍然是我觉得最为有用的学习率改进算法。那它和SGD的对比究竟如何呢?下面我们来实验不同的参数,需要在solver.prototxt中修改配置,完整的solver如下,需要修改的地方为标粗橙色部分,后面的实验同理。 net: "allconv6.prototxt" test_interval:100 test_iter:15 base_lr: 0.01 lr_policy: "step" stepsize: 10000 gamma: 0.1 momentum: 0.9 ##动量项配置 weight_decay: 0.005 display: 100 max_iter: 100000 snapshot: 10000 snapshot_prefix: "models/allconv6_" solver_mode: GPU 下图是实验结果对比: 我们可以发现,m=0.9时确实取得了最好的效果,m=0时效果最差,对于大部分的任务,我们在配置这个参数时也不需要修改,就采用m=0.9。 |
|