一.批量归一化
继续上一篇文章的批量归一化,如果是固定的学习率,可能很难得到好的结果,所以我们才需要自适应的学习率、Adam等比较进阶的优化的方法,才能够得到好的结果。如果我们可以给不同的维度,同样的数值范围的话,那我们可能就可以制造比较好的误差表面,让训练变得比较容易一点其实有很多不同的方法,这些不同的方法往往就合起来统称为特征归一化(feature normalization)归一化有个好处,做完归一化以后,这个维度上面的数值就会平均是 0,其方差是 1,所以这一排数值的分布就都会在 0 上下;对每一个维度都做一样的归一化,所有特征不同维度的数值都在 0 上下,可能就可以制造一个比较好的误差表面。所以像这样子的特征归一化方式往往对训练有帮助,它可以让在做梯度下降的时候,损失收敛更快一点,训练更顺利一点。一般而言,特征归一化,要放在激活函数之前,之后都是可以的,在实现上,没有太大的差别。
GPU 的显存无法把它整个数据集的数据都加载进去。因此,在实现的时候,不会让这一个网络考虑整个训练数据里面的所有样本,而是只会考虑一个批量里面的样本。比如批量设 64,这个网络就是把 64 笔数据读进去,计算这 64 笔数据的 µ,σ,对这 64 笔数据做归一化。因为实际实现的时候,只对一个批量里面的数据做归一化,所以技巧称为批量归一化。一定要有一个够大的批量,才算得出 µ,σ。所以批量归一化适用于批量大小比较大的时候,批量大小如果比较大,也许这个批量大小里面的数据就足以表示整个数据集的分布。这个时候就不需要对整个数据集做特征归一化,而改成只在一个批量上做特征归一化作为近似。
下图是从批量归一化原始文献的实验结果
横轴代表的是训练的过程,纵轴代表的是验证集上的准确率。黑色的虚线是没有做批量归一化的结果,它用的是 inception 的网络(一种网络以 CNN 为基础的网络架构)。如果有做批量归一化,则是红色的这一条虚线。红色虚线的训练速度显然比黑色的虚线还要快很多。虽然只要给模型足够的训练的时间,最后会收敛都差不多的准确率。但是红色虚线可以在比较短的时间内跑到一样的准确率。蓝色的菱形代表说几个点的准确率是一样的。粉红色的线是 sigmoid 函数,一般的认知,但一般都会选择ReLU,而不是用 sigmoid 函数,因为 sigmoid 函数的训练是比较困难的。但是这边想要强调的点是,就算是 sigmoid 比较难搞的加批量归一化,还是可以训练的,这边没有 sigmoid,没有做批量归一化的结果。因为在这个实验上,sigmoid 不加批量归一化,根本连训练都训练不起来。蓝色的实线跟这个蓝色的虚线呢是把学习率设比较大一点,×5 就是学习率变原来的 5倍;×30 就是学习率变原来的 30 倍。因为如果做批量归一化,误差表面会比较平滑,比较容易训练,所以就可以把学习率设大一点。
二.卷积神经网络
(一)通道的定义
彩色图像的每个像素都可以描述为红色(red)、绿色(green)、蓝色(blue)的组合,这 3 种颜色就称为图像的 3 个色彩通道。这种颜色描述方式称为 RGB 色彩模型,常用于在屏幕上显示颜色。
一张图像是一个三维的张量,其中一维代表图像的宽,另外一维代表图像的高,还有一维代表图像的通道(channel)的数目。
(二)感受野
卷积神经网络会设定一个区域,即感受野(receptivefield),每个神经元都只关心自己的感受野里面发生的事情,感受野是由我们自己决定的。
一般在做图像识别的时候,可能不会觉得有些模式只出现在某一个通道里面,所以会看全部的通道。既然会看全部的通道,那么在描述一个感受野的时候,只要讲它的高跟宽,不用讲它的深度,因为它的深度就等于通道数,而高跟宽合起来叫做核大小。一般同一个感受野会有一组神经元去守备这个范围,比如 64 个或者是 128 个神经元去守备一个感受野的范围。目前为止,讲的都是一个感受野,接下来介绍下各个不同感受野之间的关系。我们把左上角的感受野往右移一个步幅,就制造出一个新的守备范围,即新的感受野。移动的量称为步幅(stride)。感受野需要有重叠,如果有一个模式正好出现在两个感受野的交界上面,就没有任何神经元去检测它,这个模式可能会丢失,所以希望感受野彼此之间有高度的重叠。如令步幅 = 2,感受野就会重叠。
若感受野超出图像范围,超出范围就做填充(padding),填充就是补值,一般使用零填充(zero padding),超出范围就补 0,如果感受野有一部分超出图像的范围之外,就当做那个里面的值都是 0。其实也有别的补值的方法,比如补整张图像里面所有值的平均值或者把边界的这些数字拿出来补没有值的地方。
(三)共享参数
如果放在图像处理上,则可以让不同感受野的神经元共享参数,也就是做参数共享(parameter sharing),如下图所示。所谓参数共享就是两个神经元的权重完全是一样的。
全连接网络是弹性最大的。全连接网络可以决定它看整张图像还是只看一个范围,如果它只想看一个范围,可以把很多权重设成 0。全连接层(fully-connected layer,)可以自己决定看整张图像还是一个小范围。但加上感受野的概念以后,只能看一个小范围,网络的弹性是变小的。参数共享又进一步限制了网络的弹性。本来在学习的时候,每个神经元可以各自有不同的参数,它们可以学出相同的参数,也可以有不一样的参数。但是加入参数共享以后,某一些神经元无论如何参数都要一模一样的,这又增加了对神经元的限制。而感受野加上参数共享就是卷积层(convolutional layer),用到卷积层的网络就叫卷积神经网络。卷积神经网络的偏差比较大。但模型偏差大不一定是坏事,因为当模型偏差大,模型的灵活性较低时,比较不容易过拟合。全连接层可以做各式各样的事情,它可以有各式各样的变化,但它可能没有办法在任何特定的任务上做好。而卷积层是专门为图像设计的,感受野、参数共享都是为图像设计的。虽然卷积神经网络模型偏差很大,但用在图像上不是问题。如果把它用在图像之外的任务,就要仔细想想这些任务有没有图像用的特性。
(四)滤波器
滤波器就是一个一个的张量,这些张量里面的数值就是模型里面的参数。这些滤波器里面的数值其实是未知的,它是可以通过学习找出来的。
不同的神经元可以共享权重,去守备不同的范围。而共享权重其实就是用滤波器扫过一张图像,这个过程就是卷积。这就是卷积层名字的由来。把滤波器扫过图像就相当于不同的感受野神经元可以共用参数,这组共用的参数就叫做一个滤波器。
(五)汇聚
汇聚没有参数,所以它不是一个层,它里面没有权重,它没有要学习的东西,汇聚比较像 Sigmoid、ReLU 等激活函数。因为它里面是没有要学习的参数的,它就是一个操作符(operator),其行为都是固定好的,不需要根据数据学任何东西。每个滤波器都产生一组数字,要做汇聚的时候,把这些数字分组,可以 2 × 2 个一组,3 × 3、4 × 4 也可以,这个是我们自己决定的。不过汇聚对于模型的性能(performance)可能会带来一点伤害。假设要检测的是非常微细的东西,随便做下采样,性能可能会稍微差一点。所以近年来图像的网络的设计往往也开始把汇聚丢掉,它会做这种全卷积的神经网络,整个网络里面都是卷积,完全都不用汇聚。汇聚最主要的作用是减少运算量,通过下采样把图像变小,从而减少运算量。随着近年来运算能力越来越强,如果运算资源足够支撑不做汇聚,很多网络的架构的设计往往就不做汇聚,而是使用全卷积,卷积从头到尾,看看做不做得起来,看看能不能做得更好。
(六)扁平化
扁平化就是把图像里面本来排成矩阵样子的东西“拉直”,即把所有的数值“拉直”变成一个向量。