前言
卷积神经网络(CNN)是受人类视觉神经系统运作原理启发而出现的算法,在图像识别领域有着广泛的应用。
试想如果用全连接神经网络来识别一张 1000x1000的RGB(3通道)图像,一个像素需要一个神经元那么我们就需要 1000x1000x3=3百万个参数进行反向传播梯度更新,这个计算量是非常消耗资源的!这时CNN应运而生。
CNN 有2大特点:
- 能够有效的将大数据量的图片降维成小数据量
- 能够有效的保留图片特征,符合图片处理的原则
CNN主要由:卷积层、池化层、全连接层组成:
卷积层
卷积层主要用来提取图像中的局部特征。
在二维卷积层中,一个二维输入数组和一个二维核(kernel)数组通过互相关运算输出一个二维数组。如图输入高和宽为3x3,卷积核数组的高和宽3x3,该数组在卷积计算中又称卷积核或过滤器(filter),卷积核窗口的形状取决于卷积核的高和宽,卷积输出为卷积核覆盖输入的区域乘积的和:
卷积层的滑动运算过程(滑动步幅为1)如下图,用一个卷积核扫完整张图片:
卷积计算涉及到的几个概念:
1.步幅stride
卷积窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。我们将每次滑动的行数和列数称为步幅
上面例子中在高和宽两个方向上步幅均为1, 如果在宽上步幅为2,高上步幅为3的话则计算过程变成:
2.填充padding
在输入高和宽的两侧填充元素(通常是0元素),我们在原输入高和宽的两侧分别添加了值为0的元素,使得输入高和宽从3变成了5,并导致输出高和宽由2增加到4:
通过控制填充数量可以让卷积计算后的宽和高跟原来保持一致,另外在图片边缘的点也可以被多次计算,防止边缘信息的丢失
3.输入通道channel
前面的例子用到的输入和输出都是二维数组,但真实数据的维度经常更高的,如彩色图像,一般都是RGB三个通道的,因此输入数据的维度一般有三个(长,宽,通道数)
如含2个输入通道的二维互相关计算的例子。在每个通道上,二维输入数组与二维核数组做互相关运算,再按通道相加即得到输出:
4.输出通道channel
上面例子通过卷积计算之后输出是一个通道,也可以设置卷积之后输出通道数(作为下一层卷积网络的输入通道数)
如输入3通道,使用1x1的卷积核,输出2通道:
5.激活函数Activation
在卷积计算完后面其实还有一个激活函数(这一点跟神经网络一样),一般使用如Relu,实践中相比Sigmoid激活函数更加简单而有效
池化层Pooling
同卷积层一样,池化层每次对输入数据的一个固定形状窗口中的元素计算输出。池化层直接计算池化窗口内元素的最大值(或平均值),该运算也分别叫做最大池化(或平均池化),在二维最大池化中,池化窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动,当池化窗口滑动到某一位置时,窗口中的输入子数组的最大值即输出数组中相应位置的元素,如max pooling:
池化层也有类似于卷积层的步幅、填充,用法一样
全连接层
全连接层类似传统神经网络的部分,用来输出想要的结果,经过卷积层和池化层处理过的数据输入到全连接层,得到最终想要的结果。
参数更新
CNN跟多个神经网路网络一样,也使用反向传播来更新参数,如果是池化层只反向传播用到的一个神经元,具体可以参看上一篇文章: 神经网络的反向传播
经典的卷积神经网络
- LeNet:这是最早用于数字识别的CNN
- AlexNet:2012 ILSVRC比赛远超第2名的CNN,比LeNet更深,用多层小卷积层叠加替换单大卷积层。
- ZF Net:2013 ILSVRC比赛冠军
- GoogLeNet:2014 ILSVRC比赛冠军
- VGGNet:2014 ILSVRC比赛中的模型,图像识别略差于GoogLeNet,但是在很多图像转化学习问题(比如object detection)上效果奇好
使用Pytorch创建卷积神经网络
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Sequential(
nn.Conv2d(
in_channels=1,
out_channels=16,
kernel_size=5,
stride=1,
padding=2,
),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2)
)
self.conv2 = nn.Sequential(
nn.Conv2d(16, 32, 5, 1, 2),
nn.ReLU(),
nn.MaxPool2d(2),
)
# fully connected layer, output 10 classes
self.out = nn.Linear(32 * 7 * 7, 10)
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = x.view(x.size(0), -1)
output = self.out(x)
return outpu
总结
- 卷积神经网络结构:输入层->多个[卷积层->激活函数->池化层]->全连接层->激活函数->输出
- 卷积层的神经元数量固定实现区域参数的共享,对高维数据处理无压力
- 卷积神经网络目前在图像分类、人脸识别、自动驾驶、视频安防、医疗等有着广泛的用用
参考
[1] 李沐 <<动手学深度学习>>
[2] https://easyai.tech/ai-definition/cnn/
[3] https://www.jianshu.com/p/c0215d26d20a
[4] https://www.jianshu.com/p/1ea2949c0056
网友评论