卷积神经网络CNN

卷积神经网络CNN

卷积神经网络(convolutional neural networks,CNN)是机器学习利用自然图像中一些已知结构的创造性方法。

不变性

假设我们想从一张图片中找到某个物体。 合理的假设是:无论哪种方法找到这个物体,都应该和物体的位置无关。理想情况下,我们的系统应该能够利用常识:猪通常不在天上飞,飞机通常不在水里游泳。 但是,如果一只猪出现在图片顶部,我们还是应该认出它。

卷积神经网络正是将空间不变性(spatial invariance)的这一概念系统化,从而基于这个模型使用较少的参数来学习有用的表示。

神经网络架构特性
  1. 平移不变性(translation invariance):不管检测对象出现在图像中的哪个位置,神经网络的前面几层应该对相同的图像区域具有相似的反应,即为“平移不变性”。

  2. 局部性(locality):神经网络的前面几层应该只探索输入图像中的局部区域,而不过度在意图像中相隔较远区域的关系,这就是“局部性”原则。最终,可以聚合这些局部特征,以在整个图像级别进行预测。

多层感知机的限制

多层感知机的输入是二维图像X\mathbf{X},其隐藏表示H\mathbf{H}在数学上是一个矩阵,在代码中表示为二维张量。

其中X\mathbf{X}H\mathbf{H}具有相同的形状。

为了方便理解,我们可以认为,无论是输入还是隐藏表示都拥有空间结构。

使用[X]i,j[\mathbf{X}]_{i, j}[H]i,j[\mathbf{H}]_{i, j}分别表示输入图像和隐藏表示中位置(ii,jj)处的像素。

为了使每个隐藏神经元都能接收到每个输入像素的信息,我们将参数从权重矩阵(如同我们先前在多层感知机中所做的那样)替换为四阶权重张量W\mathsf{W}。假设U\mathbf{U}包含偏置参数,我们可以将全连接层形式化地表示为:

[H]i,j=[U]i,j+kl[W]i,j,k,l[X]k,l=[U]i,j+ab[V]i,j,a,b[X]i+a,j+b.\begin{aligned} \left[\mathbf{H}\right]_{i, j} &= [\mathbf{U}]_{i, j} + \sum_k \sum_l[\mathsf{W}]_{i, j, k, l} [\mathbf{X}]_{k, l}\\ &= [\mathbf{U}]_{i, j} + \sum_a \sum_b [\mathsf{V}]_{i, j, a, b} [\mathbf{X}]_{i+a, j+b}.\end{aligned}

其中,从W\mathsf{W}V\mathsf{V}的转换只是形式上的转换,因为在这两个四阶张量的元素之间存在一一对应的关系。

我们只需重新索引下标(k,l)(k, l),使k=i+ak = i+al=j+bl = j+b,由此可得[V]i,j,a,b=[W]i,j,i+a,j+b[\mathsf{V}]_{i, j, a, b} = [\mathsf{W}]_{i, j, i+a, j+b}

索引aabb通过在正偏移和负偏移之间移动覆盖了整个图像。

对于隐藏表示中任意给定位置(ii,jj)处的像素值[H]i,j[\mathbf{H}]_{i, j},可以通过在xx中以(i,j)(i, j)为中心对像素进行加权求和得到,加权使用的权重为[V]i,j,a,b[\mathsf{V}]_{i, j, a, b}

平移不变性

引用上述的第一个原则:平移不变性。

这意味着检测对象在输入X\mathbf{X}中的平移,应该仅导致隐藏表示H\mathbf{H}中的平移。也就是说,V\mathsf{V}U\mathbf{U}实际上不依赖于(i,j)(i, j)的值,即[V]i,j,a,b=[V]a,b[\mathsf{V}]_{i, j, a, b} = [\mathbf{V}]_{a, b}。并且U\mathbf{U}是一个常数,比如uu。因此,我们可以简化H\mathbf{H}定义为:

