卷积神经网络是深度学习领域最重要的概念之一。
如果使用单隐藏层MLP对有36M个特征的图片进行处理,假设隐藏层的神经元为100个,模型参数将达到3.6B,保存这些模型参数将占用14GB,这是不可行的。
感兴趣的对象满足两个特征,可以考虑卷积神经网络:
- 平移不变性
- 局部性
二维卷积
二维卷积运算:给定二维的图像I作为输入,二维卷积核K,卷积运算可表示为 S ( i , j ) = ( I ∗ K ) ( i , j ) = ∑ m ∑ n I ( i − m , j − n ) K ( m , n ) S(i, j)=(I * K)(i, j)=\sum_{m} \sum_{n} I(i-m, j-n) K(m, n) S(i,j)=(I∗K)(i,j)=∑m∑nI(i−m,j−n)K(m,n),卷积核需要进行上下翻转和左右翻转。
对于不同位置的图像输入,卷积核保持不变,体现了平移不变性;每个卷积核对相应卷积核窗口大小的图像输入计算得到结果,体现了局部性。
二维卷积层
- 输入: X : n h × n w X:n_h×n_w X:nh×nw
- 核: W : k h × k w W:k_h×k_w W:kh×kw
- 偏差: b ∈ R b\in R b∈R
- 输出: Y : ( n h − k h + 1 ) × ( n w − k w + 1 ) Y:(n_h-k_h+1)×(n_w-k_w+1) Y:(nh−kh+1)×(nw−kw+1)
- Y = X ∗ W + b Y=X*W+b Y=X∗W+b
- W , b W,b W,b是可学习的参数
虽然名义上是卷积,实际计算是交叉相关,二者唯一的不同就是卷积需要权重先进行翻转,然而在工程上是否进行翻转不影响效果,就没有进行翻转。
除了二维卷积处理图片,一维卷积适合处理文本、语言和时间序列;
三维卷积适合处理视频、医学图像和气象地图。
卷积层将输入和核矩阵进行交叉相关,加上偏移后得到输出;
核矩阵和偏移是可学习的参数;
核矩阵的大小是超参数。
卷积的特点之一是所要训练的权重参数的数量与输入的特征数量无关,只和卷积核的大小有关,解决了MLP因为输入特征数多,导致需要训练的权重参数也增多的问题。
互相关运算的Pytorch代码实现
import torch
from torch import nn
from d2l import torch as d2l
def corr2d(X, K): #@save
"""计算二维互相关运算。"""
h, w = K.shape
Y = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))
for i in range(Y.shape[0]):
for j in range(Y.shape[1]):
Y[i, j] = (X[i:i + h, j:j + w] * K).sum()
return Y
二维卷积层的Pytorch实现
class Conv2D(nn.Module):
def __init__(self, kernel_size):
super().__init__()
self.weight = nn.Parameter(torch.rand(kernel_size))
self.bias = nn.Parameter(torch.zeros(1))
def forward(self, x):
return corr2d(x, self.weight) + self.bias
填充
填充的目的是避免卷积造成输出的维度比输入的维度小。如果不进行填充,输入维度不高时,多次卷积后,输出结果维度过小,甚至小于卷积核,无法进一步增加模型的深度。
填充的具体做法是在输入的四周添加额外的行和列,填充值一般取0。
填充 p h p_h ph 行和 p w p_w pw 列,输出的形状为 ( n h − k h + p h + 1 ) × ( n w − k w + p w + 1 ) (n_h-k_h+p_h+1)×(n_w-k_w+p_w+1) (nh−kh+ph+1)×(nw−kw+pw+1)
通常取 p h = k h − 1 p_h=k_h-1 ph=kh−1 , p w = k w − 1 p_w=k_w-1 pw=kw−1,这样的好处是当步幅为1时,保持输入和输出的维度不变。
步幅
步幅是指行和列的滑动步长。使用大于1的步幅,可以迅速降低卷积输出的维度。
- 填充和步幅是卷积层的超参数;
- 填充在输入周围添加额外的行和列,来控制输出形状的减少量;
- 步幅是每次滑动核窗口时的行和列的步长,可以成倍地减少输出形状。
通常采用填充以确保卷积的输入和输出的形状大小保持不变,之所以这样做,是希望在堆叠很多卷积层的时候,不用去关心输出结果的维度变化。
步幅通常会选择1,如果选择大于1的步幅,往往是出于减少计算量的考虑。为了减少计算量,更快地降低特征维度,步幅也会经常选择2。
卷积核的边长一般取奇数,是为了填充的时候是对称的。常用的卷积核大小为3×3。
池化层
池化操作使用某位置相邻输出的总体统计特征作为该位置的输出,常用最大池化 (max-pooling)和均值池化(average- pooling)。
池化层不包含需要训练学习的参数,仅需指定池化操作的核大小、操作步幅以及池化类型。
池化的作用:
- 减少网络中的参数计算量,从而遏制过拟合
- 增强网络对输入图像中的小变形、扭曲、平移的鲁棒性(输入里的微小扭曲不会改变池化输出——因为我们在局部邻域已经取了最大值/ 平均值)
- 帮助我们获得不因尺寸而改变的等效图片表征。这非常有用,因为这样我们就可以探测到图片里的物体,不管它在哪个位置
全连接层
- 对卷积层和池化层输出的特征图(二维)进行降维
- 将学到的特征表示映射到样本标记空间的作用
输出层
对于分类问题:使用Softmax函数 y i = e z i ∑ i = 1 n e z i y_i = \frac{e^{z_i}}{\sum_{i = 1}^{n}e^{z_i}} yi=∑i=1neziezi 对于回归问题:使用线性函数 y i = ∑ m = 1 M w i m x m y_i = \sum_{m = 1}^{M}w_{im}x_m yi=m=1∑Mwimxm
参考资料
Datawhale 开源文档:https://github.com/liu-yang-maker/Easy-DL-Theory/tree/main/docs
B站视频《跟李沐学AI——动手学深度学习Pytorch版》:https://space.bilibili.com/1567748478/channel/seriesdetail?sid=358497
感谢Datawhale对开源学习的贡献!