李宏毅机器学习笔记:【5.Batch和Momentum的训练技巧】
1.Batch
每次训练一个batch计算一次Loss
所有的Batch看过一遍叫做一个epoch
1.1shuffle
我们将所有资料分成一个一个batch时候会先shuffle,shuffle的不同做法,一个比较常见的做法是在每一个epoch开始之前会分一次batch,然后每个epoch的batch都不一样(第二个epoch会重新分一次batch),哪些资料在同一个batch里面,每个epoch都不一样,这件事情叫shuffle。
1.2为什么要用batch?
假设我们现在有20笔训练资料,左边的没有用batch,或者说batchsize设置的和训练资料一样多,这种状况叫做Full batch;右边的batch size=1
左边的我们必须把20笔训练资料都看完,才能够计算Loss和梯度,我们看完后参数才会更新一次。
右边的Batch size=1,我们只用拿一笔资料算loss,就能更新我们的参数,如果有20笔资料的话,我们的参数更新20 次
左边的蓄力时间长,右边蓄力短,左边的一步走的比较稳,右边的不稳。如果考虑平行运算,左边的不一定时间长。
事实上,比较大的batchsize,算loss,进而算梯度所需要的时间不一定比小的batchsize花费的时间长,实验表明,实际运算时候由于平行运算batchsize=10和=1000花费时间差不多。但是batchsize非常庞大时候,计算时间随着batchsize的增加还是会增长。
因为有平行计算的能力,因此跑完一个小的batchsize花的时间比大的batchsize时间多。
怎么说呢?如果假设训练资料6万笔,batchsize设置为1则一个epoch更新60000次参数;batchsize设置为1000,一个epoch更新60次参数;假设batchsize=1和batchsize=1000要计算梯度的时间差不多,那么60000次和60次updates比起来时间差距就可观了。左边的图为拿一个batch出来,计算一个梯度,更新一次参数所需要的时间。右边的是跑完一个完整的epoch需要的时间,从右图可看出,大的batchsize花费时间更短。
如果拿不同的batchsize训练模型可能得到下面结果:
小的batchsize结果更好。
为什么小的batchsize结果更好?
假设你是full batch,沿着损失函数更新参数,可能走到一个局部最小点或者马鞍点就停下了,梯度就是0,就没有办法更新参数;如果是Small Batch,我们每次挑选一个batch出来计算它的loss,每次更新参数时候,用到的损失函数都是略有差异的,选到第一个batch时候用L1计算梯度,选到第二个batch时候可能用L2计算梯度,你用L1计算梯度时候可能遇到0,梯度卡住了,但是用L2时候就不一定被卡住,因为L1和L2不一样。所以小的batchsize对训练更有帮助。
小的batch也对testing data有帮助。实验结果如下:
小的batch的测试精度低—>overfitting
为什么会有这样的现象?文章给出了解释。
假设下面是Training Loss,在这个上面有很多Local minima,有很多可能比较低,但是也有好minima和坏minima之分,我们认为如果一个Local minima在峡谷就是一个坏的Minima,如果在平原上,就是一个好的minima。Training Loss和Testing Loss有点不一样,可能因为其子集不一样,算出来有点差距,假设他们的差距是把Testing Loss往右移一点,你会发现,在左边的盆地上的minima,它的training 和testing的loss不会差太多;但是右边的就差距比较多。很多人倾向说大的batch size会让我们走到峡谷里面,而小的batchsize倾向走到盆地,小的每次更新的不一样,可能会跳出峡谷,小的峡谷没有办法困住小的batch,有一个大的盆地才会停下来;大的batchsize可能顺着梯度更新,走到一个小的峡谷里面。(这只是一个解释)
对大batch和小batch的比较:
2.Momentum
2.1概念
假设Error surface(误差曲面)是一个真正的斜坡,我们的参数是一个球,梯度走到局部最小点或者马鞍点就停住了。但是在物理世界,由于惯性,还是会继续走,如果动量够大,走到local minima还是会继续走。我们怎么运用这个概念到gradient descent里面,这就是我们讲的momentum技术。
2.2Gradient Descent
我们有个初始的参数
θ
0
\theta_0
θ0,计算gradient,然后往gradient的反方向去更新参数,到了新的位置
θ
1
\theta_1
θ1,再计算gradient,然后往gradient的反方向去更新参数…
2.3Momentum
如果加上Momentum,每次我们在移动参数时候,不是只往gradient的反方向来移动参数,而是gradient的反方向+前一步移动的方向 以此来移动参数。
具体来说,找一个初始参数
θ
0
\theta_0
θ0,前一步的变化量设置为0,在
θ
0
\theta_0
θ0这里计算
g
0
g_0
g0,下一步的方向就是gradient的反方向+前一步移动的方向(这里初始先是0)记作
m
1
m^1
m1;从第二步开始计算
g
1
g_1
g1,下一步的方向是
m
1
m^1
m1-
g
1
g_1
g1
所以我们会考虑之前移动的方向来进行调整,而不仅是gradient的反方向
另一个解读方向我们将其带入可以发现,现在的gradient考虑的是过去所有gradient的总和。
举例了解Momentum
当我们走到Local minima时候,gradient=0,我们还有前一步的方向,前一步告诉我们向右走,我们就继续走;当在小邱时候前一步的影响力更大的话,我们会翻过小丘,继续走,可能会找到更小的Local minima