[H]i,j=u+ab[V]a,b[X]i+a,j+b.[\mathbf{H}]_{i, j} = u + \sum_a\sum_b [\mathbf{V}]_{a, b} [\mathbf{X}]_{i+a, j+b}.

这就是卷积(convolution)。我们是在使用系数[V]a,b[\mathbf{V}]_{a, b}对位置(i,j)(i, j)附近的像素(i+a,j+b)(i+a, j+b)进行加权得到[H]i,j[\mathbf{H}]_{i, j}

注意,[V]a,b[\mathbf{V}]_{a, b}的系数比[V]i,j,a,b[\mathsf{V}]_{i, j, a, b}少很多,因为前者不再依赖于图像中的位置。

局部性

引用上述的第二个原则:局部性。

如上所述,为了收集用来训练参数[H]i,j[\mathbf{H}]_{i, j}的相关信息,我们不应偏离到距(i,j)(i, j)很远的地方。这意味着在a>Δ|a|> \Deltab>Δ|b| > \Delta的范围之外,我们可以设置[V]a,b=0[\mathbf{V}]_{a, b} = 0。因此,我们可以将[H]i,j[\mathbf{H}]_{i, j}重写为:

\begin{equation}[\mathbf{H}]_{i, j} = u + \sum_{a = -\Delta}^{\Delta} \sum_{b = -\Delta}^{\Delta} [\mathbf{V}]_{a, b} [\mathbf{X}]_{i+a, j+b} \label{convolutional layer} \end{equation}

简而言之,上述公式就是一个卷积层(convolutional layer),而卷积神经网络是包含卷积层的一类特殊的神经网络。

在深度学习研究中,V\mathbf{V}被称为卷积核(convolution kernel)或者滤波器(filter),亦或简单地称之为该卷积层的权重,通常该权重是可学习的参数。

当图像处理的局部区域很小时,卷积神经网络与多层感知机的训练差异可能是巨大的:以前,多层感知机可能需要数十亿个参数来表示网络中的一层,而现在卷积神经网络通常只需要几百个参数,而且不需要改变输入或隐藏表示的维数。

参数大幅减少的代价是,我们的特征现在是平移不变的,并且当确定每个隐藏活性值时,每一层只包含局部的信息。

以上所有的权重学习都将依赖于归纳偏置。当这种偏置与现实相符时,我们就能得到样本有效的模型,并且这些模型能很好地泛化到未知数据中。但如果这偏置与现实不符时,比如当图像不满足平移不变时,我们的模型可能难以拟合我们的训练数据。

卷积(convolution)

为什么称为“卷积”

为什么上面的操作被称为卷积(convolution)。

在数学中,两个函数(比如f,g:RdRf, g: \mathbb{R}^d \to \mathbb{R})之间的“卷积”被定义为:

(fg)(x)=f(z)g(xz)dz(f * g)(\mathbf{x}) = \int f(\mathbf{z}) g(\mathbf{x}-\mathbf{z}) d\mathbf{z}

也就是说,卷积是当把一个函数“翻转”并移位x\mathbf{x}时,测量ffgg之间的重叠。

当为离散对象时,积分就变成求和。例如,对于由索引为Z\mathbb{Z}的、平方可和的、无限维向量集合中抽取的向量,我们得到以下定义:

(fg)(i)=af(a)g(ia)(f * g)(i) = \sum_a f(a) g(i-a)

对于二维张量,则为ff的索引(a,b)(a, b)gg的索引(ia,jb)(i-a, j-b)上的对应加和:

(fg)(i,j)=abf(a,b)g(ia,jb)(f * g)(i, j) = \sum_a\sum_b f(a, b) g(i-a, j-b)

