1.3 卷积神经网络CNN
常规神经网络的线性变换操作WX,可以按如图1-6所示进行视觉理解,左边表示参数矩阵,也称权重矩阵W,假如其为3×4矩阵,而输入则为4×1的向量,那么按照矩阵乘法,W每行会和X每列的元素分别相乘,然后作连加求和操作,从而输出一个3×1的向量。
那么CNN是什么呢?其英文全称为Convolutional Neural Network,中文译为卷积神经网络。下面形象地讲解其结构。
图1-6 矩阵乘向量
首先,如果将图1-6中的输入X(灰)变换一下形式,比如2×2的结构,参数矩阵W的每行也变成2×2的结构,为了清晰,这里将W(黄、紫、绿)的三行分开画,便得到图1-7。
图1-7 CNN解析
这样一个3×4的二维参数矩阵就可视为一个3×2×2(或2×2×3)的三维矩阵,而输入X则变为一个2×2的矩阵。计算的时候,假设W视为3×2×2,则按箭头所示进行对应元素相乘,然后将结果相加,W每一层都会得到一个标量,这样综合起来就得到一个3×1的矩阵。然而这样变换到底有什么用呢?
细心的读者有没有发现:此时X的结构和前面讲的灰度图的矩阵表示结构一样,就是这个道理,只不过真正的灰度图表示为X时,黑色圆点更多而已,即像素更多。这种保持空间信息的线性乘法操作就是CNN操作,而参数矩阵W此时便叫作卷积核。
CNN会以固定大小的卷积核去扫描整张图片,每次在扫描的小区域内做上述线性变换操作,然后输出一个像素点,对整张图来说会扫描出很多这样的小区域(如2×2或3×3),这样便会输出一张很多像素点组成的特征图,即feature map。
卷积核最基础的参数如下:
● 核大小
● 输出通道数
● 输入通道数
● 边缘填充数
● 扫描步长
核大小就是图1-7中参数矩阵中每行的长×宽,即kernel size,此例中为2×2,现实中常用的还有3×3、1×3、3×1、1×1等。
输出通道数则是图1-7中参数矩阵中的行数,此处分别用三种颜色加以区分,即为3,但现实中输出通道数可能会更多,如64、128、512等。
输入通道数一般可由上层输入变量确定,此处为输入变量X,为一个二维变量的灰度图,所以其输入通道数为1,但现实的神经网络中经常是上一层的输出会作下一层的输入,所以输入和输出是针对某一层来说的,故输入通道数也有多种多样的变化,如1、3、32、64等。
边缘填充就是所谓的Padding,这是为了捕获边缘信息而产生的手段,一般就是在边缘的一行和列添0进行填充。
而步长则是卷积核每次扫描所移动的像素点数,一般有水平和垂直两个方向,步长常用的取值有1×1和2×2。
图1-8是一个大小为3×3、步长为1×1的卷积核,在4×4的灰度图上的操作,此时作了边缘为1的填充,这样经过卷积后输出还是一个4×4的feature map。如果想获得多输出通道,图1-8中左边为3×3×1的卷积核参数矩阵,第3维(1)便是输出通道数,改变这个数值即可。如果步长为2×2,那么卷积核扫描就会隔一个像素点扫描一次,最后则会输出一个2×2的feature map,形成所谓的下采样操作,即宽高降低(尺寸变小)。
图1-8 带边缘填充的卷积操作
对于卷积操作输入输出尺寸的变化,其实是有一个公式,希望通过上面的阐述,读者会对以下公式有更加直观形象地理解。需要注意,很多教程没有指明Padding(边缘填充)和Stride(步长)在不同方向是可以不同的,这可能会给初学者带来迷惑,所以在此将不同方向使用下标标明。当然在真正实践中,这些方向一般会设置为相同大小,但了解其原理对理解其真实操作是非常有必要的。
以上是对灰度图作卷积操作,那么遇到彩色图片怎么办呢?
其实原理都差不多,只是输入变成了一个三维矩阵。而且在处理灰度图的过程中,如果某一层的输出通道数为3,那这一层的输出本质上和彩色图片作为输入没有区别。从图1-9中可以管中窥豹。
图1-9 灰度图卷积输出彩图
对于一张1920×1080的灰度图,使用一个核大小为3×3(Wheight×Wwidth)、边缘填充为1×1(Paddingheight×Paddingwidth)、步长为1×1(Strideheight×Stridewidth)和输出通道数为3(output_channels)的卷积去扫描整张图片,其输出就是一个高和宽不变,但通道数变为3的3维矩阵,此矩阵其实可以看作一张彩色图片。如果后面再接一个卷积层,那么意味着后面的卷积层处理的就是彩色图片了。
对于彩色图片,可以从图1-10中看到,其操作与对灰度图片的操作类似,需要注意的是,此时黄色区域的层数会与输入图片的通道数一致,此时为3,且对应层的参数会与输入对应的通道进行卷积,然后再连加求和,形成最后的黄色输出通道,其他颜色输出通道类似。如果输出通道数为n,那么W可以形象地理解为有n组颜色的参数矩阵,即n×3×3×3。这点与灰度图不同,因为灰度图只有一个通道。
这是常规的CNN操作,但后来有人对彩色通道的这种操作提出了疑问,催生了Xception(3)这种网络模型,有兴趣的读者可查阅相关资料,本书后面也会作简要介绍。
CNN中的激活函数与常规网络并无太多出入,都是使用RELU、Sigmoid等函数。
图1-10 彩图卷积操作
另外,CNN中还有一类操作,叫作Pooling,其本质也是卷积操作。不同于常规的线性变换,它只是在相应的区域内提取最大值、最小值或平均值,分别可记为MaxPooling、MinPooling和AvgPooling。取最小值这种操作在真实情况下比较少见,用得较多的是最大值和平均值。
Pooling常常会用2×2的步长,以达到下采样的目的,同时取得局部抗干扰的效果。如图1-11所示,当0.1变为0.5时,其输出还是0.8,这种便是所谓的局部抗干扰,同时尺寸由4×4变为了2×2。
图1-11 Pooling操作
CNN主要结构单元清楚后,便是如何组装这些单元了,最常见的操作就是往深度方向叠加,即将这些子结构串联起来,如图1-12所示。
图1-12 卷积串联组合
这其实也就是VGG(4)网络的抽象结构,另外还有残差网络结构ResNet(5),以及考虑宽度方向的Inception(6)结构,本书后面都会作相关介绍。
CNN相对于常规的神经网络的优点就是:保持了输入变量的空间特性,同时大大减小神经网络的参数数量,最终得到的效果也非常好。
它通过不断添加网络层的方式达到了层级学习的效果,即每一层都负责学习相关的特征,比如对于CNN来说,靠近输入端的网络层会偏向学习点、线、角和面等基础特征;而靠近输出端的网络层则偏向学习图片内容等更加抽象的高级语义特征,此特征对这个输入来说比较独特,而基础特征对于所有输入都比较类似。
通过这样的层层学习,神经网络便学习到了非常好的特征来表达此输入,后面再加入几层全连接层或全卷积网络层,便可以完成分类或其他任务。
所以神经网络一般包含两个部分,前面的特征提取层和后面的任务层,通常这些层会合在一起训练,从而实现从输入到输出的端到端(End to End)训练。