2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)

上一篇文章2-2 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(一)局部最小值与鞍点(Local Minima and Saddle Point)介绍了机器学习时训练神经网络的第一个策略。下面介绍第二个策略:批次与动量。

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第1张图片

目录

Review: Optimization with Batch

Small Batch v.s. Large Batch

Larger batch size does not require longer time to compute gradient.

Smaller batch requires longer time for one epoch

“Noisy” update is better for training

“Noisy” update is better for generalization

Momentum

Small Gradient

Vanilla Gradient Descent

Gradient Descent + Momentum

结束语

Review: Optimization with Batch

上次我们有讲说,实际上在算微分的时候,并不是真的用所有 Data 对 L 作微分,而是分成一个一个的 Batch,有的人是叫Mini Batch (这边叫做 Batch,助教投影片里面是写 Mini Batch)。

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第2张图片

每一个 Batch 的大小,就是B 笔的资料,我们每次在 Update 参数的时候,拿 B 笔资料出来算 Loss,算Gradient,Update 参数;然后拿另外B笔资料,再算Loss,再算Gradient,再 Update 参数,以此类推。所以我们不会拿所有的资料一起去算出 Loss,只会拿一个 Batch 的资料来算 Loss。

所有的 Batch 看过一遍,叫做一个 Epoch。事实上在做这些 Batch 时,会做一件事情叫做 Shuffle(中文意思有洗牌,这里表示将数据集进行打乱操作)。Shuffle 有很多不同的做法,一个常见的做法是:在每一个 Epoch 开始之前,会分一次 Batch,然后每个 Epoch 的 Batch 都不一样。第一个 Epoch,我们分这样子的 Batch;第二个 Epoch,会重新再分一次 Batch;所以哪些资料在同一个 Batch 里面,每一个 Epoch 都不一样的这件事情,叫做 Shuffle。

Small Batch v.s. Large Batch

我们先解释为什么要用 Batch,再说 Batch 对 Training 带来了什么样的帮助。

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第3张图片

如上图,我们来比较左右两边这两个 Case,那假设现在我们有20个训练资料。看两个最极端的状况。

  • 左边 Case 就是没有用 Batch,Batch Size直接跟训练资料一样多,这做 Full Batch,就是没有用 Batch 的意思。Model 必须把20个训练资料都看完,才计算 Loss和Gradient,然后参数才 Update 一次。假设开始的地方在右上边,把所有资料都看完以后,Update 参数就从这里移动到下边。
  • 那右边 Case 就是Batch Size = 1。代表我们只需要拿一笔资料出来算 Loss,就可以 Update 参数,同样假设开始的点在右上边,今天总共20个资料的话,在每一个 Epoch里面参数会 Update 20次,看一笔资料就 Update 一次参数,但是这样算出来的 Loss显然Noisy ,你会发现Update 的方向是曲曲折折的。

​所以我们比较左边跟右边,哪一个比较好呢,他们有什么差别呢

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第4张图片

你会发现左边蓄力的时间比较长,它技能冷却的时间比较长,你要把所有的资料都看过一遍,才能够 Update 一次参数,这一步走的是稳的;而右边的方法,Batch Size = 1,蓄力的时间比较短,每次看到一笔资料,就会更新一次参数。这个例子有20个资料,所有资料看过一遍已经更新了20次的参数,但是它每一步走的是不稳的

看起来左边的方法跟右边的方法各自都有擅长跟不擅长的东西,左边是蓄力时间长,但是威力比较大;右边技能冷却时间短,但是它是比较不准的。但是你会觉得说,左边的方法技能冷却时间长,右边的方法技能冷却时间短,那只是你没有考虑并行运算的问题实际上考虑并行运算的话,左边这个并不一定时间比较长

Larger batch size does not require longer time to compute gradient.

​这边是真正的实验结果,事实上,比较大的 Batch Size,你要算 Loss,再进而算 Gradient,所需要的时间不一定比小的 Batch Size 要花的时间长。

​那以下是做在一个叫做 MNIST 上面,MNIST (Mixed National Institute of Standards and Technology database)美国国家标准与技术研究院收集整理的大型手写数字数据库,机器要做的事情是给它一张图片,然后判断这张图片是0到9的哪一个数字,它要做数字的分类。那 MNIST 是机器学习的hello-world,假设你今天从来没有做过机器学习的任务,一般大家第一个会尝试的机器学习的任务往往就是做 MNIST 做手写数字辨识

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第5张图片

