Convolutional Neural Networks

Convolutional Layer

CNN中最重要的构件就是卷积层,特点是非全连接,而只是前一层的一小矩形区域的连接。 each neuron in the second convolutional layer is connected only to neurons located within a small rectangle in the first layer.

zero padding(零填充)

stride(步幅)

注意到卷积层的计算,采用same方式的话,那其实就是从原图的顶点开始,以该点为中心点产生一个包围着的矩阵,生成一个新图的点,然后再按方向移动,除非中心点不在原图了,就不再移动。因此当stride=1时,往往原图和新图的形状是一样的,但是如果stride=2,则往往会缩小一倍尺寸。

权重组就是filter(过滤器),又称为convolution kernels(卷积核),最终得到feature map(特征图)

卷积层实际由多组特征图组成,用3D表示(卷积层是卷积核在上一级输入层上通过逐一滑动窗口计算而得,准备说卷积核生成了卷积层)

每一层卷积层,由多组特征图构成。其中每一组特征图的输出值都是由该组特征图的计算权重与前一层的多组特征图的输出值相乘,再累加而得。

具体卷积层计算过程

如下图,假设现有一个为 6×6×3的图片样本,使用 3×3×3的卷积核(filter)进行卷积操作。此时输入图片的 channels 为 3 ,而卷积核中in_channels 与 需要进行卷积操作的数据的 channels 一致(这里就是图片样本,为3)。

cnn

接下来,进行卷积操作,卷积核中的27个数字与分别与样本对应相乘后,再进行求和,得到第一个结果。依次进行,最终得到 4×4的结果。

单个卷积核

上面步骤完成后,由于只有一个卷积核,所以最终得到的结果为 4×4×1, out_channels 为 1 。

在实际应用中,都会使用多个卷积核。这里如果再加一个卷积核,就会得到 4×4×2的结果。

多个卷积核

卷积层的尺寸计算

卷积层尺寸的计算原理

  • 输入矩阵格式:四个维度,依次为:样本数、图像高度、图像宽度、图像通道数

  • 输出矩阵格式:与输出矩阵的维度顺序和含义相同,但是后三个维度(图像高度、图像宽度、图像通道数)的尺寸发生变化。

  • 权重矩阵(卷积核)格式:同样是四个维度,但维度的含义与上面两者都不同,为:卷积核高度、卷积核宽度、输入通道数、输出通道数(卷积核个数)

  • 输入矩阵、权重矩阵、输出矩阵这三者之间的相互决定关系

    • 卷积核的输入通道数(in depth)由输入矩阵的通道数所决定。(红色标注)

    • 输出矩阵的通道数(out depth)由卷积核的输出通道数所决定。(绿色标注)

    • 输出矩阵的高度和宽度(height, width)这两个维度的尺寸由输入矩阵、卷积核、扫描方式所共同决定。计算公式如下。(蓝色标注)

\begin{cases} height_{out} &= (height_{in} - height_{kernel} + 2 * padding) ~ / ~ stride + 1\[2ex] width_{out} &= (width_{in} - width_{kernel} + 2 * padding) ~ / ~ stride + 1 \end{cases}

* 注:以下计算演示均省略掉了 Bias ,严格来说其实每个卷积核都还有一个 Bias 参数。

标准卷积计算举例

以 AlexNet 模型的第一个卷积层为例, - 输入图片的尺寸统一为 227 x 227 x 3 (高度 x 宽度 x 颜色通道数), - 本层一共具有96个卷积核, - 每个卷积核的尺寸都是 11 x 11 x 3。 - 已知 stride = 4, padding = 0, - 假设 batch_size = 256, - 则输出矩阵的高度/宽度为 (227 - 11) / 4 + 1 = 55

\begin{matrix} & \mathbf{Batch} & \mathbf{Height} && \mathbf{Width} && \mathbf{In~Depth} && \mathbf{Out~Depth}\[2ex] \mathbf{Input} & \quad\quad 256 \quad\quad \times & \color{blue}{227} & \times & \color{blue}{227} & \times & \color{red}{3} \[2ex] \mathbf{Kernel} &\quad\quad\quad\quad\quad & \color{blue}{11} & \times & \color{blue}{11} & \times & \color{red}{3} & \times & \color{green}{96} \[2ex] \mathbf{Output} & \quad\quad 256 \quad\quad \times & \color{blue}{55} & \times & \color{blue}{55} &&& \times & \color{green}{96} \end{matrix}

1 x 1 卷积计算举例

后期 GoogLeNet、ResNet 等经典模型中普遍使用一个像素大小的卷积核作为降低参数复杂度的手段。 从下面的运算可以看到,其实 1 x 1 卷积没有什么神秘的,其作用就是将输入矩阵的通道数量缩减后输出(512 降为 32),并保持它在宽度和高度维度上的尺寸(227 x 227)。