这看起来类似于[H]i,j[\mathbf{H}]_{i, j}重写后的公式,但有一个主要区别:这里不是使用(i+a,j+b)(i+a, j+b),而是使用差值。然而,这种区别是表面的,因为我们总是可以匹配两个公式之间的符号。我们在公式\eqref{convolutional layer}([H]i,j[\mathbf{H}]_{i, j}重写后的公式)中的原始定义更正确地描述了互相关(cross-correlation)。

通道(channel)

实际上,图像不是二维张量,而是一个由高度、宽度和颜色组成的三维张量,比如包含1024×1024×31024 \times 1024 \times 3个像素。

前两个轴与像素的空间位置有关,而第三个轴可以看作每个像素的多维表示。

因此,我们将X\mathsf{X}索引为[X]i,j,k[\mathsf{X}]_{i, j, k}。由此卷积相应地调整为[V]a,b,c[\mathsf{V}]_{a,b,c},而不是[V]a,b[\mathbf{V}]_{a,b}

此外,由于输入图像是三维的,我们的隐藏表示H\mathsf{H}也最好采用三维张量。换句话说,对于每一个空间位置,我们想要采用一组而不是一个隐藏表示。这样一组隐藏表示可以想象成一些互相堆叠的二维网格。因此,我们可以把隐藏表示想象为一系列具有二维张量的***通道***(channel)。

这些通道有时也被称为***特征映射***(feature maps),因为每个通道都向后续层提供一组空间化的学习特征。

直观上可以想象在靠近输入的底层,一些通道专门识别边缘,而一些通道专门识别纹理。

为了支持输入X\mathsf{X}和隐藏表示H\mathsf{H}中的多个通道,我们可以在V\mathsf{V}中添加第四个坐标,即[V]a,b,c,d[\mathsf{V}]_{a, b, c, d}。综上所述,

\begin{equation}[\mathsf{H}]_{i,j,d} = \sum_{a = -\Delta}^{\Delta} \sum_{b = -\Delta}^{\Delta} \sum_c [\mathsf{V}]_{a, b, c, d} [\mathsf{X}]_{i+a, j+b, c} \label{eq_conv-layer-channels} \end{equation}

其中隐藏表示H\mathsf{H}中的索引dd表示输出通道,而随后的输出将继续以三维张量H\mathsf{H}作为输入进入下一个卷积层。

所以,上式\eqref{eq_conv-layer-channels}可以定义具有多个通道的卷积层,而其中V\mathsf{V}是该卷积层的权重。

互相关运算

在卷积层中,输入张量核张量通过互相关运算(cross-correlation)产生输出张量。

../_images/correlation.svg

  • 输入是高度为33、宽度为33的二维张量(即形状为3×33 \times 3)。

  • 卷积核的高度和宽度都是22,则卷积核窗口(或卷积窗口)的形状由内核的高度和宽度决定(即2×22 \times 2)。

在二维互相关运算中,卷积窗口从输入张量的左上角开始,从左到右、从上到下滑动。

当卷积窗口滑动到新一个位置时,包含在该窗口中的部分张量与卷积核张量进行按元素相乘,得到的张量再求和得到一个单一的标量值,由此我们得出了这一位置的输出张量值

在如上例子中,输出张量的四个元素由二维互相关运算得到,这个输出高度为22、宽度为22,如下所示:

0×0+1×1+3×2+4×3=19,1×0+2×1+4×2+5×3=25,3×0+4×1+6×2+7×3=37,4×0+5×1+7×2+8×3=43.0\times0+1\times1+3\times2+4\times3=19,\\ 1\times0+2\times1+4\times2+5\times3=25,\\ 3\times0+4\times1+6\times2+7\times3=37,\\ 4\times0+5\times1+7\times2+8\times3=43.

注意,输出大小略小于输入大小。这是因为卷积核的宽度和高度大于1,而卷积核只与图像中每个大小完全适合的位置进行互相关运算。

所以,输出大小等于输入大小nh×nwn_h \times n_w减去卷积核大小kh×kwk_h \times k_w,即:

