主要学习任务: 1、批量归一化;2、卷积神经网络;3、CNN常用技巧
1、批量归一化
如果误差表面很崎岖,它比较难训练。能不能直接改误差表面的地貌,“把山铲平”,让它变得比较好训练呢?批量归一化(Batch Normalization,BN)就是其中一个“把山铲平”的想法。
特征归一化的原因?
例如一个非常简单的线性模型,其输入是 跟 ,对应的参数为 跟,它是一个线性的模型,没有激活函数。乘 ,乘 加上 以后就得到 ,然后会计算 跟 之间的差距当做 e,把所有训练数据 e 加起来就是损失,然后去最小化损失。
当 和 数值相差比较大时,参数 和 的变化差别也比较大,对应的误差表面就会有很大差别。可能产生不同方向,斜率非常不同,坡度非常不同的误差表面。特征归一化(feature normalization)可以解决这个问题,给不同维度的特征产生同样的数值范围
接下来介绍一种特征归一化的方法——Z 值归一化,也称为标准化。对全部的特征向量,同一个维度里面的数值取出来,对于每个维度 ,计算其平均值和标准差。Z值归一化即为该元素的数值减去平均值后除以标准值。归一化有个好处,做完归一化以后,这个维度上面的数值就会平均是 0,其方差是 1,所以这一排数值的分布就都会在 0 上下,可能就可以制造一个比较好的误差表面。它可以让在做梯度下降的时候,损失收敛更快一点,训练更顺利一点。
深度学习的归一化:中间层(z)的特征归一化,z 可以看成另外一种特征。一般而言,特征归一化,要放在激活函数之前,之后都是可以的,在实现上,没有太大的差别。
因为实际实现的时候,只对一个批量里面的数据做归一化,所以技巧称为批量归一化。一定要有一个够大的批量,才算得出 µ, σ。所以批量归一化适用于批量大小比较大的时候,批量大小如果比较大,也许这个批量大小里面的数据就足以表示整个数据集的分布。
测试时的批量归一化根本就没有批量,没办法计算 µ, σ。批量归一化在测试的时候,并不需要做什么特别的处理,PyTorch 已经处理好了。在训练的时候,如果有在做批量归一化,每一个批量计算出来的 µ, σ,从而算出移动平均,得到的移动平均来取代原来的 µ 跟 σ。下图就是批量归一化在测试的时候的运作方式。
下图是从批量归一化原始文献的实验结果,横轴代表的是训练的过程,纵轴代表的是验证集上的准确率。黑色的虚线是没有做批量归一化的结果。如果有做批量归一化,则是红色的这一条虚线。红色虚线的训练速度显然比黑色的虚线还要快很多。虽然只要给模型足够的训练的时间,最后会收敛都差不多的准确率。但是红色虚线可以在比较短的时间内跑到一样的准确率。
批量归一化不是唯一的归一化,还有很多归一化方法,比如批量重归一化(batch renormalization)、层归一化(layer normalization)、实例归一化(instance normalization)、组归一化(group normalization)、权重归一化(weight normalization)和谱归一化(spectrum normalization)。
2、卷积神经网络
卷积神经网络是一种非常典型的网络架构,常用于图像分类等任务。通过卷积神经网络,我们可以知道网络架构如何设计,以及为什么合理的网络架构可以优化网络的表现。
对于机器,图像可以描述为三维张量(张量可以想成维度大于 2 的矩阵)。一张图像是一个三维的张量,其中一维代表图像的宽,另外一维代表图像的高,还有一维代表图像的通道(channel)的数目。
什么是通道?A:彩色图像的每个像素都可以描述为红色(red)、绿色(green)、蓝色(blue)的组合,这 3 种颜色就称为图像的 3 个色彩通道。这种颜色描述方式称为 RGB 色彩模型,常用于在屏幕上显示颜色。
一张图像是由100×100×3 个数字所组成的,把这些数字排成一排就是一个巨大的向量。这个向量可以作为网络的输入,而这个向量里面每一维里面存的数值是某一个像素在某一个通道下的颜色强度。
由于每个神经元跟输入的向量中的每个数值都需要一个权重,所以当输入的向量长度是 100 × 100 × 3,且第 1 层有 1000 个神经元时,
第 1 层的权重就需要 1000 × 100 × 100 × 3 = 3 × 107个权重,这是一个非常巨大的数目。更多的参数为模型带来了更好的弹性和更强的能力,但也增加了过拟合的风险。为了避免过拟合,在做图像识别的时候,考虑到图像本身的特性,并不一定需要全连接,即不需要每个神经元跟输入的每个维度都有一个权重。
模型的输出:模型的目标是分类,因此可将不同的分类结果表示成不同的独热向量 y′。在这个独热向量里面,类别对应的值为 1,其余类别对应的值为 0。
3、常用技巧
(1)检测模式不需要整张图像——感受野
假设我们的任务是让网络识别出图像的动物。对一个图像识别的类神经网络里面的神经元而言,它要做的就是检测图像里面有没有出现一些特别重要的模式(pattern),这些模式是代表了某种物体的。比如有三个神经元分别看到鸟嘴、眼睛、鸟爪 3 个模式,这就代表类神经网络看到了一只鸟,如图。要知道图像有没有一个鸟嘴,只要看非常小的范围。这些神经元不需要把整张图像当作输入,只需要把图像的一小部分当作输入,就足以让它们检测某些特别关键的模式是否出现。
因此,卷积神经网络会设定一个区域,即感受野(receptive field),每个神经元都只关心自己的感受野里面发生的事情,感受野是由我们自己决定的。这个感受野里面有3 × 3 × 3 个数值。对蓝色的神经元,它只需要关心这个小范围,不需要在意整张图像里面有什么东西,只在意它自己的感受野里面发生的事情就好。这个神经元会把 3 × 3 × 3 的数值“拉直”变成一个长度是 3 × 3 × 3=27 维的向量,再把这 27 维的向量作为神经元的输入,这个神经元会给 27 维的向量的每个维度一个权重,所以这个神经元有 3 × 3 × 3 = 27 个权重,再加上偏置(bias)得到输出。这个输出再送给下一层的神经元当作输入。
感受野可以有大有小,因为模式有的比较小,有的比较大。感受野可以彼此重叠。感受野可以只考虑某些通道。感受野不仅可以是正方形的,也可以是长方形的,完全可以根据对问题的理解来设计感受野。
感受野超出了图像的范围,怎么办呢?如果不在超过图像的范围“摆”感受野,就没有神经元去检测出现在边界的模式,这样就会漏掉图像边界的地方,所以一般边界的地方也会考虑的。超出范围就做填充(padding),填充就是补值,一般使用零填充(zero padding),超出范围就补 0,如果感受野有一部分超出图像的范围之外,就当做那个里面的值都是 0。
(2)同样的模式可能会出现在图像的不同区域——共享参数
同样的模式,可能会出现在图像的不同区域。比如说模式鸟嘴,它可能出现在图像的左上角,也可能出现在图像的中间,同样的模式出现在图像的不同的位置也不是太大的问题。假设在某个感受野里面,有一个神经元的工作就是检测鸟嘴,鸟嘴就会被检测出来。所以就算鸟嘴出
现在中间也没有关系。
可以让不同感受野的神经元共享参数,也就是做参数共享(parameter sharing),如图所示。所谓参数共享就是两个神经元的权重完全是一样的。
因为输入不一样的关系,所以就算是两个神经元共用参数,它们的输出也不会是一样的。所以这是第 2 个简化,让一些神经元可以共享参数,共享的方式完全可以自己决定。
感受野加上参数共享就是卷积层(convolutional layer) ,用到卷积层的网络就叫卷积神经网络。卷积神经网络的偏差比较大。但模型偏差大不一定是坏事,因为当模型偏差大,模型的灵活性较低时,比较不容易过拟合。全连接层可以做各式各样的事情,它可以有各式各样的变化,但它可能没有办法在任何特定的任务上做好。而卷积层是专门为图像设计的,感受野、参数共享都是为图像设计的。虽然卷积神经网络模型偏差很大,但用在图像上不是问题。
(3)下采样不影响模式检测——汇聚
把一张比较大的图像做下采样(downsampling),把图像偶数的列都拿掉,奇数的行都拿掉,图像变成为原来的 1/4,但是不会影响里面是什么东西。汇聚有很多不同的版本,以最大汇聚(max pooling)为例。最大汇聚在每一组里面选一个代表,选的代表就是最大的一个,如图所示。除了最大汇聚,还有平均汇聚(mean pooling),平均汇聚是取每一组的平均值。
做完卷积以后,往往后面还会搭配汇聚。汇聚就是把图像变小。做完卷积以后会得到一张图像,这张图像里面有很多的通道。做完汇聚以后,这张图像的通道不变。
一般在实践上,往往就是卷积跟汇聚交替使用,可能做几次卷积,做一次汇聚。比如两次卷积,一次汇聚。不过汇聚对于模型的性能(performance)可能会带来一点伤害。假设要检测的是非常微细的东西,随便做下采样,性能可能会稍微差一点。
汇聚最主要的作用是减少运算量,通过下采样把图像变小,从而减少运算量。随着近年来运算能力越来越强,如果运算资源足够支撑不做汇聚,很多网络的架构的设计往往就不做汇聚,而是使用全卷积,卷积从头到尾,看看做不做得起来,看看能不能做得更好。