2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)

上一篇文章2-5 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(四)分类(Classification)介绍了机器学习训练神经网络时的第四个策略:分类时损失函数的选择。接下来本篇介绍批量标准化(Batch Normalization )这个技术。

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第1张图片

目录

Changing Landscape

Feature Normalization

Considering Deep Learning

Testing

Comparison

Internal Covariate Shift?

To learn more ……

Changing Landscape

之前的内容讲过说我们能不能够直接改error surface 的 landscape,当 error surface 如果很崎岖的时候,它比较难 train时,那我们能不能够直接把山铲平,让它变得比较好 train 呢

Batch Normalization 就是其中一个把山铲平的想法

我们一开始就讲不要小看 optimization 这个问题,有时候就算你的 error surface 是 convex的,它就是一个碗的形状,都不见得很好训练。假设你的两个参数对 Loss 的斜率差别非常大,在w1这个方向上面的斜率变化很小,在w2这个方向上面斜率变化很大。

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第2张图片

如果是固定的 learning rate,你可能很难得到好的结果,所以我们才说你需要adaptive 的 learning rate、 Adam 等等比较进阶的 optimization 的方法,才能够得到好的结果。

现在我们要从另外一个方向想:直接把难做的 error surface 改掉,看能不能够改得好做一点。在做这件事之前,也许我们第一个要问的问题是w1跟w2的斜率差很多的这种状况,到底是从什么地方来的?

假设我现在有一个非常非常非常简单的 model,它的输入是x1跟x2,对应的参数就是w1跟w2,它是一个 linear model,没有 activation function。

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第3张图片

通过y=w1x1+w2x2+b计算y,然后计算 y 跟y hat之间的差距e,把所有 training data的e加起来就是你的 Loss,然后去 minimize 你的 Loss。那什么样的状况我们会产生像上面这样子比较不好 train 的 error surface 呢?

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第4张图片

当我们对w1有一个小小的改变,比如说加上 delta w1的时候,那 L 也会有一个改变。那什么时候w1 的改变会对 L 的影响很小呢,即它在 error surface 上的斜率会很小呢(1)一个可能性是当你的 input  x1很小的时候,假设w1的值在不同的 training example 里面的值都很小,那因为x1是直接乘上w1,那它对 y 的影响也是小的,对 e 的影响也是小的,它对 L 的影响就会是小的。(2)反之,如果x2的值都很大,当你的w2有一个小小的变化的时候,它乘上了x2, 那 y 的变化就很大,那 e 的变化就很大,那 L 的变化就会很大,就会导致我们在 w 这个方向上变化的时候,把 w 改变一点点,error surface 就会有很大的变化。

所以既然在这个 linear model 里面,当我们 input 的 feature,每一个 dimension 的值,它的 scale 差距很大的时候,我们就可能产生像这样子的 error surface,就可能产生不同方向,斜率非常不同,坡度非常不同的 error surface。所以怎么办呢?我们有没有可能给feature 里面不同的 dimension,让它有同样的数值的范围

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第5张图片

如果我们可以给不同的 dimension同样的数值范围的话,那我们可能就可以制造比较好的 error surface,让 training 变得比较容易一点。其实有很多不同的方法,这些不同的方法,往往就合起来统称为Feature Normalization

Feature Normalization

以下所讲的方法只是Feature Normalization 的一种可能性,它并不是 Feature Normalization 的全部。假设x1到xR是我们所有的训练资料的 feature vector。

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第6张图片

我们把所有训练资料的 feature vector 统统都集合起来。那我们把不同笔资料即不同 feature vector同一个 dimension 里面的数值,把它取出来(上图的绿框),然后去计算某一个 dimension 的 mean(均值) ustandard deviation(标准差) sigma_i

那接下来可以做normalization(标准化),也可以叫 standardization,不过我们这统称 normalization。我们把某一个数值x减掉这一个 dimension 算出来的 mean,再除以standard deviation,得到新的数值tilde{x};然后再把新的数值把它代回去。以下都用这个 tilde来代表有被 normalize 后的数值那做完 normalize 以后有什么好处呢

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第7张图片

做完 normalize 以后,这个 dimension 上的数值就会平均是 0, variance是 1,所以这一排数值的分布就都会在 0 上下。对每一个 dimension都做一样的 normalization,就会发现所有 feature 不同 dimension 的数值都在 0 上下,那你可能就可以制造一个比较好的 error surface

所以像这样子 Feature Normalization 的方式,往往对你的 training 有帮助,它可以让你在做 gradient descent 时,Loss 收敛更快一点可以让你的训练更顺利一点。以上是 Feature Normalization的介绍。

