CNN原理
CNN
卷积神经网络(CNN)的结构:
卷积层→池化层→全连接层
那为何不用传统全连接神经网络处理图像呢?其缺点也是很明显的,对于大尺寸图片:
- 首先将图片展开为张量会丢失信息
- 处理大尺寸图片需要巨量的参数
- 参数太多容易导致过拟合
卷积层
卷积层是构建卷积神经网络的核心层,它产生了网络中大部分的计算量。注意是计算量而不是参数量。
卷积
何谓卷积?其实就是乘加运算与位置移动。上图所示,左边第一个矩阵为输入x,第二个矩阵为卷积核,所谓卷积就是他们对应位置相乘相加,最后得到了右图中235的结果。那让卷积核不停在输入x上移动过再乘加,得到的就是卷积层的输出。如下图所示卷积核在输入x上不停移动和乘加即为卷积。
卷积运算的维度
既然引入了上图,那我们就借此说一下卷积运算的维度。都说卷积运算处理高度,宽度以外还有一个深度,何谓深度呢?我们先对以上gif做一个分析,就明白了。
首先输入为最左边一列三个矩阵,这三个矩阵来自于同一张图片的R,G,B三个通道,高度为5,宽度为5,外面灰色的0为padding(之后我们会提到),不是原图像数据内容。那么我们输入卷积层的Tensor的size就是:
$$
x[1,3,5,5]
$$
第一个维度表示一张图片,第二个维度为3个channel:RGB,也就是输入x的深度,第三、第四个维度为高度和宽度
图中第二列和第三列为两个卷积核,因为输入深度是3,所以他需要对R,G,B三个矩阵都做卷积,其深度也是3,那么卷积核的Tensor.size()
就是:
$$
K[2,3,3,3]
$$
第一个维度表示两个不同卷积核,第二个维度表示3个channel,也就是深度,第三、第四个维度为高度和宽度
那输出参数呢?看图中最后一列:
$$
out[1,2,3,3]
$$
因为这是一张图片通过两个卷积核所得的两个3x3输出。
感受野
如果将上图中每个像素点看作神经节点,对比全连接神经网络,我们发现每个神经节点的输入仅与9个输入节点和权重有关,而不再是全连接中的与所有上一层输入有关。也就是说下一层节点仅与上一层一些神经节点连接,而这些神经节点数量仅决于卷积核的长和宽,这就叫做感受野,即与神经元连接的空间大小。
如此一来,参数的数量不就打打减小了吗,对于28*28的图片,全连接神经网络第一个隐藏层每个节点需要784个参数,而卷积层中只需要卷积核个数x卷积核大小 这么多个参数。
空间排列
稍微动一下脑筋,若卷积核在移动过程中不允许超出输入x的边界范围,那输出矩阵的大小肯定小于原图片大小,所以我们需要引入 padding,即在图像最外面加一层或几层全为0的像素,如此已到达输出核输入矩阵大小相同的目的。
如上图所示,输入为5x5,如果padding=0,卷积核为3x3,那么输出只有2x2,加上一层padding,输出才能达到3x3.
步长就更好理解了,即卷积核每次移动几个单位。
那么以上几个参数都确定了的话,输出尺寸为多大呢,公式如下:
$$
outsize=\frac{W-F+2P}{S}+1
$$
其中
W:输入数据大小
F:卷积核尺寸
S:步长
P:padding
pytorch卷积层模块
nn.Conv2d()
:其输入参数如下
def __init__( |
in_channels:输入数据的channel数(深度),为3的化通常为RGB
out_channels:输出数据的深度,与卷积核的个数相同
kernel_size:感受野的大小,卷积核的尺寸
stride:移动步长
padding:padding=0表示不填充,padding=1表示填充一层
dilation:卷积杜宇输入数据体的空间间隔,默认为1
dilation=2时计算如下:
卷积时输入x不在紧邻,而是间隔一个像素点
groups:输出数据体深度上和输入数据体深度上的联系,默认为1,相关联。如果groups=2,则输入深度被分割成两份,输出数据也被分割成两份,他们之间分别对应起来,要求输入输出深度都能被groups整除。
bias:是否添加偏执
#example |
上述代码添加了一个输入channel为3,卷积核个数32,卷积核尺寸3x3,步长为1,padding=1,采用ReLU激活函数的卷积层。
池化层
通常会在卷积层之间周期性的插入一个池化层,其作用是逐渐减低数据体的空间尺寸,这样就能减少网络中的参数量,减少计算耗费资源,同时有效控制过拟合。
池化层和卷积层一样也有一个空间窗口,通常采取这些窗口中的最大值作为暑促,然后不断滑动窗口,对输入数据每一个深度切片(channel)单独处理,减少它的尺寸空间。
最常用的池化层尺寸为2*2,滑动步长为2:
输出数据体与输入数据体尺寸关系如下:
$$
W_2=\frac{W_1-F}{S}+1
$$
F:池化窗口大小
W1:输入数据大小
W2:输出数据大小
S:步长
卷积层之间一般引入最大池化效果最好,而平均池化一般放在卷积神经网络的最后一层。
谨慎使用比较大的池化窗口,以免对网络有破坏性
pytorch池化层模块
nn.MaxPool2d()
参数:
kernel_size: 窗口大小
stride: 步长
padding: 一般不添加
dilation: 默认为1
return_indices:是否返回最大值下标,默认为False
全连接层
全连接成与之前介绍的一般神经网络的结构是一样的。一般经过一系列卷积层核池化层之后,提取出图片的特征图,将特征图中所有神经元变为全连接层的样子。
比如卷积层和池化层的输出为3x3x512,那么将其变为3x3x512=4608个神经元,再经过几个隐藏层后输出结果,在这个过程中为了防止过拟合引入Dropout。
小卷积核有效性
一般而言,几个小滤波器的卷积层的组合比一个大滤波器好。
比如3个3x3的卷积核堆叠,其最终第三层卷积层对第一层输入数据的感受野是7x7,但这样做比直接使用一个7x7的卷积核好,原因如下:
- 多个卷积层之间还有激活函数,比单一卷积层的结构更能提取出深层的特征
- 3个3x3的卷积层才27个参数,一个7x7需要49个参数