3.7 批量归一化
如果误差表面很崎岖,它比较难训练。能不能直接改误差表面的地貌,“把山铲平”,让它变得比较好训练呢?批量归一化(Batch Normalization,BN)就是其中一个“把山铲平”的想法。不要小看优化这个问题,有时候就算误差表面是凸(convex)的,它就是一个碗的形状,都不一定很好训练。
如果是固定的学习率,可能很难得到好的结果,所以我们才需要自适应的学习率、Adam等比较进阶的优化的方法,才能够得到好的结果。
从另外一个方向想,直接把难做的误差表面把它改掉,看能不能够改得好做一点。
Q:什么时候 w1 的改变会对 L 的影响很小呢,也就是它在误差表面上的斜率会很小呢?
A: 一个可能性是当输入很小的时候....
因此在这个线性模型里,当输入的特征间范围差距很大时,就可能产生像不同方向,斜率非常不同,坡度非常不同的误差表面。So how?有没有可能给特征里面不同的维度,让它有同样的数值的范围。如果我们可以给不同的维度,同样的数值范围的话,那我们可能可以制造比较好的误差表面,让训练变得较易点。这些方法往往统称为特征归一化(feature normalization)。
以下所讲的方法只是特征归一化的一种可能性,Z 值归一化(Z-score normalization),也称为标准化(standardization)
假设 x1 到 xR,是我们所有的训练数据的特征向量。我们把所有训练数据的特征向量,统统都集合起来。向量 x1 里面x 11 代表 x1 的第一个元素,x 21 代表 x2 的第一个元素,以此类推。我们把不同笔数据即不同特征向量,同一个维度里面的数值,把它取出来,对于每个维度 i,计算其平均值(mean) m i和标准差(standard deviation)σ i。接下来我们就可以做一种归一化。
(就是把这边的某一个数值 x,减掉这一个维度算出来的平均值,再除掉这个维度,算出来的标准差,得到新的数值 x˜。得到新的数值以后,再把新的数值把它塞回去。)
归一化使得所有特征不同维度的数值都在 0 上下,可能就可以制造一个比较好的误差表面。它可以让在做梯度下降的时候,损失收敛更快一点,训练更顺利一点。
3.7.1 考虑深度学习
x˜ 代表归一化的特征,把它丢到深度网络里面,去做接下来的计算和训练。如图 3.41 所示,x˜1 通过第一层得到 z1,有可能通过激活函数( sigmoid 或者 ReLU 都可),再得到 a1,接着再通过下一层等等。对每个 x 都做类似的事情。
在经过一层 W i后都应该要对这些特征做归一化。如果选择 sigmoid,比较推荐对 z 做特征归一化,因为 sigmoid 是一个 s 的形状,其在 0 附近斜率比较大,如果对 z 做特征归一化,把所有的值都挪到 0 附近,到时候算梯度的时候,算出来的值会比较大。一般而言,特征归一化,要放在激活函数之前,之后都是可以的
其中,除号代表逐元素的除,即分子分母两个向量对应元素相除。
如图 3.43 所示,接下来可以通过激活函数得到其他向量,µ 跟 σ 都是根据 z1, z2, z3 计算出来的。改变了 z1 的值,a1 的值也会改变,µ 和 σ 也会改变。µ,σ 改后,z2, a2, z3, a3的值也会改变。之前的 x˜1, x˜2 x˜3 是独立分开处理的,但是在做特征归一化以后,这三个样本变得彼此关联了。所以有做特征归一化的时候,可以把整个过程当做是网络的一部分。即有一个比较大的网络,该网络吃一堆输入,用这堆输入在这个网络里面计算出 µ,σ,接下来产生一堆输出。
有一个问题了,因为训练数据非常多,容易爆显存。因此,在实现的时候只会考虑一个批量里面的样本。该技巧称为批量归一化(Batch normalization)。批量归一化适用于批量大小比较大的时候,批量大小如果比较大,也许这个批量大小里面的数据就足以表示整个数据集的分布。这个时候就不需要对整个数据集做特征归一化,而改成只在一个批量上做特征归一化作为近似。
Q:为什么要加上 β 跟 γ 呢?
A:如果不加上,做归一化以后,z˜ 的平均值一定是 0,若如此,会给网络一些限制且其可能会带来负面影响。所以需要把 β, γ 加回去,让网络隐藏层的输出平均值不是 0。让网络学习 β, γ 来调整一下输出的分布,从而来调整 zˆ 的分布。
Q:批量归一化是为了要让每一个不同的维度的范围相同,如果把 γ 跟 β 加进去,这样不同维度的分布,其范围不会又都不一样了吗?
A:有可能,但是实际上在训练的时候,γ 的初始值都设为 1,所以 γ 值都为 1 的向量。β 是值全部都是 0 的向量,即零向量。所以让网络在一开始训练的时候,每一个维度的分布,是比较接近 的,也许训练到后来,已经训练够长的一段时间,已经找到一个比较好的误差表面,走到一个比较好的地方以后,再把 γ, β 慢慢地加进去,所以加了 γ, β 的批量归一化,往往对训练是有帮助的。
3.7.2 测试时的批量归一化
以上说的都是训练的部分,测试有时候又称为推断(inference)。
在测试的时候,我们一次会得到所有的测试数据,确实也可以在测试的数据上面,制造一个一个批量。但是假设系统上线,做一个真正的线上的应用,比如批量大小设 64,我一定要等 64 笔数据都进来,才做一次运算,这显然是不行的。
Q: 在做批量归一化的时候,µ,σ 是用一个批量的数据算出来的。但如果在测试的时候,根本就没有批量,如何算 µ,σ 呢?
A: 实际上批量归一化在测试的时候,并不需要做什么特别的处理,PyTorch 已经处理好了。在训练的时候,如果有在做批量归一化,每一个批量计算出来的 µ,σ,都会拿出来算移动平均(moving average)。
假设现在有各个批量计算出来的 µ1, µ2, µ3, · · · · · · , µt,则可以计算移动平均:其中,µ¯ 是 µ 的个平均值,p 是因子,这也是一个常数,这也是一个超参数。在 PyTorch 里面,p 设 0.1。计算滑动平均来更新 µ 的平均值。最后在测试的时候,就不用算批量里面的 µ 跟 σ 了。因为测试的时候,在真正应用上也没有批量,可以就直接拿µ¯ 跟 σ¯ ,也就是 µ,σ 在训练的时候,得到的移动平均来取代原来的 µ 跟 σ,如图 3.45 所示:
图 3.46 是从批量归一化原始文献的实验结果,横轴代表的是训练的过程,纵轴代表的是验证集上的准确率。黑色的虚线没有做批量归一化,它用的是 inception(详见链接)的网络(一种网络以 CNN 为基础的网络架构),红色的这一条虚线有做批量归一化,其训练速度显然比黑色虚线快很多。虽然模型训练的时间够的话最后准确率差不多。但是红色虚线快; 蓝色的菱形代表同水平准确率; 粉红色的线是 sigmoid 函数,一般都会选择ReLU,因为 sigmoid 函数的训练是比较困难的。但强调!!,就算是 sigmoid 比较难搞的加批量归一化,还可训练,这边没有 sigmoid,没有做批量归一化的结果。因为在这个实验上,sigmoid 不加批量归一化,根本连训练都训练不起来。蓝色的实线跟这个蓝色的虚线呢是把学习率设比较大一点,×5 就是学习率变原来的 5倍;×30 就是 30 倍。因为如果做批量归一化,误差表面较平滑,较容易训练,所以可以把学习率设大点。这边有个不好解释的地方,学习率设 30 倍的时候比5 倍差,作者也没有解释。
3.7.3 内部协变量偏移
Q: 批量归一化为什么会有帮助呢?
A: 原始论文里面提出内部协变量偏移(internal covariate shift)概念。如图 3.47 所示,假设网络有很多层,-x 通过第一层后得到 a,a 通过第二层以后得到 b;计算出梯度以后,把 A 更新成 A′,把 B 这一层的参数更新成 B′。但是作者认为说,我们在计算 B 更新到 B′ 的梯度的时候,这个时候前一层的参数是 A,或者是前一层的输出是 a。那当前一层从 A 变成 A′ 的时候,其输出就从 a 变成 a′ 。但是我们计算这个梯度的时候,是根据 a 算出来,所以这个更新的方向也许它适合用在 a 上,但不适合用在 a′ 上面。 因为我们每次都有做批量归一化,就会让 a 和a′ 的分布比较接近,也许这样对训练有帮助。
但是论文“How Does Batch NormalizationHelp Optimization?”[11] 认为内部协变量偏移有问题。这篇论文从不同的角度来说明内部协变量偏移不一定是训练网络的时候的一个问题。批量归一化会比较好,可能不一定是因为它解决了内部协变量偏移。这篇论文里面做了很多实验,比如其比较了训练的时候 a 的分布的变化,发现不管有没有做批量归一化,其变化都不大。就算是变化很大,对训练也没有太大的伤害。不管是根据 a 算出来的梯度,还是根据 a′ 算出来的梯度,方向居然都差不多。内部协变量偏移(问题发生时)可能不是训练网络的时候,最主要的问题,它可能也不是批量归一化会好的一个的关键。
协变量偏移(covariate shift),训练集和预测集样本分布不一致的问题就叫做协变量偏移现象,
这个词汇是原来就有的,内部协变量偏移是批量归一化的作者自创。
为什么批量归一化会比较好呢,那在这篇“How Does Batch Normalization Help Optimization?”这篇论文从实验和理论上,至少支持批量归一化可以改变误差表面,让误差表面比较不崎岖这个观点。所以这个观点是有理论的支持,也有实验的佐证的。如果要如此,其实不一定要做批量归一化,还有很多其他的方法。 这篇论文就试了一些其他的方法,发现跟批量归一化表现也差不多,甚至还稍微好一点,这篇论文的作者也觉得批量归一化是一种偶然的发现,但无论如何,其是一个有用的方法。其实批量归一化不是唯一的归一化,还有很多归一化方法,比如批量重归一化(batchrenormalization)[12]、层归一化(layer normalization)[13]、实例归一化(instance normalization)[14]、组归一化(group normalization)[15]、权重归一化(weight normalization)[16] 和谱归一化(spectrum normalization)[17]。
小拓展:哪些算法不需要归一化
与距离计算无关的概率模型不需要,比如Naive Bayes;
与距离计算无关的基于树的模型,比如决策树、随机森林等,树中节点的选择只关注当前特征在哪里切分对分类更好,即只在意特征内部的相对大小,而与特征间的相对大小无关。但是我们前几篇文章中说到了,使用Z-Score归一化会提高模型的准确率。其实归一化的作用就是由绝对变为了相对,所以可以说归一化对于树型模型不那么重要,是一个可选项或者说可以作为一个超参数在训练时进行选择。
https://www.overfit.cn/post/767ff89fdb544dc1a20aad896d80859f 作者:Manish
第 4 章 卷积神经网络
卷积神经网络是一种非常典型的网络架构,常用于图像分类等任务。通过卷积神经网络,我们可以知道网络架构如何设计,以及为什么合理的网络架构可以优化网络的表现。
对于机器,图像可以描述为三维张量(张量可以想成维度大于 2 的矩阵)。一张图像是一个三维的张量,其中一维代表图像的宽,另外一维代表图像的高,还有一维代表图像的通道(channel)的数目。
Q:什么是通道?
A:彩色图像的每个像素都可以描述为红色(red)、绿色(green)、蓝色(blue)的组合,这 3 种颜色就称为图像的 3 个色彩通道。这种颜色描述方式称为 RGB 色彩模型,常用于在屏幕上显示颜色。
图像有大有小,而且不是所有图像尺寸都是一样的。常见的处理方式是把所有图像先调整成相同尺寸,再“丢”到图像的识别系统里面。以下的讨论中,默认模型输入的图像尺寸固定为 100像素 × 100像素。
由于每个神经元跟输入的向量中的每个数值都需要一个权重,所以当输入的向量长度是 100 × 100 × 3,且第 1 层有 1000 个神经元时,第 1 层的权重就需要 3 ×10的7次方 个权重,这是一个非常巨大的数目。更多的参数为模型带来了更好的弹性和更强的能力,但也增加了过拟合的风险。模型的弹性越大,就越容易过拟合。为了避免过拟合,在做图像识别的时候,考虑到图像本身的特性,并不一定需要全连接,即不需要每个神经元跟输入的每个维度都有一个权重。接下来就是针对图像识别这个任务,对图像本身特性进行一些观察。
模型的目标是分类,因此可将不同的分类结果表示成不同的独热向量 y′。在这个独热向量里面,类别对应的值为 1,其余类别对应的值为 0。若分类结果为猫,则猫所对应的维度的数值就是 1,其他东西所对应的维度的数值就是 0,独热向量 y′ 的长度决定了模型可以识别出多少不同种类的东西。如果希望图像识别系统可以识别上万种目标,标签就会是维度上万的独热向量。模型的输出通过 softmax 以后,输出是 yˆ。我们希望 y′ 和 yˆ 的交叉熵越小越好。
4.1 观察 1:检测模式不需要整张图像
对一个图像识别的类神经网络里面的神经元而言,它要做的就是检测图像里面有没有出现一些特别重要的模式(pattern),这些模式是代表了某种物体的。
神经元不需要把整张图像当作输入,只需要把图像的一小部分当作输入,就足以让它们检测某些特别关键的模式是否出现,这是第 1 个观察。
4.2 简化 1:感受野
根据观察 1 可以做第 1 个简化,卷积神经网络会设定一个区域,即感受野(receptivefield),每个神经元都只关心自己的感受野里面发生的事情,感受野是由我们自己决定的。
比如在图 4.6 中,蓝色的神经元的守备范围就是红色正方体框的感受野。这个感受野里面有3 × 3 × 3 个数值。对蓝色的神经元,它只需要关心这个小范围,不需要在意整张图像。这个神经元会把 3 × 3 × 3 的数值“拉直”变成一个长度是 3 × 3 × 3=27 维的向量,再把这 27 维的向量作为神经元的输入,这个神经元会给 27 维的向量的每个维度一个权重,所以这个神经元有 3 × 3 × 3 = 27 个权重,再加上偏置(bias)得到输出。这个输出再送给下一层的神经元当作输入。
感受野彼此之间也可以是重叠的,比如绿色的神经元的感受野跟蓝色的、黄色的神经元都有一些重叠的空间。我们没有办法检测所有的模式,所以同个范围可以有多个不同的神经元,即多个神经元可以去守备同一个感受野。接下来我们讨论下如何设计感受野。
感受野可以有大有小,此外,感受野可以只考虑某些通道。目前感受野是 RGB 三个通道都考虑,但也许有些模式只在红色或蓝色的通道会出现,即有的神经元可以只考虑一个通道。(之后在讲到网络压缩的时候,会讲到这种网络的架构。) 感受野不仅可以是正方形 / 长方形的,完全可以根据对问题的理解来设计感受野。感受野可以任意设计,但下面要跟大家讲一下最经典的感受野安排方式。
Q: 感受野一定要相连吗?
A: 感受野的范围不一定要相连,理论上可以有一个神经元的感受野就是图像的左上角跟右上角。但是就要想想为什么要这么做,会不会有什么模式也要看一个图像的左上角跟右下角才能够找到,没有就没什么用。要检测一个模式,这个模式就出现在整个图像里面的某一个位置,而不是分成好几部分,出现在图像里面的不同的位置。所以通常的感受野都是相连的领地,但如果要设计很奇怪的感受野去解决很特别的问题,完全是可以的,这都是自己决定的。
一般做图像识别会看全部的通道,在描述一个感受野的时候,只要讲它的高跟宽,不用讲它的深度,因为它的深度就等于通道数,而高跟宽合起来叫做核大小。常见的感受野设定方式就是核大小为 3 × 3。
一般同一个感受野会有一组(64/128个)神经元去守备这个范围。接下来介绍下各个不同感受野之间的关系。我们把左上角的感受野往右移一个步幅,就制造出一个新的守备范围/感受野。移动的量称为步幅(stride),图 4.9 中的这个例子里面,步幅就等于 2。步幅是一个超参数。因为希望感受野跟感受野之间是有重叠的,所以步幅一般设为 1 或 2。
Q: 为什么希望感受野之间是有重叠的呢?
A: 因为假设感受野完全没有重叠,如果有一个模式正好出现在两个感受野的交界上面,就没有任何神经元去检测它,这个模式可能会丢失,所以希望感受野彼此之间有高度的重叠。如令步幅 = 2,感受野就会重叠。
感受野超出了图像的范围,怎么办呢?如果不在超过图像的范围“摆”感受野,就没有神经元去检测出现在边界的模式,这样就会漏掉图像边界的地方,所以一般边界的地方也会考虑的。如图 4.10 所示,超出范围就做填充(padding),填充就是补值,一般使用零填充(zero padding),超出范围就补 0,如果感受野有一部分超出图像的范围之外,就当做那个里面的值都是 0。其实也有别的补值的方法,比如补整张图像里面所有值的平均值或者把边界的这些数字拿出来补没有值的地方。
除了水平方向的移动,也会有垂直方向上的移动,其步幅也是设 2,如图 4.11 所示。我们就按照这个方式扫过整张图像,所以整张图像里面每一寸土地都是有被某一个感受野覆盖的。也就是图像里面每个位置都有一群神经元在检测那个地方,有没有出现某些模式。这个是第 1 个简化。
4.3 观察 2:同样的模式可能会出现在图像的不同区域
第 2 个观察是同样的模式,可能会出现在图像的不同区域。比如说模式鸟嘴,它可能出现在图像的左上角,也可能出现在图像的中间,同样的模式出现在图像的不同的位置也不是太大的问题。
其实没必要每个守备范围都去放一个检测鸟嘴的神经元。如果不同的守备范围都要有一个检测鸟嘴的神经元,参数量会太多了,因此需要做出相应的简化。
4.4 简化 2:共享参数
先举个类似的例子:假设每个院系都需要深度学习相关的课程,没必要在每个院系都开机器学习的课程,可以开一个比较大型的课程,让所有院系的人都可以修课。如果放在图像处理上,则可以让不同感受野的神经元共享参数,也就是做参数共享(parameter sharing),如图 4.13 所示。所谓参数共享就是两个神经元的权重完全一样。
如图 4.14 所示,颜色相同,权重完全是一样的,比如上面神经元的第 1 个权重是 w1,下面神经元的第 1 个权重也是 w1,它们是同一个权重,用同一种颜色黄色来表示。上面神经元跟下面神经元守备的感受野是不一样的,但是它们的参数是相同的。虽然两个神经元的参数是一模一样,但它们的输出不会永远都是一样的,因为它们的输入是不一样的,它们照顾的范围是不一样的。上面神经元的输入是 x1, x2, · · · ,下面神经元的输入是 x′1, x′2, · · · ; 上面神经元的输出为
下面神经元的输出为:
因为输入不一样的关系,所以就算是两个神经元共用参数,它们的输出也不会是一样的。所以这是第 2 个简化,让一些神经元可以共享参数,共享的方式完全可以自己决定。接下来将介绍图像识别方面,常见的共享方法是如何设定的。
如图 4.15 所示,每个感受野都有一组神经元在负责守备,比如 64 个神经元,它们彼此之间可以共享参数。图 4.16 中使用一样的颜色代表这两个神经元共享一样的参数,所以每个感受野都只有一组参数,就是上面感受野的第 1 个神经元会跟下面感受野的第 1 个神经元共用参数,上面感受野的第 2 个神经元跟下面感受野的第 2 个神经元共用参数 · · · · · · 所以每个感受野都只有一组参数而已,这些参数称为滤波器(filter)。这是第 2 个简化的方法。
4.5 简化 1 和 2 的总结
总结下。如图 4.17 所示,全连接网络是弹性最大的。全连接网络可以决定它看整张图像还是只看一个范围,如果它只想看一个范围,可以把很多权重设成 0。全连接层(fully-connected layer),可以自己决定看整张图像还是一
(PDF暂时到此为止了,dbq,若有需要请等明天)
本文图文基本摘抄自————《深度学习详解》,非营利仅供学习参考,侵删。