Considering Deep Learning

tilde{x}代表 normalize 的 feature,把它代入 deep network 里面,去做接下来的计算和训练。

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第8张图片

通过第一个 layer 得到 z1,那你有可能通过 activation function,不管是选 Sigmoid 或者 ReLU 都可以,然后再得到a1,然后再通过下一层等等,那就看你有几层 network 就做多少的运算。每一个 x 都做类似的事情。但是如果我们进一步来想,对w2来说,这边的a1 a2 a3,这边的z1 z2 z3,其实也是另外一种 input如果这边 z1 的数值的分布仍然有很大的差异的话,那我们要 train 第二层的参数,会不会也有困难呢对w2来说,这边的 a 或这边的 z 其实也是一种 feature,我们应该要对这些 feature 也做 normalization

那如果你选择的是 Sigmoid激活函数,那可能比较推荐对 z 做 Feature Normalization,因为Sigmoid 是一个 s 的形状,那它在 0 附近斜率比较大,所以对 z 做 Feature Normalization,把所有的值都挪到 0 附近,那你到时候算 gradient 的时候,算出来的值会比较大。那不过因为你不一定用 sigmoid ,你也不一定要把 Feature Normalization放在 z 这个地方,如果是选别的,也许你选 a 也会有好的结果也说不定总体而言这个 normalization放在 activation function 之前或之后都可以的在实作上可能没有太大的差别,那我们这边就是对 z 做一下 Feature Normalization。

那怎么对 z 做 Feature Normalization 呢?

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第9张图片

那你就把 z想成是另外一种 feature ,我们这边有z1 z2 z3,我们算一下mean,这边的μ是一个 vector。同样我们也算一个 standard deviation

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第10张图片

接下来就把这边的每一个 z 都进行 Normalization。那这边的μ跟sigma都是矢量,所以除的意思是element wise 的相除,就是把这个两个矢量对应的 element 的值相除。做 Feature Normalization之后得到 z 的 tilde。接下来就看你爱做什么就做什么。通过 activation function得到其他 vector,然后再通过其他 layer 等,这样就可以了。所以这边我们做 Feature Normalization 后,改变了z的值,然后会改变这边 a 的值。

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第11张图片

之前我们每一个tilde{x}1 tilde{x}2 tilde{x}3是独立分开处理的,但是我们在做 Feature Normalization 以后,这三个 example变得彼此关联了。我们这边 z1 只要有改变,接下来 z2 a2 z3 a3也都会跟着改变,所以要把这一整个 process,把这堆 feature 算出 μ 跟 sigma当做是 network 的一部分我们现在有一个比较大的 network。之前的 network只输入一个 input,得到一个 output,现在有一个比较大的 network,它是输入一堆 input,用这堆 input 在这个 network 里面,要算出μ 和 sigma,然后接下来产生一堆 output。这个地方比较抽象。

那这边就会有一个问题了,因为你的训练资料里面的 data 非常多,现在一个 data set,benchmark corpus 都上百万笔资料, GPU 的 memory根本没有办法,把整个 data set 的 data 都 load 进去。在实践中,你不会让这一个 network 考虑整个 training data 里面的所有 example,你只会考虑一个 batch 里面的 example。举例来说,你 batch size 设 64,那这个巨大的 network就是把 64 笔 data 读进去,算这 64 笔 data 的μ和sigma ,对这 64 笔 data 做 normalization。因为我们在实践时只对一个 batch 里面的 data 做 normalization,所以这招叫做 Batch Normalization

这个 Batch Normalization显然有一个问题,你一定要有一个够大的 batch才算得出μ和sigma。假设你 batch size 设 1,那你就没有必要计算。所以Batch Normalization适用于 batch size 比较大的时候因为 batch size 比较大的话,那里面的 data就足以表示整个 corpus 的分布,那你就可以把本来要对整个 corpus做 Feature Normalization ,改成只在一个 batch做 Feature Normalization作为 approximation

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第12张图片

在做 Batch Normalization 时,往往还会有上图所示的设计。当算出tilde{z}后,接下来你会再乘上另外一个矢量γ,再加上β这个矢量,得到hat{z}。而你要把γ和β想成是 network 的参数,这是另外再被learn出来的。

那为什么要加上γ和β呢?有人可能会觉得说,如果我们做 normalization 以后,那tilde{z}的平均就一定是 0,那也许会给那 network 一些限制,这个限制可能带来负面影响,所以我们把γ和β加回去,然后现在 hidden layer 的 output平均不是 0 的话,就让 network 去learn这个 γ和β,来调整hat{z}的分布。