这边我们就是做了一个实验,我们想要知道给机器一个 Batch,它要计算出 Gradient,进而 Update 参数,到底需要花多少的时间

这边列出了 Batch Size 等于1, 等于10,等于100 ,等于1000 所需要耗费的时间

Batch Size 从1到1000,需要耗费的时间几乎是一样的。直觉上我们可能认为有1000笔资料,那需要计算 Loss,然后计算 Gradient花的时间不会是一笔资料的1000倍吗,但是实际上并不是这样的。因为实际上,做运算的时候我们有 GPU,可以做并行运算,这1000笔资料是平行处理的,所以1000笔资料所花的时间,并不是一笔资料的1000倍,当然 GPU 平行运算的能力还是有它的极限,当你的 Batch Size 真的非常非常巨大的时候,GPU 在跑完一个 Batch,计算出 Gradient 所花费的时间,还是会随着 Batch Size 的增加而逐渐增长

所以当你的 Batch Size 增加到 10000乃至增加到60000的时候,你就会发现 GPU 要算完一个 Batch,把这个 Batch 里面的资料都拿出来算 Loss,再进而算 Gradient,所要耗费的时间确实有随着 Batch Size 的增加而逐渐增长,但你会发现这边用的是 V100,所以它挺厉害的,给它60000笔资料,一个 Batch 里面60000笔资料,它在10秒钟之内把 Gradient 就算出来

而 Batch Size 的大小跟时间的关系,其实每年都会做这个实验,我们可以看到这个时代的演进这样,17年的时候用的是那个980啊,2015年的时候用的是那个760啊,然后980要跑60000个 Batch,那要跑好几分钟才跑得完啊,现在只要10秒钟就可以跑得完了,你可以看到时代的演进

Smaller batch requires longer time for one epoch

GPU 虽然有平行运算的能力,但它平行运算能力终究是有个极限,所以当 Batch Size 真的很大的时候,时间还是会增加的。

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第6张图片

实际上,当Batch Size 小的时候,由于并行运算,跑完一个 Epoch花的时间是比大的 Batch Size 还要多的,为什么呢

如上图所示,​假设我们的训练资料只有60000笔,当 Batch Size = 1时,那你要60000个 Update 才能跑完一个 Epoch;如果今天是 Batch Size 等于1000,你要60个 Update 才能跑完一个 Epoch,算 Gradient 的时间根本差不多。那60000次跟60次 Update 比起来,它的时间的差距量就非常可观了。你会发现左边的图(一次Update的时间)跟右边的图(一次Epoch的时间)趋势正好是相反的。假设Batch Size =1,跑完一个 Epoch,你要 Update 60000次参数,它的时间是非常可观的,但是 Batch Size = 1000,你只要跑60次就会跑完一个 Epoch,看完所有资料的时间其实是比较短的,比 Batch Size =1 还要更快。右边的图告诉我们跑完一个Epoch大的 Batch Size 反而是较有效率的,是不是跟你直觉想的不太一样。在没有考虑平行运算的时候,你觉得大的 Batch 比较慢,但实际上,在有考虑平行运算的时候,一个 Epoch 大的 Batch 花的时间反而是比较少的。

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第7张图片

我们如果要比较这个 Batch Size 大小的差异的话,直接用技能时间冷却的长短并不是一个精确的描述,大的 Batch 并没有比较吃亏,甚至还占到优势了。事实上,如果你用 GPU 的话,左边20笔资料 Update 一次的时间,跟右边看一笔资料 Update 一次的时间其实可能一样。大的 Batch技能冷却的时间并没有比较长。那你可能就会说那个大的 Batch 的劣势消失了,看起来大的 Batch 应该比较好?

我们还注意到大Batch的 Update 比较稳定,小Batch的 Gradient 的方向比较 Noisy 。神奇的地方是 Noisy 的 Gradient反而可以帮助 Training,这个也是跟直觉正好相反的。​如果你今天拿不同的 Batch 来训练你的模型,你可能会得到这样子的结果。如下图所示,左边是 MNIST ,右边是 CIFAR-10 ,两者都是影像辨识的问题。

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第8张图片

  • 横轴代表的是 Batch Size,从左到右越来越大。
  • 纵轴代表的是正确率,越往上正确率越高,当然正确率越高越好。