\begin{matrix} & \mathbf{Batch} & \mathbf{Height} && \mathbf{Width} && \mathbf{In~Depth} && \mathbf{Out~Depth}\[2ex] \mathbf{Input} & \quad\quad 256 \quad\quad \times & \color{blue}{227} & \times & \color{blue}{227} & \times & \color{red}{512} \[2ex] \mathbf{Kernel} &\quad\quad\quad\quad\quad & \color{blue}{1} & \times & \color{blue}{1} & \times & \color{red}{512} & \times & \color{green}{32} \[2ex] \mathbf{Output} & \quad\quad 256 \quad\quad \times & \color{blue}{227} & \times & \color{blue}{227} &&& \times & \color{green}{32} \end{matrix}

全连接层计算举例

实际上,全连接层也可以被视为是一种极端情况的卷积层,其卷积核尺寸就是输入矩阵尺寸,因此输出矩阵的高度和宽度尺寸都是1。

\begin{matrix} & \mathbf{Batch} & \mathbf{Height} && \mathbf{Width} && \mathbf{In~Depth} && \mathbf{Out~Depth}\[2ex] \mathbf{Input} & \quad \quad 256 \quad \quad \times & \color{blue}{32} & \times & \color{blue}{32} & \times & \color{red}{512} \[2ex] \mathbf{Kernel} &\quad\quad\quad\quad\quad & \color{blue}{32} & \times & \color{blue}{32} & \times & \color{red}{512} & \times & \color{green}{4096} \[2ex] \mathbf{Output} & \quad \quad 256 \quad \quad \times & \color{blue}{1} & \times & \color{blue}{1} &&& \times & \color{green}{4096} \end{matrix}

总结下来,其实只需要认识到,虽然输入的每一张图像本身具有三个维度,但是对于卷积核来讲依然只是一个一维向量。卷积核做的,其实就是与感受野范围内的像素点进行点积(而不是矩阵乘法)。

附:TensorFlow 中卷积层的简单实现

  • 输入 x:[batch, height, width, in_channel]

  • 权重 w:[height, width, in_channel, out_channel]

  • 输出 y:[batch, height, width, out_channel]

代码

注意参数的类型是numpy.ndarray。

参数的维度,其实类似索引方式,比如多加一个括号,dataset = np.array([china, flower],那么在形状上多一个维度(2, 427, 640, 3)

Each input image is typically represented as a 3D tensor of shape [height, width, channels].

A mini-batch is represented as a 4D tensor of shape [mini-batch size, height, width, channels].

The weights of a convolutional layer are represented as a 4D tensor of shape [fh, fw, fn, fn′].

这里的fn表示的是当前层的特征图数;fn'表示的是前一层的特征图数。

而经过tf.nn.conv2d返回的张量与输入有同样的类型[mini-batch size, height, width, channels],但是channel变为filter中当前层的特征图数。

内存需求

如上所述,每一层卷积层,由多组特征图构成。其中每一组特征图的输出值都是由该组特征图的计算权重与前一层的多组特征图的输出值相乘,再累加而得。

因此存在几处需要的内存消耗:filter中的参数及bias参数;计算每层特征图输出值的乘法运算以及输出值的所占空间;多组instances造成的内存消耗;训练时需要保存所有的数据,以方便反向传播时调整。

Pooling Layer

CNN中第二个常见的构件就是池化层,与卷积层类似,区别在于并不采用过滤器的权值去乘积累积,只是对于过滤器范围内进行聚合,比如max或mean

注意到池化的计算,采用valid方式的话,那其实就是从原图的顶点开始,生成一个新图的点,然后再按方向移动,当没有数据了,就不再移动,导致新图的尺寸比较小。

CNN Architectures

典型的cnn结构如下图所示:J猜测a few convolutional layers表示的就是一组特征层;a pooling layer就是对每一个特征层,生成一个池化后的结果,前后数量并不变。

Typical CNN architectures stack a few convolutional layers (each one generally followed by a ReLU layer), then a pooling layer, then another few convolutional layers (+ReLU), then another pooling layer, and so on. The image gets smaller and smaller as it progresses through the network, but it also typically gets deeper and deeper (i.e., with more feature maps) thanks to the convolutional layers. At the top of the stack, a regular feedforward neural network is added, composed of a few fully connected layers (+ReLUs), and the final layer outputs the prediction (e.g., a softmax layer that outputs estimated class probabilities).

CNN结构的变体

LeNet-5、AlexNet、GoogleNet、ResNet

关于MNIST的代码(这是作者自己搭的一个神经网络)

CPU可以运行

minibatch输入到神经网络的张量形状为:[mini-batch size, height, width, channels],一起输入的,而不是一个个样本分开输入,所以需要进行reshape下。

全连接层的输入的张量形状为:[mini-batch size, input],所以需要进行reshape下。

VGC16

Reference

Last updated

Was this helpful?