但讲到这边又会有人问,之前不是说做 Batch Normalization 就是为了要让每一个不同的 dimension的 range 都是一样吗,现在如果通过 γ和β调整分布,这样不会不同 dimension 的分布的 range 又都不一样了吗?有可能,但是你实际上在训练的时候,γ跟β的初始值会提前设定,把γ的初始值都设为 1,β的初始值都设为0。所以 network 在一开始训练时,每一个 dimension 的分布是比较接近的,也许训练到后来,已经训练够长的一段时间,已经找到一个比较好的 error surface,走到一个比较好的地方以后,那再把γ 跟 β慢慢地加进去总之Batch Normalization往往对训练是有帮助的

Testing

以上说的都是 training 的部分,接下来讲testing(有时候又叫 inference )。Batch Normalization 在 testing 的时候会有什么样的问题呢

在 testing 的时候,如果今天你是在做作业,我们一次会把所有的 testing 的资料给你,所以你确实也可以在 testing 的资料上制造一个一个 batch。但是假设有系统上线,有一个真正的线上的 application,比如说你的 batch size 设 64,你一定要等 64 笔资料都进来才一次做运算吗,这显然是不行的。

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第13张图片

但是在做 Batch Normalization 时,一个 normalization 后的 feature 进来,然后你有一个 z,你的 要减掉μ,除以sigma,这是用一个 batch 的资料算出来的。但在 testing 时根本就没有 batch,那我们要怎么算这个呢?

真正的实作上的解法是这个样子的,Batch Normalization 在 testing 的时候,你并不需要做什么特别的处理,PyTorch 帮你处理好了。在 training 时,如果你有做 Batch Normalization 的话,在 training 的时候,你每一个 batch 计算出来的μ 跟 sigma,都会拿出来算移动平均(moving average)

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第14张图片

如上图所示,你第一次取一个 batch 出来的时候,你就会算一个μ1,取第二个 batch 出来的时候,你就算个μ2,... ,一直到取第 t 个 batch 出来的时候,你就算一个μt。接下来你会算一个 moving average,你会把你现在算出来的μ的一个平均值,叫做μ bar,乘上某一个 factor p(是一个常数),这也是一个hyper parameter,需要自己调。

在 PyTorch 里面,p设为 0.1,然后加上 (1 - p)μt ,然后来更新μ的平均值,然后最后在 testing 的时候,你就不用算 batch 里面的 μ 跟 sigma。因为 testing 的时候,在真正 application 上没有 batch 这个东西,你就直接拿bar μbar sigma,也就是μ 跟 sigma在训练时得到的 moving average,这个就是 Batch Normalization在 testing 的时候的运作方式

Comparison

那下图是从 Batch Normalization原始的文件上面截出来的一个实验结果,在原始的文件上还讲了很多其他的东西。举例来说,我们今天还没有讲的是,Batch Normalization 用在 CNN 上要怎么用呢?那你自己去读一下原始的文献也可以得到答案。

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第15张图片

如上图所示,是原始文献上面截出来的一个数据。横轴代表的是训练的过程,纵轴代表的是 validation set 上面的 accuracy。

  • 黑色虚线[Inception]没有做 Batch Normalization 的结果,它用的是 inception 的 network(inception是以 CNN 为基础的 network 架构)。如果做 Batch Normalization,你会得到红色虚线[BN-Baseline]它训练的速度显然比黑色的虚线还要快很多,虽然最后收敛的结果,你只要给它足够的训练的时间,可能都跑到差不多的 accuracy,但是红色这一条虚线可以在比较短的时间内得到一样的 accuracy这个蓝色的菱形代表说这几个点的那个 accuracy 是一样的
  • 粉红色线[BN-x5-Sigmoid]是 sigmoid function,其实一般都会选择 ReLu,而不是用 sigmoid function,因为 sigmoid function的 training 是比较困难的,但是这边想要强调的点是就算是 sigmoid 比较难搞的,加 Batch Normalization还是 train 的起来。那这边没有 sigmoid,没有做 Batch Normalization 的结果,因为在这个实验上,作者有说sigmoid 不加 Batch Normalization,根本连 train 都 train 不起来
  • 蓝色实线[BN-x30]蓝色虚线[BN-x5],是把 learning rate 设比较大一点,乘 5( learning rate 变原来的 5 倍),然后乘 30( learning rate 变原来的 30 倍),那因为如果你做 Batch Normalization 的话,那你的 error surface会比较平滑,比较容易训练,所以你可以把比较不崎岖的 learning rate 设大一点有个不好解释的奇怪的地方,就是不知道为什么learning rate 设 30 倍的时候比 5 倍差,那作者也没有解释。做 deep learning 有时候会产生这种怪怪的不知道怎么解释的现象。不过作者就是照实,把他做出来的实验结果呈现在这个图上面。

