前言
本文为学习《深度学习》入门一书的学习笔记,详情请阅读原著
一、整体结构
卷积神经网络(Convolutional Neural Network,CNN)。CNN被用于图像识别、语音识别等各种场合。
CNN和之前介绍的神经网络一样,可以通过组装层来构建,但是,CNN中出现了卷积层(Convolution 层)和 池化层(Pooling层)。卷积层和池化层将在下一节讲述,先看看如何组装层以构建CNN。
之前介绍的神经网络中,相邻层的所有神经元之间都有连接,这称为全连接(fully-connected)。另外,我们用 Affine 层实现了全连接层。如果使用这个 Affine 层,一个 5 层的全连接的神经网络就可以通过图 7-1 所示的网络结构来实现。
如图 7-1 所示,全连接的神经网络中,Affine 层后面跟着激活函数 ReLU 层(或者 Sigmoid 层)。这里堆叠了 4 层“Affine-ReLU”组合,然后第 5 层是 Affine 层,最后由 Softmax 层输出最终结果(概率)。
图 7-1 基于全连接层(Affine 层)的网络的例子
CNN的结构
图 7-2 基于 CNN 的网络的例子:新增了 Convolution 层和 Pooling 层(用灰色的方块表示)
如图 7-2 所示,CNN 中新增了 Convolution 层和 Pooling 层。CNN 的层的连接顺序是“Convolution - ReLU -(Pooling)”(Pooling 层有时会被省略)。这可以理解为之前的“Affine - ReLU”连接被替换成了“Convolution - ReLU -(Pooling)”连接。
还需要注意的是,在图 7-2 的 CNN 中,靠近输出的层中使用了之前的“Affine - ReLU”组合。此外,最后的输出层中使用了之前的“Affine - Softmax”组合。这些都是一般的 CNN 中比较常见的结构。
二、卷积层
1、全连接层存在的问题
在全连接层(Affine层)中,相邻层的神经元全部连接在一起,输出的数量可以任意决定。
全连接层会忽视数据的形状,将全部的输入数据作为相同的神经元(同一维度的神经元)处理,所以无法利用与形状相关的信息。例如图像处理时。
而卷积层可以保持形状不变。当输入数据是图像时,卷积层会以3维数据的形式接收数据,并同样以3为数据的形式输出至下一层。因此,在CNN中,可以(有可能)正确的理解图像等具有形状的图形的数据。
在CNN中,会将卷积层的输入输出数据称为特征图(feature map)。卷积层的输入数据称为输入特征图(input feature map),输出数据称为输出特征图(output feature map)。本文中将“输入输出数据”和“特征图”作为含义相同的词使用。
2、卷积运算
卷积层进行的处理就是卷积运算。卷积运算相当于图像处理中的“滤波器运算”。
示例
图 7-3 卷积运算的例子:用“”符号表示卷积运算
假设用(height, width)表示数据和滤波器的形状,则在本例中,输入大小是 (4, 4),滤波器大小是 (3, 3),输出大小是 (2, 2)。另外,有的文献中也会用“核”这个词来表示这里所说的“滤波器”。
解释一下图 7-3 的卷积运算的例子中都进行了什么样的计算。图 7-4 中展示了卷积运算的计算顺序。
图 7-4 卷积运算的计算顺序
对于输入数据,卷积运算以一定间隔滑动滤波器的窗口并应用。这里所说的窗口是指图 7-4 中灰色的 3 × 3 的部分。如图 7-4 所示,将各个位置上滤波器的元素和输入的对应元素相乘,然后再求和(有时将这个计算称为乘积累加运算)。然后,将这个结果保存到输出的对应位置。将这个过程在所有位置都进行一遍,就可以得到卷积运算的输出。
在全连接的神经网络中,除了权重参数,还存在偏置。CNN 中,滤波器的参数就对应之前的权重。如图 7-5 所示,向应用了滤波器的数据加上了偏置。偏置通常只有 1 个(1 × 1)(本例中,相对于应用了滤波器的 4 个数据,偏置只有 1 个),这个值会被加到应用了滤波器的所有元素上。
图 7-5 卷积运算的偏置:向应用了滤波器的元素加上某个固定值(偏置)
3、填充
在进行卷积层的处理之前,有时要向输入数据的周围填入固定的数据(比如 0 等),这称为填充(padding),是卷积运算中经常会用到的处理。
图 7-6 卷积运算的填充处理:向输入数据的周围填入 0(图中用虚线表示填充,并省略了填充的内容“0”)
使用填充主要是为了调整输出的大小。比如,对大小为 (4, 4) 的输入数据应用 (3, 3) 的滤波器时,输出大小变为 (2, 2),相当于输出大小比输入大小缩小了 2 个元素。这在反复进行多次卷积运算的深度网络中会成为问题。为什么呢?因为如果每次进行卷积运算都会缩小空间,那么在某个时刻输出大小就有可能变为 1,导致无法再应用卷积运算。为了避免出现这样的情况,就要使用填充。在刚才的例子中,将填充的幅度设为 1,那么相对于输入大小 (4, 4),输出大小也保持为原来的 (4, 4)。因此,卷积运算就可以在保持空间大小不变的情况下将数据传给下一层。
4、步幅
应用滤波器的位置间隔称为步幅(stride)。之前的例子中步幅都是 1,如果将步幅设为 2,则如图 7-7 所示,应用滤波器的窗口的间隔变为 2 个元素
图 7-7 步幅为 2 的卷积运算的例子
在图 7-7 的例子中,对输入大小为 (7, 7) 的数据,以步幅 2 应用了滤波器。通过将步幅设为 2,输出大小变为 (3, 3)。像这样,步幅可以指定应用滤波器的间隔。
综上,增大步幅后,输出大小会变小。而增大填充后,输出大小会变大。将这样的关系写成算式,接下来,我们看一下对于填充和步幅,如何计算输出大小。
假设输入大小为 (H, W),滤波器大小为 (FH, FW),输出大小为 (OH, OW),填充为 P,步幅为 S。此时,输出大小可通过式 (7.1) 进行计算。
例 1:图 7-6 的例子
输入大小:(4, 4);填充:1;步幅:1;滤波器大小:(3, 3)
例 2:图 7-7 的例子
输入大小:(7, 7);填充:0;步幅:2;滤波器大小:(3, 3)
注意的是,虽然只要代入值就可以计算输出大小,但是所设定的值必须使式(7.1)中的 和 分别可以除尽。当输出大小无法除尽时(结果是小数时),需要采取报错等对策。顺便说一下,根据深度学习的框架的不同,当值无法除尽时,有时会向最接近的整数四舍五入,不进行报错而继续运行。
5、 3维数据的卷积运算
图像是 3 维数据,除了高、长方向之外,还需要处理通道方向。
图 7-8 是卷积运算的例子,图 7-9 是计算顺序。这里以 3 通道的数据为例,展示了卷积运算的结果。和 2 维数据时(图 7-3 的例子)相比,可以发现纵深方向(通道方向)上特征图增加了。通道方向上有多个特征图时,会按通道进行输入数据和滤波器的卷积运算,并将结果相加,从而得到输出。
图 7-8 对 3 维数据进行卷积运算的例子
图 7-9 对 3 维数据进行卷积运算的计算顺序
在 3 维数据的卷积运算中,输入数据和滤波器的通道数要设为相同的值。在这个例子中,输入数据和滤波器的通道数一致,均为 3。滤波器大小可以设定为任意值(不过,每个通道的滤波器大小要全部相同)。这个例子中滤波器大小为 (3, 3),但也可以设定为 (2, 2)、(1, 1)、(5, 5) 等任意值。再强调一下,通道数只能设定为和输入数据的通道数相同的值(本例中为 3)。
6、批处理
之前的全连接神经网络的实现也对应了批处理,通过批处理,能够实现处理的高效化和学习时对 mini-batch 的对应。
为此,需要将在各层间传递的数据保存为 4 维数据。具体地讲,就是按 (batch_num, channel, height, width) 的顺序保存数据。