看 Validation Acc 的结果会发现Batch Size 越大,Validation Acc 结果越差,但这个不是 Overfitting,因为 Batch Size 越大,Training 的结果也是越差的。而我们现在用的是同一个模型,照理说,它们可以表示的 Function 就是一模一样的。但是神奇的事情是,大的 Batch Size往往在 Training 的时候会给你带来比较差的结果。

所以同样的 Model,不是 Model Bias 的问题,是 Optimization 的问题。大 Batch Size 的时候,你的 Optimization 可能会有问题,小 Batch Size的Optimization 的结果反而是比较好的,为什么会这样子呢

“Noisy” update is better for training

​为什么小的 Batch Size在 Training Set 上会得到比较好的结果,为什么 Noisy 的 Update,Noisy 的 Gradient 会在 Training 的时候,给我们比较好的结果呢?

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第9张图片

如上图,左边是Full Batch,在 Update 参数时,你用一个Loss Function走到一个 Local Minima,走到一个 Saddle Point,显然就停下来了,Gradient 是零,如果你不特别去看Hession的话,那你用 Gradient Descent 的方法,你就没有办法再更新你的参数了。

右边是 Small Batch ,我们每次挑一个 Batch 出来算它的 Loss,所以等于你每一次 Update 参数时,用的 Loss Function 都有差异——第一个 Batch 时,是用 L1 来算你的 Gradient;第二个 Batch 是用 L2 来算你的 Gradient。假设在L1 算 Gradient 时,Gradient 是零,卡住了,但 L2 的 Function 跟 L1 又不一样,L2 就不一定会卡住,所以 L1 卡住了没关系,换下一个 Batch 来。这样你还是有办法 Training 你的 Model,继续让你的 Loss 变小,所以今天这种 Noisy 的 Update 的方式,结果反而对 Training有帮助。

“Noisy” update is better for generalization

这边还有另外一个更神奇的事情,其实小的 Batch 也对 Testing 有帮助

​假设我们在 Training 的时候,都不管是大的 Batch 还小的 Batch,都 Training 到一样好。刚才的 Case是Training 的时候就已经 Training 不好了,假设你想办法把大的 Batch跟小的 Batch Training 得一样好,结果小的 Batch居然在 Testing 的时候会是比较好的。我们看下面的这个实验结果,引用自On Large-Batch Training For Deep Learning,Generalization Gap And Sharp Minima

,是这篇 Paper 的实验结果。

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第10张图片

如上图,作者训练了六个 Network ,里面有 CNN和 Fully Connected Network 的,做在不同的 Cover 上,代表这个实验是很泛用的。在很多不同的 Case 都观察到一样的结果,那它有小的 Batch size = 256,大的 Batch size = Data Set 乘 0.1 = 6000。然后想办法,大的 Batch跟小的 Batch都 Train 到差不多的 Training Accuracy。但是Testing 时小的 Batch 居然比大的 Batch 好,这个才是 Over Fitting 那为什么会有这样子的现象呢?在这篇文章里面也给出了一个解释。

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第11张图片

假设实线是 Training Loss,那可能有很多个 Local Minima,那这些 Local Minima 的 Loss 都很低,它们 Loss 可能都趋近于 0,但是这个 Local Minima,还是有好 Minima 跟坏 Minima 之分。如果一个 Local Minima 它在一个峡谷里面,它是坏的 Minima,然后它在一个平原上,它是好的 Minima,为什么会有这样的差异呢

  • 因为假设现在 Training 跟 Testing 中间,有一个 Mismatch,Training Loss 跟 Testing Loss,它们的 Function 不一样,有可能本来 Training 跟 Testing 的 Distribution就不一样。
  • 那也有可能是因为Training 跟 Testing,Sample 到的 Data 不一样,那所以它们算出来的 Loss当然是有一点差距。