(nhkh+1)×(nwkw+1)(n_h-k_h+1) \times (n_w-k_w+1)

这是因为我们需要足够的空间在图像上“移动”卷积核。

如何通过在图像边界周围填充零来保证有足够的空间移动卷积核,从而保持输出大小不变。

卷积层中的两个被训练的参数是卷积核权重(weight)和标量偏置(bias)

从数据中学习卷积核的参数

当有了更复杂数值的卷积核,或者连续的卷积层时,我们不可能手动设计滤波器。

可以通过仅查看“输入-输出”来学习由X生成Y的卷积核。 我们先构造一个卷积层,并将其卷积核初始化为随机张量。接下来,在每次迭代中,我们比较Y与卷积层输出的平方误差,然后计算梯度来更新卷积核。

为了与深度学习文献中的标准术语保持一致,我们将继续把“互相关运算”称为**卷积运算,尽管严格地说,它们略有不同。 此外,对于卷积核张量上的权重,我们称其为*元素***。

**特征映射**可以被视为一个输入映射到下一层的空间维度的转换器。

在卷积神经网络中,对于某一层的任意元素xx,其感受野(receptive field)是指在前向传播期间可能影响xx计算的所有元素(来自所有先前层)。

请注意,感受野可能大于输入的实际大小。用以上输入(3 * 3)以及卷积核(2 * 2)为例来解释感受野:

给定2×22 \times 2卷积核,阴影输出元素值1919的感受野是输入阴影部分的四个元素。

假设之前输出为Y\mathbf{Y},其大小为2×22 \times 2,现在我们在其后附加一个卷积层,该卷积层以Y\mathbf{Y}为输入,输出单个元素zz

在这种情况下,Y\mathbf{Y}上的zz的感受野包括Y\mathbf{Y}的所有四个元素,而输入Y\mathbf{Y}的感受野包括最初所有九个输入元素。

因此,当一个特征图中的任意元素需要检测更广区域的输入特征时,我们可以构建一个更深的网络。

填充(padding)和步幅(stride)

假设以下情景:

有时,在应用了连续的卷积之后,我们最终得到的输出远小于输入大小。这是由于卷积核的宽度和高度通常大于11所导致的。比如,一个240×240240 \times 240像素的图像,经过10105×55 \times 5的卷积后,将减少到200×200200 \times 200像素。如此一来,原始图像的边界丢失了许多有用信息。而***填充是解决此问题最有效的方法;有时,我们可能希望大幅降低图像的宽度和高度。例如,如果我们发现原始的输入分辨率十分冗余*。***步幅***则可以在这类情况下提供帮助。

填充(padding)

填充(padding):在输入图像的边界填充元素(通常填充元素是00)。

在下图中,我们将3×33 \times 3输入填充到5×55 \times 5,那么它的输出就增加为4×44 \times 4

../_images/conv-pad.svg

通常,如果我们添加php_h行填充(大约一半在顶部,一半在底部)和pwp_w列填充(左侧大约一半,右侧一半),则输出形状将为

(nhkh+ph+1)×(nwkw+pw+1)(n_h-k_h+p_h+1)\times(n_w-k_w+p_w+1)

这意味着输出的高度和宽度将分别增加php_hpwp_w

在许多情况下,我们需要设置ph=kh1p_h=k_h-1pw=kw1p_w=k_w-1,使输入和输出具有相同的高度和宽度。这样可以在构建网络时更容易地预测每个图层的输出形状

假设khk_h是奇数,我们将在高度的两侧填充ph/2p_h/2行。如果khk_h是偶数,则一种可能性是在输入顶部填充ph/2\lceil p_h/2\rceil行,在底部填充ph/2\lfloor p_h/2\rfloor行(一个向上取整,一个向下取整)。同理,我们填充宽度的两侧。

