卷积神经网络(CNN)
卷积神经网络(CNN)
1.1二维卷积层
卷积神经网络是含有卷积层的神经网络,均使用最常见的二维卷积层,它有高和宽两个空间维度,常用来处理图像数据。
1.1.1二维互相关运算
在二维卷积层中,一个二维输入数组和一个二维核数组通过互相关运算输出一个二维数组。
输入一个高和宽均为3的二维数组,核数组的高和宽均为2,核数组在卷积计算中又称卷积核或过滤器,卷积核窗口(卷积窗口)的形状取决于卷积核的高和宽。
1.1.2二维卷积层
二维卷积层将输入和卷积核做互相关运算,并加上一个标量偏差来得到输出。卷积层的模型参数包括卷积核与标量偏差。在训练模型时,通常先对卷积核随机初始化,然后不断迭代卷积核与偏差。
卷积窗口形状为p x q的卷积层称为p x q卷积层,说明卷积核的高和宽分别为p和q。
1.1.3图像中物体边缘检测
卷积层的简单应用:检测图像中物体的边缘,即找到像素变化的位置。卷积层可以通过重复使用卷积核有效的表征局部空间。
1.1.4通过数据学习核数组
例子:使用物体边缘检测中的输入数据x,输出数据y,来构造核数组k。首先构造一个卷积层,将卷积核初始化成随机数组,在每一次迭代中,使用平方误差来比较Y和卷积层的输出,然后计算梯度来更新权重。
1.15特征图和感受野
特征图:二维卷积层输出的二维数组可以看做是输入在空间维度(宽和高)上某一级的表征。
感受野:影响元素x的前向计算的所有可能输入区域(可能大于输入的实际尺寸)叫做x的感受野。
1.2填充和步幅
假设输入形状是卷积核窗口形状是,输出形状是,所以卷积层的输出形状有输入形状和卷积核窗口形状决定。
1.2.1填充
填充:指在输入高和宽两侧填充元素(通常是0元素)。
卷积神经网络经常使用奇数的高和宽的卷积核,如1,3,5和7,所以两端上的填充个数相等。对任意的二维数组X,设它的第i行第j列的元素为X[i,j]。当两端上的填充个数相等,并使输入和输出具有相同的高和宽时,输出Y[i,j]是由输入X[i,j]为中心的窗口同卷积核进行互相关计算得到的。
当卷积核的高和宽不同时,通过设置高和宽上不同的填充数使输出和输入具有相同的高和宽。
1.2.2步幅
卷积窗口从输入数组的最左上方开始,按从左到右,从上往下的顺序,依次在输入数组上滑动。将每次滑动的行数和列数称为步幅。
1.3多输入通道和多输出通道
彩色图像在高和宽2个维度外还有RGB(红、绿、蓝)3个颜色通道。假设彩色图像的高和宽分别是h和w(像素),那么它可以表示为一个3 X h X w的多维数组。将大小为3的这一维称为通道维。
1.3.1多输入通道
当输入数据含多个通道时,需要构造一个输入通道数与输入数据的通道数相同的卷积核,从而能够与含多通道的输入数据做互相关运算。假设输入数据的通道数为,那么卷积核的输入通道数同样为。设卷积核窗口的形状为,卷积核只包含一个形状为的二维数组。当时,为每个输入通道各分配一个形状为的核数组。把这个数组在输入通道维上连结,得到一个形状维的卷积核。由于输入和卷积核各有个通道,在各个通道上对输入的二维数组和卷积核的二维数组做互相关运算,再将这个个互相关运算的二维输出按通道相加,得到一个二维数组。
下图,在每个通道上,二维输入数组与二维核数组做互相关运算,再按通道相加,得到输出。
1.3.2多输出通道
当输入通道有多个时,因为我们对各个通道的结果做了累加,所以无论输入通道数是多少,输出通道数总是1。设卷积核输入通道数和输出通道数分别为,高和宽分别为。如果希望得到含多个通道的输出,我们可以为每个输出通道分别创建形状为的核数组。将它们在输出通道维上连结,卷积核的形状。每个输出通道上的结果由卷积核在该输出通道上的核数组与整个输入数组计算而来。
1.3.3 1 x 1卷积层
卷积窗口形状为的多通道卷积层。通常称为1x1卷积层,并将其中的卷积运算称为1x1卷积。1x1卷积失去卷积层可以识别高和宽维度上相邻元素构成的模式的功能。1x1卷积的主要计算发生在通道维上。
使用多通道可以拓展卷积层的模型参数。
假设将通道维当做特征维,将高和宽维度上的元素当成数据样本,那么1x1卷积层的作用与全连接层等价。
1x1卷积层通常用来调整网络层之间的通道数,并控制模型复杂度。
1.4池化层
池化层,它的提出是为了缓解卷积层对位置的过度敏感性。
1.4.1二维最大池化层和平均池化层
池化层每次对输入数据的一个固定形状窗口(又称池化窗口)中的元素计算输出。池化层直接计算池化窗口内元素的最大值或者平均值。该运算也分别叫做最大池化或平均池化。在二维最大池化中,池化窗口从输入数组的最左上方开始,按从左到右,从上往下的顺序,依次在数组上滑动。当池化窗口移动到某一位置时,窗口中的输入子数组的最大值,即输出数组中相应位置的元素。
二维平均池化的工作原理与二维最大池化类似,但将最大运算符替换成平均运算符。池化窗口形状为的池化层称为池化层,其中的池化运算叫做池化。
1.4.2填充和步幅
同卷积层一样,池化层也可以在输入的高和宽两侧的填充并调整窗口的移动步幅来改变输出形状。池化层填充和步幅与卷积层填充和步幅的工作机制一样。
1.4.3多通道
在处理多通道输入数据时,池化层对每个输入通道分别池化,池化层的输出通道数与输入通道数相等。
1.5卷积神经网络(LeNet)
卷积神经网络就是含卷积层的网络。
1.5.1 LetNet模型
LetNet分为卷积层块和全连接层块两个部分。
卷积层块里的基本单位是卷积层后接最大池化层:卷积层用来识别图像里的空间模式,如线条和物体局部,最大池化层用来降低卷积层对位置的敏感性。卷积层块由两个这样的基本单位重复堆叠构成。
在卷积层中,每个卷积层都使用5x5的窗口,并在输出上使用sigmoid激活函数。第一个卷积层输出通道数为6,第二个卷积层输出通道数则增加到16。这是因为第二个卷积层比第一个卷积层的输入的高和宽要小,所以增加输出通道使两个卷积层的参数尺寸类似。卷积层块的两个最大池化层的窗口形状均为2x2,且步幅为2。由于池化窗口与步幅形状相同,池化窗口在输入上每次滑动所覆盖的区域互不重叠。
卷积层块的输出形状为(批量大小,通道,高,宽),当卷积层块的输出传入全连接层时,全连接层会将小批量中每个样本变平。即全连接层的输入形状将变成二维,其中第一维是小批量中的样本,第二维是每个样本变平后的向量表示,且向量长度为通道,高和宽的乘积。全连接层块含3个全链接层,它们的输出个数分别是120、84和10,其中10为输出的类别个数。
LetNet交替使用卷积层和最大池化层后接全连接层来进行图像分类。
1.6深度卷积神经网络(AlexNet)
神经网络可以直接基于图像的原始像素进行分类,这种称为端到端的方法。
1.6.1 AlexNet
AlexNet与LetNet的区别:
第一,与相对较小的LexNet相比,AlexNet包含8层变换,其中有5层卷积和2层全连接层隐藏层,以及1个全连接输出层。
AlexNet第一层中的卷积窗口形状是11x11,ImageNet图像的物体占用更多的像素,所以需要更大的卷积窗口来捕获物体。第二层中的卷积窗口形状减小到5x5,之后全采用3x3。第一、第二和第五个卷积层之后都使用了窗口形状为3x3、步幅为2的最大池化层。最后一个卷积层的时两个输出个数为4096的全连接层。
第二,AlexNet将sigmoid激活函数改成了更简单的ReLU激活函数。当sigmoid激活函数输出极限接近0或1时,这些区域的梯度几乎为0,从而造成反向传播无法继续更新部分模型参数,而ReLU激活函数在正区间的梯度恒为1。
第三,AlexNet通过丢弃法来控制全连接层的模型复杂度。而LeNet并没有使用丢弃法。
第四,AlexNet引入了大量的图像增广,如翻转、裁剪和颜色变化,从而进一步扩大数据集来缓解过拟合。
AlexNet和LetNet结构类似,但使用了更多的卷积层和更大的参数空间来拟合大规模数据集ImageNet。它是浅层神经网络和深度神经网络的分界线。
1.7使用重复元素的网络(VGG)
1.7.1 VGG块
VGG块的组成规律是:连续使用数个相同的填充为1、窗口形状为3x3的卷积层后接上一个步幅为2、窗口形状为2x2的最大池化层。卷积层保持输入的高和宽不变,而池化层则对其减半。使用vgg_block函数来实现这个基础的VGG块,它可以指定卷积层的数量num_convs和输出通道数num_channels。
1.7.2 VGG网络
与AlexNet和LeNet一样,VGG网络由卷积层模块后接全连接层模块构成。卷积层模块串联数个vgg_biock,其超参数由变量conv_rach定义。该变量指定了每个VGG块里卷积层个数和输出通道数,全连接层则跟AlexNet中的一样。
VGG这种高和宽减半以及通道翻倍的设计使得多数卷积层都有相同的模型参数尺寸和计算复杂度。
1.8网络中的网络(NiN)
网络中的网络(NiN),它提出了一个思路,即串联多个由卷积层和“全连接”层构成的小网络来构建一个深层网络。
1.8.1 NiN块
卷积层的输入和输出通常是四维数组(样本,通道,高,宽),而全连接层的输入和输出则通常是二维数组(样本,特征)。如果想在全连接层后再接上卷积层,则需要将全连接层的输出变换为四维。1x1卷积层可以看成全连接层,其中空间维度(高和宽)上的每个元素相当于样本,通道相当于特征。因此,NiN使用1x1卷积层来替代全连接层,从而使空间信息能够自然传递到后面的层中去。
NiN块是NiN中的基础块,它由一个卷积层加两个充当全连接层的1x1卷积层串联而成。其中第一个卷积层的超参数可以自行设置,而第二个和第三个卷积层的超参数一般是固定的。
1.8.2 NiN模型
NiN使用卷积窗口形状分别为11x11、5x5和3x3的卷积层,相应的输出通道数也与AlexNet中的一致。每个NiN块后接一个步幅为2、窗口形状为3x3的最大池化层。
除使用NiN块以外,NiN还有一个设计与AlexNet显著不同:NiN去掉了AlexNet最后的3个全连接层,使用了输出通道数等于标签类别数的NiN块,然后使用全局平均池化层对每个通道中所有元素求平均并直接用于分类。这里的全局平均池化层即窗口形状等于输入空间维形状的平均池化层。NiN的这个设计的好处是可以显著减小模型参数尺寸,从而缓解过拟合。
NiN重复使用由卷积层和代替全连接层的1x1卷积层构成的NiN块来构建深层网络。
1.9含并行连结的网络(GoogLeNet)
1.9.1 nception块
GoogLeNet中的基础卷积块叫做Inception块。
Inception块里有4条并行的线路,前3条分别是1x1、3x3和5x5的卷积层来抽取不同空间尺寸下的信息,其中中间2个线路会对输入先做1x1卷积来减少输入通道数,以降低模型复杂度。第四条线路则使用3x3最大池化层,后接1x1卷积层来改变通道数。4条线路都使用了合适的填充来使输入与输出的高和宽一致。最后将每条线路的输出在通道维上连结,并输入接下来的层中去。
Inception块中可以自定义的超参数是每个层的输出通道数,我们以此来控制模型复杂度。
1.9.2GoogLeNet模型
GoogLeNet跟VGG一样,在主体卷积部分中使用5个模块,每个模块之间使用步幅为2的3x3最大池化层来减小输出高宽。
第一个模块使用一个64通道的7x7卷积层。
第二个模块使用2个卷积层:首先是64通道的1x1卷积层,然后是将通道增大3倍的3x3卷积层。它对应Inception块中的第二条线路。
第三个模块串联2个完整的Inception块。
第四个模块串联了5个Inception块。
第五个模块的后面紧跟输出层,该模块同NiN一样使用全局平均池化层来将每个通道的高和宽变成1。最后将输出变成二维数组后接上一个输出个数为标签类别数的全连接层。
Inception块相当于一个有4条线路的子网络,它通过不同窗口形状的卷积层和最大池化层来并行抽取信息,并使用1x1卷积层减少通道数从而降低模型复杂度。
GoogLeNet将多个设计精细的Inception块和其它层串联起来,其中Inception块的通道数分配之比是在ImageNet数据集上通过大量的实验得到的。
GoogLeNet和它的后继者们一度是ImageNet上最高效的模型之一:在类似的测试精度下,它们的计算复杂度往往更低。
1.10批量归一化
在训练模型时,批量归一化利用小批量上的均值和标准差,不断调整神经网络中间输出,从而使整个神经网络在各层的中间输出的数值更稳定。
1.10.1批量归一化层
对全连接层做批量归一化
通常,我们将批量归一化层置于全连接层中的仿射变换和激活函数之间。设全连接层的输入为u,权重参数和偏差分别为W和b,激活函数为。设批量归一化的运算符为BN,那么,使用批量归一化的全连接层的输出为,其中批量归一化输入x由仿射变换得到。
考虑一个由m个样本组成的小批量,仿射变换的输出为一个新的小批量B=。它们正是批量归一化层的输入。对于小批量B任意样本,批量归一化层的输出同样是d维向量,并由以下几步求得。首先,小批量B求均值和方差:,,其中的平方计算是按元素平方。接下来,使用元素开方和按元素除法对标准化:,是一个很小的数,保证分母大于0。在标准化的基础上,批量归一化层引入了两个可以学习的模型参数,拉伸参数和偏移参数。这两个参数和形状相同,皆为d维向量,它们与分别按元素乘法和加法计算:,至此,我们得到了的批量归一化的输出。
对卷积层做批量归一化
对卷积层来说,批量归一化发生在卷积计算之后,应用激活函数之前。如果卷积计算输出多个通道,我们需要对这些通道的输出分别做批量归一化,且每个通道都拥有独立的拉伸和偏移参数,并均为标量。设小批量中有m个样本,在单个通道上,假设卷积计算输出的高和宽分别为p和q。我们需要对该通道中m x p x q个元素的均值和方差。
预测时的批量归一化
将训练好的模型用于预测时,我们希望模型对于任意输入都有确定的输出。因此,单个样本的输出不应取决于批量归一化所需要的随机小批量中的均值和方差。一种常用的方法是通过移动平均估算整个训练数据集的样本均值和方差,并在预测时使用它们得到确定的输出。
使用批量归一化层的LeNet
小结:
在训练模型时,批量归一化利用小批量上的均值和标准差,不断调整神经网络的中间输出,从而使整个神经网络在各层的中间输出的数值更稳定。
对全连接层和卷积层做批量归一化的方法稍有不同。
批量归一化层和丢弃层一样,在训练模式和预测模式的计算结果是不一样的。
Gluon提供的BatchNorm类使用起来简单、方便。
1.11 残差网络(ResNet)
1.11.1残差块
设输入为x,假设我们希望学出的理想映射为,作为激活函数的输入,左图虚线框中的部分需要直接拟合出该映射,而右图虚线框中的部分则需要拟合出有关恒等映射的残差映射。只需将右图虚线框内上方的加权运算(如仿射)的权重和偏差参数学成0,那么即为恒等映射。实际中,当理想映射接近于恒等映射时,残差映射也易于捕捉恒等映射的细微波动。右图是ResNet的基础块,即残差块。在残缺块中,输入可通过跨层的数据线路更快的向前传播。
设输入为x,假设图中最上方激活函数输入的理想映射为,左图虚线框中的部分需要直接拟合出该映射,而右图虚线框中的部分需要拟合出有关恒等映射的残差映射,ResNet沿用了VGG全3x3卷积层的设计。残差块里首先有2个有相同输出通道数的3x3卷积层。每个卷积层后接一个批量归一化层和ReLU激活函数。然后将输入跳过这两个卷积层运算后直接加在最后的ReLU激活函数前。这样的设计要求两个卷积层的输出与输入形状一样,从而可以相加。如果想改变通道数,许引入一个额外的1x1卷积层来将输入变换成需要的形状后再做相加运算。
1.11.2 ResNet模型
ResNet的前两层跟之前介绍的GoogLeNet中的一样:在输出通道数为64、步幅为2的7x7卷积层后接步幅为2的3x3的最大池化层。不同之处在于ResNet每个卷积层后增加的批量归一化层。
GoogLeNet在后面接了4个由Inception块组成的模块,ResNet则使用4个由残缺块组成的模块,每个模块使若干个同样的输出通道数的残缺块,第一个模块的通道数同输入通道数一致。由于之前已经使用了步幅为2的最大池化层,所以无需减小高和宽,之后的每个模块在第一个残缺块里将上一个模块的通道数翻倍,并将高和宽减半。
最后,与GoogLeNet一样,加入全局平均池化层后接上全连接层输出。
通过配置不同的通道数和模块里的残缺块数可以得到不同的ResNet模型。
残缺块通过跨层的数据通道从而能够训练出有效的深度神经网络。
1.12稠密连接网络(DenseNet)
稠密连接网络(DenseNet)与ResNet的主要区别:
图中将部分前后相邻的运算抽象为模块A和模块B,与ResNet的主要区别在于,DenseNet里模块B的输出不是像ResNet那样和模块A的输出相加,而是在通道维上连结。这样模块A的输出可以直接传入模块B后面的层。在这个设计里,模块A直接跟模块B后面的所有层连接在一起。这也是它被称为“稠密连接的原因。
DenseNet的主要构建模块是稠密块和过渡层。前者定义了输入和输出是如何连结的,后者则用来控制通道数,使之不过大。
1.12.1稠密块
稠密块由多个conv_block组成,每块使用相同的输出通道数。但在前向计算时,我们将每块的输入和输出在通道维上连结。
卷积块的通道数控制了输出通道数相对于输入通道数的增长,因此也被称为增长率。
1.12.2过渡层
由于每个稠密块都会带来通道数的增加,使用过多则会带来过于复杂的模型。过渡层用来控制模型复杂度。它通过1x1卷积层来减小通道数,并使用步幅为2的平均池化层减半高和宽,从而进一步降低模型复杂度。
1.12.3 DenseNet模型
我们来构造DenseNet模型,DenseNet首先使用同ResNet一样的单卷积层和最大池化层。DenseNet使用的是4个稠密模块。
在跨层连接上,不同于ResNet中将输入与输出相加,DenseNet在通道维上连结输入与输出。
DenseNet的主要构建模块是稠密块和过渡层。