​假设Training 跟 Testing的差距就是把 Training 的 Loss Function 往右平移一点,这时候你会发现,对左边这个在一个盆地里面的 Minima 来说,它的在 Training 跟 Testing 上面的结果,不会差太多,只差了一点点,但是对右边这个在峡谷里面的 Minima 来说,一差就可以天差地远。它在这个 Training Set 上的 Loss 很低,但是因为 Training 跟 Testing 之间的不一样,所以 Testing 时 Error Surface 一变,它算出来的 Loss 就变得很大,而很多人相信这个大的 Batch Size,会让我们倾向于走到峡谷里面,而小的 Batch Size,倾向于让我们走到盆地里面

直觉上的想法是小的 Batch有很多的 Loss,它每次 Update 的方向都不太一样,所以如果今天这个峡谷非常地窄,它可能一个不小心就跳出去了,因为每次 Update 的方向都不太一样,它的 Update 的方向也就随机性,所以一个很小的峡谷,没有办法困住小的 Batch,它可能动一下就跳出去。之后停下来如果有一个非常宽的盆地,它才会停下来,那对于大的 Batch Size,反正它就是顺着规定 Update,然后它就很有可能,走到一个比较小的峡谷里面。

但这只是一个解释,那也不是每个人都相信,那其实还是一个尚待研究的问题

​那下面比较了大的 Batch 跟小的 Batch

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第12张图片

(1)​在有平行运算的情况下,小的 Batch 跟大的 Batch,其实运算的时间并没有太大的差距,除非你的大的 Batch 那个大是真的非常大,才会显示出差距来。但是一个 Epoch 需要的时间,小的 Batch 比较长,大的 Batch 反而是比较快的,所以从一个 Epoch 需要的时间来看,大的 Batch 其实是占到优势的。(2)而小 Batch的 Update 的方向比较 Noisy,大Batch 的 Update 的方向比较稳定,但是 Noisy 的 Update 的方向,反而在 Optimization 的时候会占到优势,而且在 Testing 的时候也会占到优势,所以大的 Batch 跟小的 Batch,它们各自有它们擅长的地方。因此 Batch Size变成另外一个你需要去调整的 Hyperparameter

​那我们能不能够鱼与熊掌兼得呢,我们能不能够截取大的 Batch 跟小的 Batch 的优点,我们用大的 Batch Size 来做训练,用平行运算的能力来增加训练的效率,但是训练出来的结果同时又得到好的结果呢,又得到好的训练结果呢?请看下图:

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第13张图片

这是有可能的,有很多文章都在探讨这个问题。今天我们不细讲,把Reference 列在这边给大家参考,那你发现这些 Paper,往往它想要做的事情是什么,76分钟训练 BERT,15分钟训练 ResNet?!多大的数据集,一分钟 Train Imagenet 等等。这为什么他们可以做到那么快,就是因为他们 Batch Size 是真的开很大,比如说在第一篇 Paper 的Batch Size 里面有三万个 Example ,真的可以算很快,你可以在很短的时间内看到大量的资料,那他们需要有一些特别的方法来解决,Batch Size 可能会带来的劣势。

Momentum

Momentum也是另外一个有可能可以对抗 Saddle Point或 Local Minima 的技术,Momentum 的运作是这个样子的。

Small Gradient

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第14张图片

如上图,假设 Error Surface 就是真正的斜坡,而我们的参数是一个球,你把球从斜坡上滚下来,如果今天是 Gradient Descent,它走到 Local Minima 就停住了,走到 Saddle Point 就停住了。

但是在物理的世界里,一个球如果从高处滚下来,从高处滚下来就算滚到 Saddle Point,因为惯性的关系它还是会继续往右走,甚至它走到一个 Local Minima,如果今天它的动量够大的话,它还是会继续往右走,甚至翻过这个小坡然后继续往右走。​所以它并不会被 Saddle Point或 Local Minima卡住。我们有没有办法运用这样子的概念到 Gradient Descent 里面呢?这个就是我们要讲的Momentum 这个技术。

Vanilla Gradient Descent

那我们先很快的复习一下,原来的 Gradient Descent 长得是什么样子,Vanilla (一般的)的 Gradient Descent长什么样子呢?

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第15张图片

一般的 Gradient Descent 说,我们有一个初始参数 θ^0,我们计算Gradient,然后往 Gradient 的反方向去 Update 参数 θ^1 = θ^0 - ηg^0 。到达了新的参数以后,同样再计算一次 Gradient,再往 Gradient 的反方向,再 Update 一次参数,这个 Process 就一直这样子下去。