卷积神经网络中卷积核的高度和宽度通常为奇数,例如1、3、5或7。选择奇数的好处是,保持空间维度的同时,我们可以在顶部和底部填充相同数量的行在左侧和右侧填充相同数量的列

此外,使用奇数的核大小和填充大小也提供了书写上的便利。对于任何二维张量X,当满足:

  1. 卷积核的大小是奇数;

  2. 所有边的填充行数和列数相同;

  3. 输出与输入具有相同高度和宽度

则可以得出:输出Y[i, j]是通过以输入X[i, j]为中心,与卷积核进行互相关计算得到的。

当卷积核的高度和宽度不同时,我们可以填充不同的高度和宽度,使输出和输入具有相同的高度和宽度。在如下示例中,我们使用高度为5,宽度为3的卷积核,高度和宽度两边的填充分别为2和1。

1
2
3
4
5
6
# padding=(2, 1):表示在行方向上,高处与低处都要填充2行,在列方向上,左边和右边都需要填充1行
# Ph = Kh - 1 = 4; Pw = Kw - 1 = 2
conv2d = nn.Conv2D(1, kernel_size=(5, 3), padding=(2, 1))
comp_conv2d(conv2d, X).shape

# 输出:(8, 8)

步幅(stride)

在计算互相关时,卷积窗口从输入张量的左上角开始,向下、向右滑动。在前面的例子中,我们默认每次滑动一个元素。但是,有时候为了高效计算或是缩减采样次数,卷积窗口可以跳过中间位置,每次滑动多个元素。

我们将每次滑动元素的数量称为***步幅***(stride)。到目前为止,我们只使用过高度或宽度为11的步幅,那么如何使用较大的步幅呢?

下图是垂直步幅为33,水平步幅为22的二维互相关运算。着色部分是输出元素以及用于输出计算的输入和内核张量元素:0×0+0×1+1×2+2×3=80\times0+0\times1+1\times2+2\times3=80×0+6×1+0×2+0×3=60\times0+6\times1+0\times2+0\times3=6

可以看到,为了计算输出中第一列的第二个元素和第一行的第二个元素,卷积窗口分别向下滑动三行和向右滑动两列。但是,当卷积窗口继续向右滑动两列时,没有输出,因为输入元素无法填充窗口(除非我们添加另一列填充)。

../_images/conv-stride.svg

通常,当垂直步幅为shs_h、水平步幅为sws_w时,输出形状为

(nhkh+ph+sh)/sh×(nwkw+pw+sw)/sw\lfloor(n_h-k_h+p_h+s_h)/s_h\rfloor \times \lfloor(n_w-k_w+p_w+s_w)/s_w\rfloor

如果我们设置了ph=kh1p_h=k_h-1pw=kw1p_w=k_w-1,则输出形状将简化为(nh+sh1)/sh×(nw+sw1)/sw\lfloor(n_h+s_h-1)/s_h\rfloor \times \lfloor(n_w+s_w-1)/s_w\rfloor

更进一步,如果输入的高度和宽度可以被垂直和水平步幅整除,则输出形状将为(nh/sh)×(nw/sw)(n_h/s_h) \times (n_w/s_w)

1
2
3
4
conv2d = nn.Conv2D(1, kernel_size=(3, 5), padding=(0, 1), strides=(3, 4))
comp_conv2d(conv2d, X).shape

# 输出:(2, 2)

为了简洁起见,当输入高度和宽度两侧的填充数量分别为php_hpwp_w时,我们称之为填充(ph,pw)(p_h, p_w)。当ph=pw=pp_h = p_w = p时,填充是pp。同理,当高度和宽度上的步幅分别为shs_hsws_w时,我们称之为步幅(sh,sw)(s_h, s_w)。特别地,当sh=sw=ss_h = s_w = s时,我们称步幅为ss默认情况下,填充为0,步幅为1。在实践中,我们很少使用不一致的步幅或填充,也就是说,我们通常有ph=pwp_h = p_wsh=sws_h = s_w

