摘要:前面六节学习的还只是通用基础框架,设计思路较为粗略。要让网络更好地适配图像数据与任务场景,就需要针对图像的核心特性做精细化结构设计。本节学习针对图像的平移不变性和局部性结构设计的卷积神经网络CNN,了解卷积核的来由、填充与步幅的使用、汇聚层扩张感受野,从关注局部到整合全局,实现数字大脑处理图像的视觉皮层。
从全连接到卷积:图像适配的思考
图像中的检测对象即使改变位置,我们对检测对象的反应是相似的,这称为平移不变性。比如鸟嘴不管在图像的左上角、右上角还是中间,都不改变我们反应它是鸟嘴。也就是说,图像中任何位置的局部像素集,都应该使用同一套权重,权重不能依赖位置而变化。
图像中的像素存在一定的相关性,这种相关性是局部的、小范围的。边缘、纹理、形状这些特征,都只存在于局部区域,不需要用到全局信息就能判断。而且整体的构成就是依赖这些局部信息——比如一只猫是由局部的边缘、纹理、形状整合而成。如果不考虑局部,只关注大范围的区域,那么只要大范围中有一点点线条变化,可能就不理解这是猫了。
因此,我们需要使用一套作用于小范围的局部固定权重(卷积核),而不是全连接的随位置变化的n×n套权重。这样既减少了需要训练的参数量,又贴合了图像的局部性结构。使用卷积核做信号转换的层称为卷积层。
这里只考虑了图像的宽和高两个维度,这两个维度与空间位置有关,具有平移不变性和局部性。而实际图像有RGB三种原色组成,我们可以将RGB看作每个像素的多维表示,每个像素表示的维数就是通道数channel。
此外,前面只考虑了一套权重得到的一个隐藏表示,我们还可以考虑多套权重得到一组隐藏表示,分别表示不同的局部特征。比如一组专门识别边缘、一组专门识别纹理,这些就是输出通道(也叫特征映射)。
附:常见张量形状(简化)
• 输入X:(bs, H, W, C_in)
• 卷积核V:(C_out, k_h, k_w, C_in)
• 偏置b:(C_out)
图像卷积的几个细节
互相关 vs 卷积:严格卷积 = 上下、左右翻转卷积核 + 做互相关;深度学习实际一律用互相关替代卷积,不影响效果。
输出形状:当卷积核只与图像实际大小进行互相关运算,输出形状为:(bs, C_out, H-k_h+1, W-k_w+1)
考虑到单层时图像边缘丢失几个像素,当应用多层时丢失像素就多了,我们通过填充p_h行和p_w列来减少丢失,这样输出形状变为:(bs, C_out, H+p_h-k_h+1, W+p_w-k_w+1)。
若进一步将输出形状调整到和输入形状一样,则设p_h=k_h-1, p_w=k_w-1。由于两侧均匀填充,以高度为例,一侧p_h/2向上取整,一侧p_h/2向下取整。若k_h为奇数,则两侧均为p_h/2行填充。所以通常卷积核宽和高都取奇数,方便对称填充。
步幅:在前面的例子中,我们默认每次滑动一个元素。但是,有时候为了高效计算或是缩减采样次数,卷积窗口可以跳过中间位置,每次滑动多个元素。
假设高度、宽度步幅分别为s_h、s_w,则输出形状为:
(bs, C_out, 1+⌊(H+p_h-k_h)/s_h⌋, 1+⌊(W+p_w-k_w)/s_w⌋)
若p_h=k_h-1, p_w=k_w-1, H可被s_h整除,W可被s_w整除,则输出形状为:(bs, C_out, H/s_h, W/s_w)
PyTorch实现:
nn.Conv2d(
in_channels=1, # 输入通道数:每个像素的表示维度
out_channels=1, # 输出通道数:几组隐藏表示
kernel_size=(5, 3), # 卷积核大小
padding=(2, 1), # 填充大小
stride=(1, 1), # 步幅
bias=True # 偏置(默认开启)
)
感受野:对于某一层的任意元素,其感受野(receptive field)是指在前向传播期间可能影响计算的所有元素(来自所有先前层)。
汇聚层:降低空间分辨率,扩大感受野
经过几层卷积层,我们得到了足够的局部特征,可以降低采样、将局部感受野扩张,逐渐对全局敏感,得到全局信息。
与卷积层类似,汇聚层运算符由一个固定形状的窗口组成,该窗口根据其步幅大小在输入的所有区域上滑动,为固定形状窗口(有时称为汇聚窗口)遍历的每个位置计算一个输出。
然而,不同于卷积层中的输入与卷积核之间的互相关计算,汇聚层不包含参数。相反,池运算是确定性的,我们通常计算汇聚窗口中所有元素的最大值或平均值。这些操作分别称为最大汇聚层和平均汇聚层。
在处理多通道输入数据时,汇聚层在每个输入通道上单独运算,而不是像卷积层一样在通道上对输入进行汇总。这意味着汇聚层的输出通道数与输入通道数相同。
PyTorch实现:
nn.MaxPool2d(
kernel_size, # 汇聚窗口大小(必填)
stride=None, # 滑动步长(默认=kernel_size)
padding=0 # 填充
)
nn.AvgPool2d(2, stride=2)
LeNet:早期卷积神经网络的典范
• 卷积神经网络(CNN)是一类使用卷积层的网络
• 在卷积神经网络中,我们组合使用卷积层、非线性激活函数和汇聚层
• 为了构造高性能的卷积神经网络,我们通常对卷积层进行排列,逐渐降低其表示的空间分辨率,同时增加通道数
• 在传统的卷积神经网络中,卷积块编码得到的表征在输出之前需由一个或多个全连接层进行处理
• LeNet是最早发布的卷积神经网络之一
基于图像平移不变性与局部相关性的先验特性,针对图像数据设计了局部固定、全局复用的卷积核权重;通过填充与步幅灵活控制输出特征图的尺寸,同时引入多组独立卷积核生成多输出通道,同时提取边缘、纹理等多种局部特征。再通过汇聚层逐步扩大感受野、聚合局部信息,最终让高层神经元获得全局视野,完成图像级的全局推断。
关注小鱼,一起游历AI世界