Internal Covariate Shift?

接下来的问题就是Batch Normalization为什么会有帮助呢?在原始Batch Normalization的 paper 里面,提出来一个概念internal covariate shift(训练集和预测集样本分布不一致的问题就叫做covariate shift现象) ,这个词汇是原来就有的,internal covariate shift这个词李宏毅老师认为是Batch Normalization 的作者自己发明的。作者认为在 train network 的时候会有以下这个问题,这个问题是这样的:

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第16张图片

如上图所示,network 有很多层。

  • x 通过第一层以后 得到 a
  • a 通过第二层以后 得到 b
  • 计算出 gradient 以后,把 A update 成 A′,把 B 这一层的参数 update 成 B′

但是作者认为说,我们在计算 B update 到 B′ 的 gradient 的时候,这个时候前一层的参数是 A ,或者是前一层的 output 是 a 。那当前一层从 A 变成 A′ 的时候,它的 output 就从a 变成a′。但是我们计算这个 gradient 的时候,我们是根据这个 a 算出来的啊,所以这个 update 的方向,也许它适合用在 a 上但不适合用在 a′ 上面。那如果说 Batch Normalization 的话,因为我们每次都有做 normalization,我们就会让 a 跟 a′ 的分布比较接近,也许这样就会对训练有帮助。

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第17张图片有一篇 paper 叫做How Does Batch Normalization,Help Optimization,然后它就打脸了internal covariate shift 的这一个观点。在这篇 paper 里面,他从各式各样的面向来告诉你internal covariate shift首先它不一定是 training network 的时候的一个问题然后 Batch Normalization会比较好可能不见得是因为它解决了 internal covariate shift

那在这篇 paper 里面做了很多很多的实验,比如说他比较了训练的时候,这个 a 的分布的变化,发现不管有没有做 Batch Normalization,它的变化都不大。然后他又说,就算是变化很大对 training 也没有太大的伤害,不管你是根据 a 算出来的 gradient,还是根据 a′ 算出来的 gradient,方向居然都差不多。所以他告诉我们internal covariate shift可能不是 training network 的时候,最主要的问题它可能也不是,Batch Normalization 会好的一个的关键,那有关更多的实验,你就自己参见这篇文章。

为什么 Batch Normalization 会比较好呢,那在这篇 How Does Batch Normalization,Help Optimization 这篇论文里面,他从实验上和理论上,至少支持了 Batch Normalization,可以改变 error surface,让 error surface 比较不崎岖这个观点。

2-6 李宏毅2021春季机器学习教程-类神经网络训练不起来怎么办(五)批量标准化(Batch Normalization)_第18张图片

所以这个观点是有理论的支持,也有实验的佐证的。那在这篇文章里面呢,作者还讲了一个非常有趣的话,他觉得,这个 Batch Normalization 的 positive impact。因为他说,如果我们要让 network,这个 error surface 变得比较不崎岖,其实不见得要做 Batch Normalization,感觉有很多其他的方法,都可以让 error surface 变得不崎岖。那他就试了一些其他的方法,发现跟 Batch Normalization performance 也差不多,甚至还稍微好一点,所以他就讲了下面这句感叹。

他觉得说,positive impact of batchnorm on training可能是 somewhat serendipitous(可以翻译成偶然的),但偶然并没有完全表达这个词汇的意思,这个词汇的意思是说,你发现了一个什么意料之外的东西。举例来说,盘尼西林就是意料之外的发现,大家知道盘尼西林的由来就是,有一个人叫做弗莱明,然后他本来想要培养一些葡萄球菌,然后但是因为他实验没有做好,他的那个葡萄球菌被感染了,有一些霉菌掉到他的培养皿里面,然后发现那些培养皿那些霉菌会杀死葡萄球菌,所以他就发明了盘尼西林,所以这是一种偶然的发现。

那这篇文章的作者也觉得Batch Normalization 也和盘尼西林一样,是一种偶然的发现,但无论如何它是一个有用的方法。

To learn more ……

那其实 Batch Normalization不是唯一的 normalization方法,下面列了几个比较知名的方法,有兴趣可以继续研究:

Batch Renormalization https://arxiv.org/abs/1702.03275 

Layer Normalization https://arxiv.org/abs/1607.06450 

Instance Normalization https://arxiv.org/abs/1607.08022 

Group Normalization https://arxiv.org/abs/1803.08494 

Weight Normalization https://arxiv.org/abs/1602.07868 

Spectrum Normalization https://arxiv.org/abs/1705.10941

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

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