多输入多输出通道

多输入通道-单输出

当输入包含多个通道时,需要构造一个与输入数据具有相同输入通道数卷积核,以便与输入数据进行互相关运算。假设输入的通道数为cic_i,那么卷积核的输入通道数也需要为cic_i。如果卷积核的窗口形状是kh×kwk_h\times k_w,那么当ci=1c_i=1时,我们可以把卷积核看作形状为kh×kwk_h\times k_w的二维张量。

然而,当ci>1c_i>1时,我们卷积核的每个输入通道将包含形状为kh×kwk_h\times k_w的张量。将这些张量cic_i连结在一起可以得到形状为ci×kh×kwc_i\times k_h\times k_w的卷积核。由于输入和卷积核都有cic_i个通道,我们可以对每个通道输入的二维张量和卷积核的二维张量进行互相关运算再对通道求和(将cic_i的结果相加)得到二维张量。这是多通道输入和多输入通道卷积核之间进行二维互相关运算的结果。

如下图中,一个具有两个输入通道的二维互相关运算的示例。阴影部分是第一个输出元素以及用于计算这个输出的输入和核张量元素:(1×1+2×2+4×3+5×4)+(0×0+1×1+3×2+4×3)=56(1\times1+2\times2+4\times3+5\times4)+(0\times0+1\times1+3\times2+4\times3)=56

../_images/conv-multi-in.svg

多输出通道

cic_icoc_o分别表示输入和输出通道的数目,并让khk_hkwk_w为卷积核的高度和宽度。为了获得多个通道的输出,我们可以为每个输出通道创建一个形状为ci×kh×kwc_i\times k_h\times k_w卷积核张量,这样卷积核的形状是co×ci×kh×kwc_o\times c_i\times k_h\times k_w。在互相关运算中,每个输出通道先获取所有输入通道,再以对应该输出通道的卷积核计算出结果。

1×11\times 1 卷积层

1×11 \times 1卷积,即kh=kw=1k_h = k_w = 1,看起来似乎没有多大意义。毕竟,卷积的本质是有效提取相邻像素间的相关特征,而1×11 \times 1卷积显然没有此作用。尽管如此,1×11 \times 1仍然十分流行,经常包含在复杂深层网络的设计中。

因为使用了最小窗口,1×11\times 1卷积失去了卷积层的特有能力——在高度和宽度维度上,识别相邻元素间相互作用的能力。

其实1×11\times 1卷积的唯一计算发生在通道上

如下图,展示了使用1×11\times 1卷积核与33个输入通道和22个输出通道的互相关计算。

../_images/conv-1x1.svg

这里输入和输出具有相同的高度和宽度,输出中的每个元素都是从输入图像中同一位置的元素的线性组合。

我们可以将1×11\times 1卷积层看作在每个像素位置应用的全连接层,以cic_i个输入值转换为coc_o个输出值。

因为这仍然是一个卷积层,所以跨像素的权重是一致的。同时,1×11\times 1卷积层需要的权重维度为co×cic_o\times c_i,再额外加上一个偏置。

汇聚层(pooling)|池运算

汇聚层具有双重目的:降低卷积层对位置的敏感性,同时降低对空间降采样表示的敏感性。

最大汇聚层和平均汇聚层

与卷积层类似,汇聚层运算符由一个固定形状的窗口组成,该窗口根据其步幅大小在输入的所有区域上滑动,为固定形状窗口(有时称为***汇聚窗口***)遍历的每个位置计算一个输出。

然而,不同于卷积层中的输入与卷积核之间的互相关计算,汇聚层不包含参数

相反,池运算是确定性的,我们通常计算汇聚窗口中所有元素的最大值或平均值。这些操作分别称为*最大汇聚层(maximum pooling)和平均汇聚层*(average pooling)。