Gradient Descent + Momentum

现在考虑Momentum。每一次在移动参数时,我们不是只往 Gradient 的反方向来移动参数,我们是 Gradient 的反方向加上前一步移动的方向,两者加起来的结果,去调整去到我们的参数。

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第16张图片

​如上图所示,那具体说起来是这样,先找初始的参数 θ^0 ,假设前一步的参数的 Update 量 m^0 = 0 ,接着计算 Gradient 的方向g^0。​然后接下来你要决定下一步要怎么走,它是 Gradient 的方向加上前一步的方向,现在是刚初始的时候所以前一步是 0,所以 Update 的方向跟原来的 Gradient Descent 是一样的, m^1 = λm^0- ηg^0θ^1 = θ^0 + m^1。但从第二步开始,加上 Momentum 以后就不太一样了。我们计算 g^1,然后接下来我们 Update 的方向,不是 g^1的反方向,而是根据上一次 Update 方向,写成m^2 = λm^1-ηg^1,当做我们新的 Update 的方向。

如上图左边图示,g1 告诉我们要往红色反方向这边走,但是我们也考虑 Momentum,也会看前一次 Update 的方向,如果前一次要往m^1蓝色及蓝色虚线这个方向走,把两者相加起来,也就是往蓝色m^2这一个方向走,所以我们就移动了 m2,走到 θ2 这个地方。接下来就反覆进行同样的过程。

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第17张图片

每一步的移动,我们都用 m 来表示,其实可以写成之前所有算出来的Gradient 的 Weighted Sum,表达式如下:

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第18张图片

这里λ η (Learning Rate )是我们要调的参数。观察这个式子,(1)一个解读是 Momentum 是Gradient 的负反方向加上前一次移动的方向,(2)那但另外一个解读方式是当加上 Momentum 时,我们 Update 的方向不是只考虑现在的 Gradient,而是考虑过去所有 Gradient 的总和。

有一个更简单的例子,希望帮助你了解 Momentum。

2-3 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(二)批次与动量(Batch and Momentum)_第19张图片

注释:Gradient 的反方向用红色实线箭头,前一步的方向用蓝色虚线箭头来表示。

那我们从红点开始 Update 参数,根据 Gradient 的方向应该往右 Update 参数,那现在没有前一次 Update 的方向,所以我们就完全按照 Gradient 给我们的指示往右移动参数,那我们的参数就往右移动了一点到红点②。此时Gradient 变得很小,告诉我们往右移动,但前一步是往右移动的,两者方向加起来,得到往右走的方向,那再往右走,走到红点③,这是一个 Local Minima,一般 Gradient Descent 就无法向前走了,因为已经没有这个 Gradient 的方向,那走到 Saddle Point 也一样,没有 Gradient 的方向已经无法向前走了。

但没有关系,如果有 Momentum 的话,你还是有办法继续走下去,因为 Momentum 不是只看 Gradient,Gradient 就算是 0,你还有前一步的方向,前一步的方向告诉我们向右走,我们就继续向右走,甚至你走到红点④,Gradient 告诉你应该要往左走了,但是假设你前一步的影响力,比 Gradient 要大的话,你还是有可能继续往右走,甚至翻过一个小丘,搞不好就可以走到更好 Local Minima,这个就是 Momentum 有可能带来的好处

结束语

  • 临界点斜率为零。(Critical points have zero gradients.)
  • 临界点可以是鞍点,也可以是局部极小点。(Critical points can be either saddle points or local minima.)
  • 鞍点或者局部极小点可以由Hessian矩阵确定。(Saddle points or local minima can be determined by the Hessian matrix.)
  • 局部极小值可能很少见。(Local minima may be rare.)
  • 沿着Hessian矩阵的特征向量方向可以避开鞍点。(It is possible to escape saddle points along the direction of eigenvectors of the Hessian matrix.)
  • 更小的批量大小和动量有助于逃离临界点。(Smaller batch size and momentum help escape critical points.)

​那以上就是今天想要跟大家说的内容。

说明:记录学习笔记,如果错误欢迎指正!写文章不易,转载请联系我。

你可能感兴趣的:(李宏毅机器学习笔记,AI,笔记,神经网络,人工智能,深度学习,机器学习,python)