全连接神经网络的局限性
- 当图片分辨率提高时,当隐藏层数量增加时,会导致参数增多
- 参数增多则会导致计算速度减慢和过拟合
卷积神经网络结构
- 输入层:将每个像素代表一个特征点输入到网络中
- 卷积层:卷积运算的主要目的是使原信号特征增强,并降低噪音
- 降采样层:降低网络训练参数及模型的过拟合程度
- 全连接层:对生成的特征进行加权
卷积
看一个例子,这是一个 6×6 的灰度图像。因为是灰度图像,所以它是 6×6×1 的矩阵,而 不是 6×6×3 的,因为没有 RGB 三通道。为了检测图像中的垂直边缘,你可以构造一个 3×3 矩阵。在卷积神经网络的术语中,它被称为过滤器
这个卷积运算的输出将会是一个 4×4 的矩阵,你可以将它看成一个 4×4 的图像
-
第一步卷积结果
4×4矩阵中第一个元素值为上图中左边的蓝色部分的3×3矩阵与中间的3×3过滤器进行元素乘法运算,即为:3×1 + 1×1 + 2×1 + 0×0 + 5×0 + 7×0 + 1 ×(−1) + 8×(−1) + 2×(−1) = −5 -
第二步卷积结果
接下来,为了弄明白第二个元素是什么,你要把蓝色的方块,向右移动一步,如下图所示。
继续做同样的元素乘法,然后加起来,所以是 0×1 + 5×1 + 7×1 + 1×0 + 8×0 + 2×0 + 2×(−1) + 9×(−1) + 5×(−1) = −4。 -
第三步卷积结果
接下来也是一样,继续右移一步,把 9 个数的点积加起来得到 0。
继续做同样的元素乘法,然后加起来,所以是 1×1 + 8×1 + 2×1 + 2×0 + 9×0 + 5×0 + 7×(−1) + 3×(−1) + 1×(−1) = 0。 -
第四步卷积结果
继续移得到 8,验证一下:2×1+9×1+5×1+7×0+3×0+1×0+4×(−1)+ 1 × (−1) + 3 × (−1) = 8。
-
第五步卷积结果
接下来为了得到下一行的元素,现在把蓝色块下移,现在蓝色块在这个位置:
重复进行元素乘法,然后加起来。通过这样做得到-10。再将其右移得到-2,接着是 2, 3。以此类推,这样计算完矩阵中的其他元素。 -
最后卷积结果
Padding
- 我们在之前卷积运算中看到,如果你用一个 3×3 的过滤器卷积一个 6×6 的图像,你最后会得到一个 4×4 矩阵。这背后的数学解释是,如果我们有一个? × ?的图像,用? × ?的过滤器做卷积,那么输出的维度就是(? − ? + 1) × (? − ? + 1)。在这个例子里是6 − 3 + 1 = 4, 因此得到了一个 4×4 的输出。
- 这样的话会有两个缺点,第一个缺点是每次做卷积操作,你的图像就会缩小
- 第二个缺点时,如果你注意角落边缘的像素,这个像素点只被一个输出所触碰或者使用,因为它位于这个 3×3 的区域的一角。但如果是在中间的像素点,比如这个,就会有许多 3×3 的区域与之重叠。所以那些在角落或者边缘区域的像素点在输出中采用较少,意味着你丢掉了图像边缘位置的许多信息
- 为了解决这些问题,你可以在卷积操作之前填充这幅图像。
你可以用 0 去填充,如果? 是填充的数量,在这个案例中,? = 1,因为我们在周围都填充了一个像素点,输出也就变 成了(? + 2? − ? + 1) × (? + 2? − ? + 1),所以就变成了(6 + 2 × 1 − 3 + 1) × (6 + 2 × 1 − 3 + 1) = 6 × 6,和输入的图像一样大。
至于选择填充多少像素,通常有两个选择,分别叫做 Valid 卷积和 Same 卷积。
Valid 卷积: Valid 卷积意味着不填充,这样的话,如果你有一个? × ?的图像,用一个? × ?的过滤器 卷积,它将会给你一个(? − ? + 1) × (? − ? + 1)维的输出
Same 卷积: Same 卷积,那意味你填充后,你的输出大小和输入 大小是一样的
卷积步长(Strided convolutions)
- 步长是卷积操作的重要概念,表示卷积核(过滤器)在图片上移动的格数
- 通过步长的变换,可以得到不同尺寸的卷积输出结果
- 当stride=1时
- 当stride=2时
如果你用一个? × ?的过滤器卷积一个? × ?的图像, 你的 padding 为?,步幅为?,输出于是变为 n + 2 p − f s + 1 \frac{n + 2p - f}{s} + 1 sn+2p−f+1
三维卷积(Convolutions over volumes)
我们从一个例子开始,假如说你不仅想检测灰度图像的特征,也想检测 RGB 彩色图像 的特征。彩色图像如果是6×6×3,这里的3指的是三个颜色通道,你可以把它想象成三个6×6 图像的堆叠。为了检测图像的边缘或者其他的特征,不是把它跟原来的 3×3 的过滤器做卷 积,而是跟一个三维的过滤器,它的维度是 3×3×3,这样这个过滤器也有三层,对应红绿、 蓝三个通道。
给这些起个名字(原图像),这里的第一个 6 代表图像高度,第二个 6 代表宽度,这个 3 代表通道的数目。同样你的过滤器也有高,宽和通道数,并且图像的通道数必须和过滤器的通道数匹配,所以这两个数(紫色方框标记的两个数)必须相等。这个的输出会是一个 4×4 的图像,注意是 4×4×1,最 后一个数不是 3 了。
为了简化这个 3×3×3过滤器的图像,我们不把它画成 3 个矩阵的堆叠,而一个三维的立方体。
为了计算这个卷积操作的输出,你要做的就是把这个 3×3×3 的过滤器先放到最左上角 的位置,这个 3×3×3 的过滤器有 27 个数,27 个参数就是 3 的立方。依次取这 27 个数,然 后乘以相应的红绿蓝通道中的数字。先取红色通道的前 9 个数字,然后是绿色通道,然后再 是蓝色通道,乘以左边黄色立方体覆盖的对应的 27 个数,然后把这些数都加起来,就得到 了输出的第一个数字。
如果要计算下一个输出,你把这个立方体滑动一个单位,再与这 27 个数相乘,把它们 都加起来,就得到了下一个输出,以此类推
所以和第一个过滤器卷积,可以得到第一个 4×4 的输出,然后卷积第二个过滤器,得到 一个不同的 4×4 的输出
单层卷积神经网络
我们已经讲了如何通过两个过滤器卷积处理一个三维图像,并输出两个不同的 4×4 矩阵。假设使用第一个过滤器进行卷积,得到第一个 4×4 矩阵。使用第二个过滤器进行 卷积得到另外一个 4×4 矩阵。
最终各自形成一个卷积神经网络层,然后增加偏差,它是一个实数,通过 Python 的广 播机制给这 16 个元素都加上同一偏差。然后应用非线性函数,为了说明,它是一个非线性激活函数 ReLU,输出结果是一个 4×4 矩阵。把这两个矩阵堆叠起来,最终得到一个 4×4×2 的矩阵。我们通过计算,从 6×6×3 的输入推导出一个 4×4×2 矩阵,它是卷积神经网络的一层,把它映射到 标准神经网络中四个卷积层中的某一层或者一个非卷积神经网络中。
注意前向传播中一个操作就是
z
[
1
]
=
W
[
1
]
a
[
0
]
+
b
[
1
]
z^{[1]} = W^{[1]}a^{[0]} + b^{[1]}
z[1]=W[1]a[0]+b[1]
其
中
a
[
0
]
为
输
入
x
,
即
为
图
中
的
输
入
矩
阵
,
W
[
1
]
表
示
过
滤
器
,
b
[
1
]
为
偏
差
其中a^{[0]}为输入x,即为图中的输入矩阵,W^{[1]}表示过滤器,b^{[1]}为偏差
其中a[0]为输入x,即为图中的输入矩阵,W[1]表示过滤器,b[1]为偏差
a
[
1
]
=
g
(
z
[
1
]
)
,
其
中
g
(
x
)
为
非
线
性
激
活
函
数
,
这
里
是
R
e
l
u
,
a
[
1
]
表
示
单
层
卷
积
神
经
网
络
的
输
出
a^{[1]} = g(z^{[1]}),其中g(x)为非线性激活函数,这里是Relu,a^{[1]}表示单层卷积神经网络的输出
a[1]=g(z[1]),其中g(x)为非线性激活函数,这里是Relu,a[1]表示单层卷积神经网络的输出
这就是?[0]到?[1]的演变过程,首先执行线性函数,然后所有元素相乘做卷积,具体做法是运用线性函数再加上偏差,然后应用激活函数 ReLU。
池化层(Pooling layers)
- 除了卷积层,卷积网络也经常使用池化层来缩减模型的大小,提高计算速度,同时提高所提取特征的鲁棒性。
- 计算图像一个区域上的某个特定特征的平均值或最大值,这种聚合操作就叫做池化
- 卷积层的作用是探测上一层特征的局部连接,而池化的作用是在语义上把相似的特征合并起来,从而达到将为的目的
- 常用的池化方法:
- 均值池化:对池化区域内的像素点取均值,这种方法得到的特征数据对背景信息更加敏感
- 最大池化:对池化区域内的像素点取最大值,这种方法得到的特征对纹理特征信息更加敏感。
先举一个最大池化(max pooling)的例子
假如输入是一个 4×4 矩阵。执行最大池化的树池是一个 2×2 矩阵。执行过程非常简单,把 4×4 的输入拆分成不同的区域,我把这个区域用不同颜色来标记。对于 2×2 的输出,输出的每个元素都是其对应颜色区域中的最大元素值。
卷积神经网络示例
构建全卷积神经网络的构造模块我们已经掌握得差不多了,下面来看个例子。
假设,有一张大小为 32×32×3 的输入图片,这是一张 RGB 模式的图片,你想做手写体 数字识别。32×32×3 的 RGB 图片中含有某个数字,比如 7,你想识别它是从 0-9 这 10 个数 字中的哪一个,我们构建一个神经网络来实现这个功能。
输入是 32×32×3 的矩阵,假设第一层使用过滤器大小为 5×5×3,步幅是 1,padding(填充)是 0,过滤器个数为 6,那么输出为 28×28×6。(32-5+1=28)将这层标记为 CONV1,它用了 6 个过滤器, 增加了偏差,应用了非线性函数,可能是 ReLU 非线性函数,最后输出 CONV1 的结果。
然后构建一个池化层,这里我选择用最大池化,参数? = 2,? = 2,最大池化使用的过滤器为 2×2,步幅为 2,表示层的高度和宽度会减少一半。因此,28×28 变成了 14×14((28 - 2)/2 + 1 = 14),通道数量保持不变,所以最终输出 为 14×14×6,将该输出标记为 POOL1。
我们再为它构建一个卷积层,过滤器大小为 5×5,步幅为 1,这次我们用 16 个过滤器, 最后输出一个 10×10×16 的矩阵,标记为 CONV2。
然后做最大池化,超参数? = 2,? = 2。你大概可以猜出结果,? = 2,? = 2,高度和宽度会减半,最后输出为 5×5×16,标记为 POOL2,这就是神经网络的第二个卷积层,即 Layer2。
5×5×16 矩阵包含 400 个元素,现在将 POOL2 平整化为一个大小为 400 的一维向量。我 们可以把平整化结果想象成这样的一个神经元集合,然后利用这 400 个单元构建下一层。下 一层含有 120 个单元,这就是我们第一个全连接层,标记为 FC3。这 400 个单元与 120 个单 元紧密相连,这就是全连接层。它的权重矩阵为?[q],维度为 120×400。
然后我们对这个 120 个单元再添加一个全连接层,这层更小,假设它含有 84 个单元, 标记为 FC4。
最后,用这 84 个单元填充一个 softmax 单元。如果我们想通过手写数字识别来识别手 写 0-9 这 10 个数字,这个 softmax 就会有 10 个输出。
以上为两层卷积层和两层全连接层神经网络全过程
为什么使用卷积?(Why convolutions?)
假设有一张 32×32×3 维度的图片,我们构建一个神经网络,如果使用全连接层,其中一层含有 3072 个单元,下一层含有 4074 个单元,两层中的每个神经元彼此相连,然后计算权重矩阵,它等于 4074×3072≈1400 万,所以要训练的参数很多。虽然以现在的技术,我们 可以用 1400 多万个参数来训练网络,因为这张 32×32×3 的图片非常小,训练这么多参数没 有问题。如果这是一张 1000×1000 的图片,权重矩阵会变得非常大。
如果使用卷积层,假设用了 6 个大小为 5×5×3 的过滤器,输出维度为 28×28×6。(32-5+1,padding = 0, 步长 = 1)一个过滤器有 25 个参数,再加上偏差参数,那么每个过滤器就有 26 个参数,一共有 6 个过滤器,所以参数共计 156 个,参数数量还是很少。
卷积网络映射这么少参数有两个原因:
- 一是参数共享。
- 二是使用稀疏连接
参考数据:吴恩达深度学习笔记