在这两种情况下,与互相关运算符一样,汇聚窗口从输入张量的左上角开始,从左往右、从上往下的在输入张量内滑动。在汇聚窗口到达的每个位置,它计算该窗口中输入子张量的最大值或平均值。计算最大值或平均值是取决于使用了最大汇聚层还是平均汇聚层。

../_images/pooling.svg

上图中的输出张量的高度为22,宽度为22。这四个元素为每个汇聚窗口中的最大值:

max(0,1,3,4)=4,max(1,2,4,5)=5,max(3,4,6,7)=7,max(4,5,7,8)=8.\max(0, 1, 3, 4)=4,\\ \max(1, 2, 4, 5)=5,\\ \max(3, 4, 6, 7)=7,\\ \max(4, 5, 7, 8)=8.\\

汇聚窗口形状为p×qp \times q的汇聚层称为p×qp \times q汇聚层,汇聚操作称为p×qp \times q汇聚。

与卷积层一样,汇聚层也可以通过填充和步幅改变输出形状。默认情况下,深度学习框架中的步幅与汇聚窗口的大小相同

在处理多通道输入数据时,汇聚层在每个输入通道上单独运算,而不是像卷积层一样在通道上对输入进行汇总。 这意味着汇聚层的输出通道数与输入通道数相同

LeNet:识别图像中的手写数字

LeNet取得了与支持向量机(support vector machines)性能相媲美的成果,成为监督学习的主流方法。 LeNet被广泛用于自动取款机(ATM)机中,帮助识别处理支票的数字。

LeNet ¶

总体来看,LeNet(LeNet-5)由两个部分组成:

  • 卷积编码器:由两个卷积层组成;

  • 全连接层密集块:由三个全连接层组成。

架构如下图所示:

../_images/lenet.svg

LeNet中的数据流。输入是手写数字,输出为10种可能结果的概率。

每个卷积块中的基本单元是一个卷积层、一个sigmoid激活函数和平均汇聚层。请注意,虽然ReLU和最大汇聚层更有效,但它们在20世纪90年代还没有出现。每个卷积层使用5×55\times 5卷积核和一个sigmoid激活函数。这些层将输入映射到多个二维特征输出,通常同时增加通道的数量。第一卷积层有6个输出通道,而第二个卷积层有16个输出通道。每个2×22\times2池操作(步幅2)通过空间下采样[1]将维数减少4倍。卷积的输出形状由批量大小、通道数、高度、宽度决定

为了将卷积块的输出传递给稠密块,我们必须在小批量中展平每个样本。换言之,我们将这个四维输入转换成全连接层所期望的二维输入。这里的二维表示的第一个维度索引小批量中的样本第二个维度给出每个样本的平面向量表示。LeNet的稠密块有三个全连接层,分别有120、84和10个输出。因为我们在执行分类任务,所以输出层的10维对应于最后输出结果的数量。

通过下面的LeNet代码,可以看出用深度学习框架实现此类模型非常简单。我们只需要实例化一个Sequential块并将需要的层连接在一起。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from mxnet import autograd, gluon, init, np, npx
from mxnet.gluon import nn
from d2l import mxnet as d2l

npx.set_np()

net = nn.Sequential()
net.add(nn.Conv2D(channels=6, kernel_size=5, padding=2, activation='sigmoid'),
nn.AvgPool2D(pool_size=2, strides=2),
nn.Conv2D(channels=16, kernel_size=5, activation='sigmoid'),
nn.AvgPool2D(pool_size=2, strides=2),
# 默认情况下,“Dense”会自动将形状为(批量大小,通道数,高度,宽度)的输入,
# 转换为形状为(批量大小,通道数*高度*宽度)的输入
nn.Dense(120, activation='sigmoid'),
nn.Dense(84, activation='sigmoid'),
nn.Dense(10))

我们对原始模型做了一点小改动,去掉了最后一层的高斯激活。除此之外,这个网络与最初的LeNet-5一致。

