zhuanlan.zhihu.com
目前深度学习模型多采用批量随机梯度下降算法进行优化,随机梯度下降算法的原理如下,
n是批量大小(batchsize),η是学习率(learning rate)。可知道除了梯度本身,这两个因子直接决定了模型的权重更新 ,从优化本身来看它们是影响模型性能收敛最重要的参数。
学习率直接影响模型的收敛状态,batchsize则影响模型的泛化性能 ,两者又是分子分母的直接关系,相互也可影响,因此这一次来详述它们对模型性能的影响。
模型性能对batchsize虽然没有学习率那么敏感,但是在进一步提升模型性能时,batchsize就会成为一个非常关键的参数。(关于学习率对模型性能的影响,可以参考上文)
1 大的batchsize减少训练时间,提高稳定性
这是肯定的,同样的epoch数目,大的batchsize需要的batch数目减少了,所以可以减少训练时间,目前已经有多篇公开论文在1小时内训练完ImageNet数据集。另一方面,大的batch size梯度的计算更加稳定,因为模型训练曲线会更加平滑。在微调的时候,大的batch size可能会取得更好的结果。
2 大的batchsize导致模型泛化能力下降
在一定范围内,增加batchsize有助于收敛的稳定性,但是随着batchsize的增加,模型的性能会下降,如下图,来自于文[5]。
这是研究者们普遍观测到的规律,虽然可以通过一些技术缓解。这个导致性能下降的batch size在上图就是8000左右。
那么这是为什么呢?
研究[6]表明大的batchsize收敛到sharp minimum,而小的batchsize收敛到flat minimum,后者具有更好的泛化能力。 两者的区别就在于变化的趋势,一个快一个慢,如下图,造成这个现象的主要原因是小的batchsize带来的噪声有助于逃离sharp minimum。
Hoffer[7]等人的研究表明,大的batchsize性能下降是因为训练时间不够长,本质上并不少batchsize的问题 ,在同样的epochs下的参数更新变少了,因此需要更长的迭代次数。
总之batchsize在变得很大(超过一个临界点)时,会降低模型的泛化能力。在这个临界点之下,模型的性能变换随batch size通常没有学习率敏感。
3 学习率和batchsize的关系
通常当我们增加batchsize为原来的N倍时,要保证经过同样的样本后更新的权重相等,按照线性缩放规则,学习率应该增加为原来的N倍[5]。但是如果要保证权重的方差不变,则学习率应该增加为原来的sqrt(N)倍[7],目前这两种策略都被研究过,使用前者的明显居多。
从两种常见的调整策略来看,学习率和batchsize都是同时增加的。学习率是一个非常敏感的因子,不可能太大,否则模型会不收敛。同样batchsize也会影响模型性能,那实际使用中都如何调整这两个参数呢?
研究[8]表明,衰减学习率可以通过增加batchsize来实现类似的效果 ,这实际上从SGD的权重更新式子就可以看出来两者确实是等价的,文中通过充分的实验验证了这一点。
研究[9]表明,对于一个固定的学习率,存在一个最优的batchsize能够最大化测试精度 ,这个batchsize和学习率以及训练集的大小正相关。
对此实际上是有两个建议:
如果增加了学习率,那么batch size最好也跟着增加,这样收敛更稳定。
尽量使用大的学习率,因为很多研究都表明更大的学习率有利于提高泛化能力。 如果真的要衰减,可以尝试其他办法,比如增加batch size,学习率对模型的收敛影响真的很大,慎重调整。
参考文献
[1] Smith L N. Cyclical learning rates for training neural networks[C]//2017 IEEE Winter Conference on Applications of Computer Vision (WACV). IEEE, 2017: 464-472.
[2] Loshchilov I, Hutter F. Sgdr: Stochastic gradient descent with warm restarts[J]. arXiv preprint arXiv:1608.03983, 2016.
[3] Reddi S J, Kale S, Kumar S. On the convergence of adam and beyond[J]. 2018.
[4] Keskar N S, Socher R. Improving generalization performance by switching from adam to sgd[J]. arXiv preprint arXiv:1712.07628, 2017.
[5] Goyal P, Dollar P, Girshick R B, et al. Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour.[J]. arXiv: Computer Vision and Pattern Recognition, 2017.
[6] Keskar N S, Mudigere D, Nocedal J, et al. On large-batch training for deep learning: Generalization gap and sharp minima[J]. arXiv preprint arXiv:1609.04836, 2016.
[7] Hoffer E, Hubara I, Soudry D. Train longer, generalize better: closing the generalization gap in large batch training of neural networks[C]//Advances in Neural Information Processing Systems. 2017: 1731-1741.
[8] Smith S L, Kindermans P J, Ying C, et al. Don't decay the learning rate, increase the batch size[J]. arXiv preprint arXiv:1711.00489, 2017.
[9] Smith S L, Le Q V. A bayesian perspective on generalization and stochastic gradient descent[J]. arXiv preprint arXiv:1710.06451, 2017.
谈谈深度学习中的 Batch_Size Batch_Size(批尺寸)是机器学习中一个重要参数,涉及诸多矛盾,下面逐一展开。
首先,为什么需要有 Batch_Size 这个参数? Batch 的选择,首先决定的是下降的方向。 如果数据集比较小,完全可以采用全数据集 ( Full Batch Learning )的形式,这样做至少 有 2 个好处:其一,由全数据集确定的方向能够更好地代表样本总体,从而更准确地朝向极值所在的方向 。其二,由于不同权重的梯度值差别巨大,因此选取一个全局的学习率很困难。 Full Batch Learning 可以使用Rprop 只基于梯度符号并且针对性单独更新各权值。
对于更大的数据集,以上 2 个好处又变成了 2 个坏处:其一,随着数据集的海量增长和内存限制,一次性载入所有的数据进来变得越来越不可行。其二,以 Rprop 的方式迭代,会由于各个 Batch 之间的采样差异性,各次梯度修正值相互抵消,无法修正。这才有了后来 RMSProp 的妥协方案。
既然 Full Batch Learning 并不适用大数据集,那么走向另一个极端怎么样? 所谓另一个极端,就是每次只训练一个样本,即 Batch_Size = 1。这就是在线学习 (Online Learning) 。线性神经元在均方误差代价函数的错误面是一个抛物面,横截面是椭圆。对于多层神经元、非线性网络,在局部依然近似是抛物面。使用在线学习,每次修正方向以各自样本的梯度方向修正,横冲直撞各自为政,难以达到收敛 。
可不可以选择一个适中的 Batch_Size 值呢? 当然可以,这就是批梯度下降法(Mini-batches Learning) 。因为如果数据集足够充分,那么用一半(甚至少得多 )的数据训练算出来的梯度与用全部数据训练出来的梯度是几乎一样 的。
在合理范围内,增大 Batch_Size 有何好处 ?
内存利用率提高了,大矩阵乘法的并行化效率提高。
跑完一次 epoch(全数据集)所需的迭代次数减少,对于相同数据量的处理速度进一步加快。
在一定范围内,一般来说 Batch_Size 越大,其确定的下降方向越准,引起训练震荡越小。
盲目增大 Batch_Size 有何坏处 ?
内存利用率提高了,但是内存容量可能撑不住了。
跑完一次 epoch(全数据集)所需的迭代次数减少,要想达到相同的精度,其所花费的时间大大增加了,从而对参数的修正也就显得更加缓慢。
Batch_Size 增大到一定程度,其确定的下降方向已经基本不再变化。
调节 Batch_Size 对训练效果影响到底如何? 这里跑一个 LeNet 在 MNIST 数据集上的效果。MNIST 是一个手写体标准库,我使用的是 Theano 框架。这是一个 Python 的深度学习库。安装方便 (几行命令而已),调试简单(自带 Profile),GPU / CPU 通吃,官方教程相当完备 ,支持模块十分丰富(除了 CNNs,更是支持 RBM / DBN / LSTM / RBM-RNN / SdA / MLPs)。在其上层有 Keras 封装,支持 GRU / JZS1, JZS2, JZS3 等较新结构,支持 Adagrad / Adadelta / RMSprop / Adam 等优化算法。
运行结果如上图所示,其中绝对时间做了标幺化处理。运行结果与上文分析相印证:
Batch_Size 太小,算法在 200 epoches 内不收敛。
随着 Batch_Size 增大,处理相同数据量的速度越快。
随着 Batch_Size 增大,达到相同精度所需要的 epoch 数量越来越多。
由于上述两种因素的矛盾, Batch_Size 增大到某个 时候,达到时间上 的最优。
由于最终收敛精度会陷入不同的局部极值,因此 Batch_Size 增大到某些 时候,达到最终收敛精度上 的最优。
欢迎一起讨论。
caffe小菜鸟也来答一下,感觉就是大batch size在显存能允许的情况下收敛速度是比较快的但有时的确会有陷入局部最小的情况,小batch size引入的随机性会更大些,有时候能有更好的效果,但是就是收敛速度慢一些…… 还有就是除了batch size这个参数外,如果在solver setting中有momentum这个参数的话也要注意batch size的选取,具体参考一下caffe的tutorial
关于训练参数怎么选取可以参考以下一些文章: Bengio的 Practical recommendations for gradient-based learninghttp:// link.springer.com/chapt er/10.1007/978-3-642-35289-8_26
Lecun 和 Bottou的 Efficient Backprophttp:// link.springer.com/chapt er/10.1007/978-3-642-35289-8_3
还有一个代码上的细节,就是caffe的代码实现上选取一个batch的时候似乎是按着数据库的图片顺序选取输入图片的,所以在生成数据库的时候切记要shuffle一下图片顺序~
供题主参考,求大神指正~
2017年6月3号 update: 一年多之后忽然又想起了这个答案的存在,那我就多说几句,随着batch normalization的普及,收敛速度已经不像前bn时代一样需要非常玄学的调参,现在一般都还是采取大batch size,毕竟GPU友好嘛,高票答案说的batch size大了一个epoch update数量少了的这个缺点在bn面前似乎也没太多存在感了。不过bn的坏处就是不能用太小的batch size,要不然mean和variance就偏了。所以现在一般是显存能放多少就放多少。而且实际调起模型来,真的是数据分布和预处理更为重要,数据不行的话 玩再多花招也没用
批训练的引入最大好处是针对非凸损失函数来做的, 毕竟非凸的情况下, 全样本就算工程上算的动, 也会卡在局部优上, 批表示了全样本的部分抽样实现, 相当于人为引入修正梯度上的采样噪声,使“一路不通找别路”更有可能搜索最优值。
楼上很多说到随机梯度收敛问题,物理上是这样的理解,
增加噪音扩大了你的行动范围,不会受限于局部。
然而过大的行动范围使得你的选择过多而”迷茫“。
这是一个损失函数局部优有“多坑人”和局部优“数目太多好难选”之间的竞争,竞争平衡点才是你最终的训练值。故此,最终的训练值是一个分布,大伙们一般取平均来证明自己的模型多牛逼。
物理上,就是能量(坑好深)和熵(选择多)的竞争结果,而且复杂系统中,能量和熵一辈子都在竞争,讨论自由能最小值在非凸问题上的意义,比直接讨论损失函数的最小值更有意义。
然而,这种牛逼,不仅依赖模型,而且依赖数据本身。调参需要预先建立竞争平衡的理论模型,单纯用软件刷指标只能用在某个数据集上,不具有转移性。纯浪费电! 这些观点在大部分复杂物理系统的采样,自旋玻璃的研究,蛋白质折叠构象搜索上,都有广泛的认识。但是工业界被凸优化影响过多了,除了特征选择和防止过拟合外可以通过直觉建立,遇到非凸优化问题,基本不可能拍脑袋调出一个通用的(如果数学上可以,物理上应该最先发现,然而并没有)。于是,即便在物理上遇到这种问题,目前很low,而且节省成本的方法就是烧钱增加计算蛮力点。矛盾到我笑尿了。
关于深度学习中的非凸优化,可以参考LeCun今年来对深度学习和自旋玻璃之间的联系,以及随机微分方程同增强采样之间的研究。
Batch size会影响模型性能,过大或者过小都不合适。
1. 是什么?
设置过大的批次(batch)大小 ,可能会对训练时网络的准确性产生负面影响 ,因为它降低了梯度下降的随机性。
2. 怎么做?
要在可接受的训练时间内,确定最小的批次大小。 一个能合理利用GPU并行性能的批次大小可能不会达到最佳的准确率,因为在有些时候,较大的批次大小可能需要训练更多迭代周期才能达到相同的正确率。
在开始时,要大胆地尝试很小的批次大小,如16、8,甚至是1。
3. 为什么?
较小的批次大小能带来有更多起伏、更随机的权重更新。这有两个积极的作用 ,一是能帮助训练“跳出”之前可能卡住它的局部最小值,二是能让训练在“平坦”的最小值结束,这通常会带来更好的泛化性能。
4. 还有什么?
数据中其他的一些要素有时也能起到批次大小的作用。
例如,以两倍大小的先前分辨率来处理图像,得到的效果与用四倍批次大小相似。
做个直观的解释,考虑在CNN网络中,每个滤波器的权重更新值将根据输入图像的所有像素点和批次中的每张图像来进行平均,将图像分辨率提高两倍,会产生一种四倍像素量同样的平均效果,与将批次大小提高四倍的做法相似。
总体来说,最重要的是要考虑到,在每次迭代中有多少决定性的梯度更新值被平均,并确保平衡好这种不利影响与充分利用GPU并行性能的需求之间的关系。
当然,在训练网络时,还可能遇到其他棘手的问题。关于神经网络调试的更多新手指南 请移步:
量子学园:我搭的神经网络不work该怎么办!看看这11条新手最容易犯的错误
ICLR 2017 有一篇论文专门讨论了这个问题
On Large-Batch Training for Deep Learning: Generalization Gap and Sharp Minima (Nitish Shirish Keskar, Dheevatsa Mudigere, Jorge Nocedal, Mikhail Smelyanskiy, Ping Tak Peter Tang)
“We investigate the cause for this generalization drop in the large-batch regime and present numerical evidence that supports the view that large-batch methods tend to converge to sharp minimizers of the training and testing functions—and as is well known, sharp minima lead to poorer generalization. In contrast, small-batch methods consistently converge to flat minimizers, and our experiments support a commonly held view that this is due to the inherent noise in the gradient estimation”
太大的batch size 容易陷入sharp minima,泛化性不好
看你GPU显存,显存大就把batch size设大点,反之亦然。一般情况下对学习效果没影响。
补充点细节:
事实上从优化的角度来说最快的是纯stochastic,即batch size为1。 关于这一点参见Leon Bottou的分析:http:// leon.bottou.org/publica tions/pdf/compstat-2010.pdf 。当然,文中的分析适用于large scale的情况下,但deep neural net适用的条件之一就是有大量数据。另外http:// cilvr.nyu.edu/lib/exe/f etch.php?media=deeplearning:dl-optimization.pdf 的第11页也有比较stochastic和batch的优劣。
拿Yann Lecun在上述第二个链接第10页中举的toy example来说,如果事实上只有100个数据点,但有人各复制了10遍拿给你,你不知道。这时候你如果做batch gradient descent,更只用了100个点效果一样;而做stochastic gradient descent则相当于做了10个epoch。相近的计算量后者效果显然更好。至于mini batch,要你取的每个mini batch都很diverse的情况才会效果好。
当然你会说,现实中哪会有100个数据各重复10遍就直接拿来用的?没错,是不会,但现实中的数据,尤其是large scale的数据中,必然有大量的redundancy,不然你也很难学出有较好泛化性的model。因此stochastic在large scale总是优于batch。
那为什么还要用mini batch呢?这是由于GPU并行运算的性质,同时把多组数据传过去一起运算比一条一条运算来的快,因而mini batch只是为了充分利用GPU memory而做出的妥协。既然如此,batch size也调到刚好能塞进显存就差不多了。
深度神经网络的优化是个nonconvex problem.所以基于SGD的训练batch size不能取过大。过大的batchsize的结果是网络很容易收敛到一些不好的局部最优点。。同样太小的batch也存在一些问题,比如训练速度很慢,训练不容易收敛等。。具体的batch size的选取和训练集的样本数目相关。。举个例子,比如在3小时的语音识别库(大约108万个样本)训练DNN,通常batch 取128..而在300小时的库上会取1024..
可以考虑两个极端:A.全部数据作为一个batch和 B.每个采样作为一个batch A.如果用全部数据作为一个batch,优点有如下: 1. 这样理论上是可以得到全局收敛的 2. 可以用一些加速收敛算法,比如L-BFGS之类的 3. 便于并行计算 但是同样存在缺点: 如果数据集过大,训练会很慢的
B.每个采样作为一个batch,优点有如下 1. B方法在每个采样上的参数修正方向会与整体最优的方向有出入。这条看似是个缺点,实际上,DNN因为是非线性模型,有很多参数,现有目标函数会有很多局部极值,这就会导致模型不精确。因为A方法每次修正依赖于现有模型和所有数据,很难跳出这些局部极值,所以A方法是一种很依赖于初始模型的方法。而B方法基于每个采样去修正,修正幅度大了以后,就容易跳出这些局部极值,避免过拟合发生。B方法一般不依赖于初始模型,所以可以用来训练初始的神经网络。之后再用A方法或者下面介绍的C方法优化 2. 速度在大部分情况比A方法快。 缺点就是 1. 难以并行计算 2. 因为每次更新基于单个采样,很容易导致难以收敛。这个发生原因和优点1 是一样的。这种现象有时是优点有时也是缺点,主要取决于学习率的选择。
于是就有第三种情况,C:一部分数据作为一个batch,这种情况每次更新模型修正幅度没有A那么小,也没有B那么大,而且可以并行计算,所以速度也比较快。 一般用的时候,在非监督训练阶段,可以先用B方法创建初始模型, 然后在监督训练阶段,选择小batch size进行初步训练,让模型跳出局部极值,之后用大的batch size让模型收敛,这样一般能达到比较好的效果
参考:Dong Yu, Li Deng, Automatic Speech Recognition, Springer
搞机器学习大忌就是不做实验想当然,话说这种问题题主跑几组不同的batch不就知道了...调参调参不调哪来的参~
另外,运用在不同的领域,不同的网络结构,不同的训练方法,batch的取法,用法和影响也不一样。不知道题主问的是哪种batch?
batch_size设的大一些,收敛得快,也就是需要训练的次数少,准确率上升得也很稳定,但是实际使用起来精度不高。
batch_size设的小一些,收敛得慢,而且可能准确率来回震荡,所以还要把基础学习速率降低一些;但是实际使用起来精度较高。
一般我只尝试batch_size=64或者batch_size=1两种情况。
Batch size对深度学习的训练是有很大意义,但是对其推理除了提高了整体性能和降低了AI芯片的功耗外,没有特别的意义,还有一个重要的问题是,batch size推理会不会造成输出的结果有卡顿的现象,比如实时的摄像头采集图像,要先换成几帧图像用作batch size处理,然后,处理完的结果,在整体输出,这样会造成输出卡顿的现象呢。。。。
这个问题又是一个机器学习问题。
写个算法,理论上可以搜索出一个理想的参数来。
大部分人是人工调参,依靠的是经验。
谷歌利用算法,做到了自动调参,这种算法估计需要强大算力来支撑,需要的计算量更多。其他机器学习模型都可以使用这种自动调参,少的参数可以穷举,多的参数可以使用类似粒子群算法来实现。这种方法求出来的参数也要防止过拟合。
专栏 | 自动选模型+调参:谷歌AutoML背后的技术解析
我也看到过说理论上batchsize=1是最好的,不过实际上调的时候,可能因为我调参的能力比较有限,确实batchsize太小会出现网络收敛不稳定,最后结果比较差的情况,这个在ImageNet和其他数据库上都遇到过,而batchsize太大确实也会影响随机性的引入。目前一般调ImageNet的时候,大家都喜欢把显存占满,不过小一些的库,个人感觉还是应该大大小小都尝试一下。不知道各路大神有没有什么好办法指点一下。。