batch_size、epoch、iteration是深度学习中常见的几个超参数:
(1)batch_size:每批数据量的大小。DL通常用SGD的优化算法进行训练,也就是一次(1 个iteration)一起训练batchsize个样本,计算它们的平均损失函数值,来更新参数。
(2)iteration:1个iteration即迭代一次,也就是用batchsize个样本训练一次。
(3)epoch:1个epoch指用训练集中的全部样本训练一次,此时相当于batchsize 等于训练集的样本数。
最初训练DNN采用一次对全体训练集中的样本进行训练(即使用1个epoch),并计算一次损失函数值,来更新一次权值。当时数据集较小,该方法尚可。后来随着数据集迅速增大,导致这种方法一次开销大进而占用内存过大,速度过慢。
后来产生了一次只训练一个样本的方法(batchsize=1),称作在线学习。该方法根据每一个样本的情况更新一次权值,开销小速度快,但收到单个样本的巨大随机性,全局来看优化性能较差,收敛速度很慢,产生局部震荡,有限迭代次数内很可能无法收敛。
目前常用随机梯度下降SGD来训练,相当于上述两个“极端”方法的折中:将训练集分成多个mini_batch(即常说的batch),一次迭代训练一个minibatch(即batchsize个样本),根据该batch数据的loss更新权值。这相比于全数据集训练,相当于是在寻找最优时人为增加了一些随机噪声,来修正由局部数据得到的梯度,尽量避免因batchsize过大陷入局部最优。
这种方法存在两对矛盾。由于一次只分析的一小部分数据,因此整体优化效果与batchsize有关:
batchsize越小,一个batch中的随机性越大,越不易收敛。然而batchsize越小,速度越快,权值更新越频繁;且具有随机性,对于非凸损失函数来讲,更便于寻找全局最优。从这个角度看,收敛更快,更容易达到全局最优。
batchsize越大
越能够表征全体数据的特征,其确定的梯度下降方向越准确,(因此收敛越快),且迭代次数少,总体速度更快。然而大的batchsize相对来讲缺乏随机性,容易使梯度始终向单一方向下降,陷入局部最优;而且当batchsize增大到一定程度,再增大batchsize,一次batch产生的权值更新(即梯度下降方向)基本不变。因此理论上存在一个最合适的batchsize值,使得训练能够收敛最快或者收敛效果最好(全局最优点)。
1.batch
深度学习的优化算法,说白了就是梯度下降。每次的参数更新有两种方式。
第一种,遍历全部数据集算一次损失函数,然后算函数对各个参数的梯度,更新梯度。这种方法每更新一次参数都要把数据集里的所有样本都看一遍,计算量开销大,计算速度慢,不支持在线学习,这称为Batch gradient descent,批梯度下降。
另一种,每看一个数据就算一下损失函数,然后求梯度更新参数,这个称为随机梯度下降,stochastic gradient descent。这个方法速度比较快,但是收敛性能不太好,可能在最优点附近晃来晃去,hit不到最优点。两次参数的更新也有可能互相抵消掉,造成目标函数震荡的比较剧烈。
为了克服两种方法的缺点,现在一般采用的是一种折中手段,mini-batch gradient decent,小批的梯度下降,这种方法把数据分为若干个批,按批来更新参数,这样,一个批中的一组数据共同决定了本次梯度的方向,下降起来就不容易跑偏,减少了随机性。另一方面因为批的样本数与整个数据集相比小了很多,计算量也不是很大。
基本上现在的梯度下降都是基于mini-batch的,所以深度学习框架的函数中经常会出现batch_size,就是指这个。
批量大小将决定我们一次训练的样本数目
全批次(蓝色)
如果数据集比较小,我们就采用全数据集。全数据集确定的方向能够更好的代表样本总体,从而更准确的朝向极值所在的方向。
注:对于大的数据集,我们不能使用全批次,因为会得到更差的结果。
迷你批次(绿色)
选择一个适中的Batch_Size值。就是说我们选定一个batch的大小后,将会以batch的大小将数据输入深度学习的网络中,然后计算这个batch的所有样本的平均损失,即代价函数是所有样本的平均。
随机(Batch_Size等于1的情况)(红色)
每次修正方向以各自样本的梯度方向修正,横冲直撞各自为政,难以达到收敛。
适当的增加Batch_Size的优点:
1.通过并行化提高内存利用率。
2.单次epoch的迭代次数减少,提高运行速度。(单次epoch=(全部训练样本/batchsize)/iteration=1)
3.适当的增加Batch_Size,梯度下降方向准确度增加,训练震动的幅度减小。(看上图便可知晓)
经验总结:
相对于正常数据集,如果Batch_Size过小,训练数据就会非常难收敛,从而导致underfitting(欠拟合)。
增大Batch_Size,相对处理速度加快。
增大Batch_Size,所需内存容量增加(epoch的次数需要增加以达到最好的结果)
这里我们发现上面两个矛盾的问题,因为当epoch增加以后同样也会导致耗时增加从而速度下降。因此我们需要寻找最好的Batch_Size。
再次重申:Batch_Size的正确选择是为了在内存效率和内存容量之间寻找最佳平衡。