下图为简化版的LeNet示意图:

../_images/lenet-vert.svg

打印出每层的输出结果:

1
2
3
4
5
6
7
conv0 output shape:  (1, 6, 28, 28)
pool0 output shape: (1, 6, 14, 14)
conv1 output shape: (1, 16, 10, 10)
pool1 output shape: (1, 16, 5, 5)
dense0 output shape: (1, 120)
dense1 output shape: (1, 84)
dense2 output shape: (1, 10)

请注意,在整个卷积块中,与上一层相比,每一层特征的高度和宽度都减小了。

第一个卷积层使用2个像素的填充,来补偿5×55 \times 5卷积核导致的特征减少。

相反,第二个卷积层没有填充,因此高度和宽度都减少了4个像素。

随着层叠的上升,通道的数量从输入时的1个,增加到第一个卷积层之后的6个,再到第二个卷积层之后的16个。

同时,每个汇聚层的高度和宽度都减半。最后,每个全连接层减少维数,最终输出一个维数与结果分类数相匹配的输出。

小结

  • 图像的平移不变性使我们以相同的方式处理局部图像,而不在乎它的位置。

  • 局部性意味着计算相应的隐藏表示只需一小部分局部图像像素。

  • 在图像处理中,卷积层通常比全连接层需要更少的参数,但依旧获得高效用的模型。

  • 卷积神经网络(CNN)是一类特殊的神经网络,它可以包含多个卷积层

  • 多个输入和输出通道使模型在每个空间位置可以获取图像的多方面特征

  • 二维卷积层的核心计算是二维互相关运算最简单的形式是,对二维输入数据和卷积核执行互相关操作,然后添加一个偏置。

  • 我们可以设计一个卷积核检测图像的边缘

  • 我们可以从数据中学习卷积核的参数

  • 学习卷积核时,无论用严格卷积运算或互相关运算,卷积层的输出不会受太大影响。

  • 当需要检测输入特征中更广区域时,我们可以构建一个更深的卷积网络。

  • 填充可以增加输出的高度和宽度。这常用来使输出与输入具有相同的高和宽。

  • 步幅可以减小输出的高和宽,例如输出的高和宽仅为输入的高和宽的1/n1/nnn是一个大于11的整数)。

  • 填充和步幅可用于有效地调整数据的维度。

  • 多输入多输出通道可以用来扩展卷积层的模型。

  • 当以每像素为基础应用时,1×11\times 1卷积层相当于全连接层

  • 1×11\times 1卷积层通常用于调整网络层的通道数量和控制模型复杂性。

  • 对于给定输入元素,最大汇聚层会输出该窗口内的最大值平均汇聚层会输出该窗口内的平均值

  • 汇聚层的主要优点之一是减轻卷积层对位置的过度敏感

  • 我们可以指定汇聚层的填充和步幅

  • 使用最大汇聚层以及大于1的步幅,可减少空间维度(如高度和宽度)。

  • 汇聚层的输出通道数与输入通道数相同

  • 卷积神经网络(CNN)是一类使用卷积层的网络。

  • 在卷积神经网络中,我们组合使用卷积层、非线性激活函数和汇聚层

  • 为了构造高性能的卷积神经网络,我们通常对卷积层进行排列逐渐降低其表示的空间分辨率,同时增加通道数

  • 在传统的卷积神经网络中,卷积块编码得到的表征在输出之前需由一个或多个全连接层进行处理

  • LeNet是最早发布的卷积神经网络之一。


  1. 空间下采样是指在图像或特征图中减少样本点的数量,从而减小图像或特征图的尺寸。它是一种降低数据维度的方法,常用于计算机视觉和图像处理领域。空间下采样可以通过不同的操作来实现,其中最常见的方法是使用池化(pooling)操作。 ↩︎

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2023-2024 Guijie Wang
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信