Batch_size不宜选的太小,太小了容易不收敛,或者需要经过很大的epoch才能收敛;也没必要选的太大,太大的话首先显存受不了,其次可能会因为迭代次数的减少而造成参数修正变的缓慢。
(1)模型的复杂度,复杂的模型占的内存比简单的模型要大很多,这一点容易被忽略;
(2)电脑可能还在运行其他占显存的任务,使用nvida-smi命令来查看,并关闭它们;
(3)不光train阶段的Batch_size要改,test阶段的Batch_size也要调小,我以前一直以为只改动train的就可以了,too naive;
(4)图片大小
遇到了一个问题,虽然还没解决,也不知道错误在哪?运行中间说batch_size出现错误。。。
137 self.n_batch_size = int(config.get("train", "batch_size"))
-_-||原因是因为公司及其内存不够了。。。137
这个句话有问题20190829,并不是越多越好。
网易面试官问了一个问题学习率和batchsize的关系是?
【AI不惑境】学习率和batchsize如何影响模型的性能? - 龙鹏-言有三的文章 - 知乎
目前深度学习模型多采用批量随机梯度下降算法进行优化,随机梯度下降算法的原理如下,
n是批量大小(batchsize),η是学习率(learning rate)。可知道除了梯度本身,这两个因子直接决定了模型的权重更新,从优化本身来看它们是影响模型性能收敛最重要的参数。
学习率直接影响模型的收敛状态,batchsize则影响模型的泛化性能,两者又是分子分母的直接关系,相互也可影响,因此这一次来详述它们对模型性能的影响。
通常我们都需要合适的学习率才能进行学习,要达到一个强的凸函数的最小值,学习率的调整应该满足下面的条件,i代表第i次更新。
第一个式子决定了不管初始状态离最优状态多远,总是可以收敛。第二个式子约束了学习率随着训练进行有效地降低,保证收敛稳定性,各种自适应学习率算法本质上就是不断在调整各个时刻的学习率。
学习率决定了权重迭代的步长,因此是一个非常敏感的参数,它对模型性能的影响体现在两个方面,第一个是初始学习率的大小,第二个是学习率的变换方案。
2.1、初始学习率大小对模型性能的影响
初始的学习率肯定是有一个最优值的,过大则导致模型不收敛,过小则导致模型收敛特别慢或者无法学习,下图展示了不同大小的学习率下模型收敛情况的可能性,图来自于cs231n。
那么在不考虑具体的优化方法的差异的情况下,怎样确定最佳的初始学习率呢?
通常可以采用最简单的搜索法,即从小到大开始训练模型,然后记录损失的变化,通常会记录到这样的曲线。
随着学习率的增加,损失会慢慢变小,而后增加,而最佳的学习率就可以从其中损失最小的区域选择。
有经验的工程人员常常根据自己的经验进行选择,比如0.1,0.01等。
随着学习率的增加,模型也可能会从欠拟合过度到过拟合状态,在大型数据集上的表现尤其明显,笔者之前在Place365上使用DPN92层的模型进行过实验。随着学习率的增强,模型的训练精度增加,直到超过验证集。
2.2、学习率变换策略对模型性能的影响
学习率在模型的训练过程中很少有不变的,通常会有两种方式对学习率进行更改,一种是预设规则学习率变化法,一种是自适应学习率变换方法。
2.2.1 预设规则学习率变化法
常见的策略包括fixed,step,exp,inv,multistep,poly,sigmoid等,集中展示如下:
笔者之前做过一个实验来观察在SGD算法下,各种学习率变更策略对模型性能的影响,具体的结果如下:
模型性能对batchsize虽然没有学习率那么敏感,但是在进一步提升模型性能时,batchsize就会成为一个非常关键的参数。
3.1 大的batchsize减少训练时间,提高稳定性
这是肯定的,同样的epoch数目,大的batchsize需要的batch数目减少了,所以可以减少训练时间,目前已经有多篇公开论文在1小时内训练完ImageNet数据集。另一方面,大的batch size梯度的计算更加稳定,因为模型训练曲线会更加平滑。在微调的时候,大的batch size可能会取得更好的结果。
3.2 大的batchsize导致模型泛化能力下降
在一定范围内,增加batchsize有助于收敛的稳定性,但是随着batchsize的增加,模型的性能会下降,如下图,来自于文[5]。
这是研究者们普遍观测到的规律,虽然可以通过一些技术缓解。这个导致性能下降的batch size在上图就是8000左右。
那么这是为什么呢?
研究[6]表明大的batchsize收敛到sharp minimum,而小的batchsize收敛到flat minimum,后者具有更好的泛化能力。两者的区别就在于变化的趋势,一个快一个慢,如下图,造成这个现象的主要原因是小的batchsize带来的噪声有助于逃离sharp minimum。
Hoffer[7]等人的研究表明,大的batchsize性能下降是因为训练时间不够长,本质上并不少batchsize的问题,在同样的epochs下的参数更新变少了,因此需要更长的迭代次数。
3.3 小结
batchsize在变得很大(超过一个临界点)时,会降低模型的泛化能力。在此临界点之下,模型的性能变换随batch size通常没有学习率敏感。
结论:batchsize变大,学习率也要相应变大;本质是为了梯度的方差保持不变。
通常当我们增加batchsize为原来的N倍时,要保证经过同样的样本后更新的权重相等,按照线性缩放规则,学习率应该增加为原来的N倍[5]。但是如果要保证权重的方差不变,则学习率应该增加为原来的sqrt(N)倍[7],目前这两种策略都被研究过,使用前者的明显居多。
从两种常见的调整策略来看,学习率和batchsize都是同时增加的。学习率是一个非常敏感的因子,不可能太大,否则模型会不收敛。同样batchsize也会影响模型性能,那实际使用中都如何调整这两个参数呢?
研究[8]表明,衰减学习率可以通过增加batchsize来实现类似的效果,这实际上从SGD的权重更新式子就可以看出来两者确实是等价的,文中通过充分的实验验证了这一点。
研究[9]表明,对于一个固定的学习率,存在一个最优的batchsize能够最大化测试精度,这个batchsize和学习率以及训练集的大小正相关。
对此实际上是有两个建议:
- 如果增加了学习率,那么batch size最好也跟着增加,这样收敛更稳定。
- 尽量使用大的学习率,因为很多研究都表明更大的学习率有利于提高泛化能力。如果真的要衰减,可以尝试其他办法,比如增加batch size,学习率对模型的收敛影响真的很大,慎重调整。
内存利用率提高了,大矩阵乘法的并行化效率提高。
跑完一次 epoch(全数据集)所需的迭代次数减少,对于相同数据量的处理速度进一步加快。
在一定范围内,一般来说 Batch_Size 越大,其确定的下降方向越准,引起训练震荡越小。
内存利用率提高了,但是内存容量可能撑不住了。
跑完一次 epoch(全数据集)所需的迭代次数减少,要想达到相同的精度,其所花费的时间大大增加了,从而对参数的修正也就显得更加缓慢。
Batch_Size 增大到一定程度,其确定的下降方向已经基本不再变化。
另外,太大的batch size 容易陷入 sharp minima, 泛化性不好。
epoch和batchsize和iteration的关系?
同样的epoch数目,大的batchsize需要的batch数目减少了,所以可以减少训练时间。
具体:
参考:
stack Overflow
谈谈深度学习中的 Batch_Size