1 Yann LeCun和手写数字识别

本文最后更新于:2023年9月6日 晚上

1 卷积操作的提出

在LeCun提出卷积神经网络之前,学者们早已开始用MLP来进行各种测试了。但至少在当时,对于图像数据处理和语音识别任务,MLP表现的并不好。

1.1 MLP用在图像处理上

怎么把图像输入到MLP上面去?答案很简单,把像素作为数据输入就行了,以防各位对于数字图像不太了解,我们简单回顾下计算机到底怎样存储图像。

我们暂且用II来表示一个图像,因为它是图像的英文单词Image的首字母,一张图像(黑白)是一个由亮度数值组成的矩阵。

I=Im×nI = I^{m\times n}

矩阵中的每一个元素就称之为像素,而元素的值----亮度数值,指的是这个像素的亮度等级如何。具体来说,我们是这样定义的:0代表着纯黑色,代表着最暗。想象以下晚上睡觉你拉上窗帘,关掉灯光,此时你看到的画面是不是和黑色接近。255代表着纯白色,代表着最亮。当你一不小心被正午的太阳直射眼睛的时候,如果你还记得太阳中心的颜色,那一定是纯白色。而介于0到255之间的数值就是各种灰色。

一张高清图片,分辨率是1920×10801920\times 1080,那么在计算机中就是一个矩阵I1920×1080I^{1920\times 1080}

如果图片是彩色的,那么这个矩阵就会有一些不同,具体来说,矩阵会变为

I=Im×n×cI = I^{m\times n\times c}

你可以想象成一个矩阵中的每个元素都是一个维度为cc的向量,

I=[αij],  αijdimRcI = [\alpha_{ij}],\ \ \alpha_{ij} \in \dim R^c

这个向量一般是三维的,分别代表着红,蓝,绿,这在美术上称为三原色,组合这三种颜色,我们可以创造出无穷多的色彩。但就我们一般研究的8位图像来说,向量每个元素的值的范围是[0,255][0, 255],因为28=2562^8 = 256.

让我们回到刚才的问题中来,我们现在的任务不过是将一个二维的矩阵送入MLP,由于现在还在LeCun做手写数字识别的时代,先暂且不考虑彩色图像。那么我们可以将矩阵每个元素都对应一个神经元进行输入。

I=[a11a12a1na21a22a2nam1am2amn]I = \begin{bmatrix} a_{11} & a_{12} & \cdots & a_{1n} \\ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & & \vdots \\ a_{m1} & a_{m2} & \cdots & a_{mn} \end{bmatrix}

即将a11,a12,,amna_{11},a_{12},\dots,a_{mn}m×nm\times n个数据直接送进MLP。在编程实现上,我们一般是将矩阵拍扁,例如在Pytorch中使用nn.Flatten(),矩阵I就会变为

I[a11,,a1n,a21,,a2n,,am1,amn]I \rightarrow [a_{11},\dots,a_{1n},a_{21},\dots,a_{2n},\dots,a_{m1},a_{mn}]

被直接拍扁成为一个向量。

但就像之前提到的一样,这样做的效果并不好。

1.2 传统的数字图像处理与MLP结合

“特征是最重要的”,这是数字图像处理领域的一句名言。什么是图像的特征?对于一般性的任务而言,它是边缘,转角等等信息,这些也叫做elementary features(初级特征),比如说,数字11在靠近上端的部分有个大约为7575^\circ的转角,那么这就是它的特征。

在神经网络流行之前,数字图像处理都是用手动提取的方式去分析这些特征,图像处理的算法应该提取出对任务最有用的特征并消去那些不想关的特征,得到一系列的特征向量。然后,把特征向量送进MLP中进行学习。这时候MLP是作为特征的分类器。

这样的方法出来的效果比把整张图片直接拍扁丢进MLP的效果要好一些。

于是LeCun就想,能不能设计一个特征提取器,能够自动地学习如何从图像中提取和任务相关的信息。当然,我们已经知道了,MLP提取特征是不太行的。

1.3 为什么MLP不行?

首先,图像数据不同于其它数据,它非常的大。比如一张能糊成马赛克的图片,分辨率可以是28×2828\times 28,这也有784个输入。就算MLP第一层只有一百来个神经元,那也有多余一万个权重。如果继续往深堆叠,参数会变得更大。这在LeCun时代是肯定走不通的,因为那时候没有GPU加速,训练神经网络非常慢。而且也没有大型数据集,现如今的开源数据集,例如ImageNet,有多达1400万张图片。而那时候可能几百上千张图就已经是极限了。硬件限制很大。由于数据少,参数量又很多,这还会导致过拟合的问题。

其次,图像数据是可能变形失真的。例如我可以让数字11不在图像中间,让它偏左一点,但就是这小小的变化可能难倒一个训练好的MLP。试想MLP已经记住了特征的位置,那么当特征移动的时候,原来位置的神经元就看不到特征了。用专业的术语来说,MLP不具备平移不变性。当然,你可以用足够多的神经元来训练网络对这种变化的稳健性,但这可能导致很多神经元在不同区域有完全相同的权重模式。而且如果真的要这么做,你应该有巨量的样本来覆盖所有可能发生的变化。

最后,直接拍扁一个图像矩阵完全忽略了输入信息的拓扑结构。图像有非常强的局部结构,比如一个像素的邻近像素是高度相关的,一张图片中草地部分的像素周围大概率都是草的像素。所以我们应该利用这样的二维的局部特征结构,MLP则没有这个能力。

1.4 卷积操作

在讲解卷积操作之前,我想有必要再说一下什么是感受野。对于输入神经元来说,神经元“看到”的部分就是感受野。比如把图片送入MLP,那么输入层神经元是同时看到整个输入图像的,那么MLP的感受野就是整张图。

LeCun考虑了这三个问题,他认为设计出的特征提取器应该有这三个特点

  1. 局部感受野:因为图像有很强的局部结构和局部特征,所以应该有局部感受野,在局部上进行特征提取和识别,而并非看整张图。
  2. 共享权重:为了减少神经元的数量,输入的图像应该共享神经元的权重,比如第零个像素和第三个像素可能连接的是同一个神经元。而共享权重也能解决平移不变性的问题,因为对于不同区域神经网络的权重相同,那么就算特征位置发生了变化,提取器也能识别到特征。
  3. 下采样:为了消去与任务无关的特征,例如噪声,失真等等,以及为了减少推理过程中的计算量,可以将提取到的特征进行进一步压缩,只保留最关键最重要的特征。

同时满足这三点,而且要保留图像的二维拓扑结构,LeCun提出了这样的一个算子,我们用一个具体例子来说明它是怎样运算的。

考虑一个图像I

I=[113221241]I = \begin{bmatrix} 1 & 1 & 3 \\ 2 & 2 & 1 \\ 2 & 4 & 1 \\ \end{bmatrix}

我知道这个图像是没有意义的,它不是数字,也不是花花草草。但为了举例,我们就随便写一个3×33\times 3的矩阵。

现在给出一个矩阵K

K=[2182]K = \begin{bmatrix} 2 & 1 \\ 8 & 2 \end{bmatrix}

卷积操作表现如下

  1. 将K与I的左上角对齐,想象K重叠在I上面,然后重叠部分的元素相乘相加

    2×1+1×1+8×2+2×2=232\times 1+1\times 1+8\times 2+2\times 2 = 23

  2. 将K往右移一个元素,这时与[1321]\begin{bmatrix} 1 & 3 \\ 2 & 1\end{bmatrix}重叠,继续刚才的操作,重叠部分相乘相加

    1×2+3×1+2×8+1×2=231\times 2+3\times 1+2\times 8+1\times 2 = 23

  3. 此时已经移动到矩阵I的最右边了,则K往下移动一个元素,并从最左边开始继续重复刚才的操作,此时与[2224]\begin{bmatrix} 2 & 2 \\ 2 & 4\end{bmatrix}重叠

    2×2+1×2+2×8+2×4=302\times 2+1\times 2+2\times 8+2\times 4 = 30

  4. 继续往右移一个元素,这时候与[2141]\begin{bmatrix} 2 & 1 \\ 4 & 1\end{bmatrix}重叠,重复刚才的操作

    2×2+1×1+4×8+2×1=392\times 2+1\times 1+4\times 8+2\times 1 = 39

  5. 这个时候已经在整个图像上都移动了一遍,我们从左上角来到了右下角,卷积操作就完成了,而刚才重叠运算的结果形成了一个新矩阵

    f=[23233039]f = \begin{bmatrix} 23 & 23 \\ 30 & 39 \end{bmatrix}

    这个矩阵被称作特征图(feature map)。

这就是卷积操作,矩阵K被称作卷积核,它作为一个算子在图像上滑动进行运算,直到从左上角滑动到右下角,看完整张图片。而矩阵元素与元素相乘的操作叫做Hadamard积。
定义Hadamard积:给出矩阵A=[aij]A = [a_{ij}], B=[bij]B = [b_{ij}], 则C=[aijbij]C = [a_{ij}b_{ij}]是Hadamard积的结果,记作ABA\circ B

卷积操作对于局部像素的运算是Hadamard积后的矩阵做逐元素求和。

i,jAB\sum_{i,j} A\circ B

我们很容易把卷积运算推广到任意图像和任意卷积核上,给出图像II和卷积核KK,那么卷积就是K从I的左上角开始运算到右下角,然后得到一个新的矩阵----特征图。

那它满足了最开始我们提出的三个要求了吗?显然是满足了的。
首先,卷积核的大小小于图像,它做运算的时候看的是一部分的像素,所以具有局部感受野。其次,卷积核完成一个局部的运算后会滑动到下一个位置,那么不同的输入是公用一个卷积核的,也就是权重被共享,所以第二条也满足。第三条你也许会理解成卷积过后得到的特征图比原始输入的图像小,所以是下采样。但其实并非这样,下采样是单独的一个运算,我们将在后面提到。

但如果你仔细观察这个操作,它其实有很多可以调整的地方,例如

  1. 为什么滑动总是滑动一步,我可以一次滑动两个元素吗?
  2. 卷积核为什么是2×22\times 2大小的,我可以改变卷积核大小吗?

这些问题将在后面得到解答,就目前来看,LeCun提出的卷积方法满足要求。你也许会注意到卷积运算导致的图像大小变化问题,那是否有公式可以计算出卷积后得到的特征图的大小?其实是有的,卷积运算后的矩阵大小由以下公式计算:


1 Yann LeCun和手写数字识别
https://jesseprince.github.io/2023/04/22/convnets/basics/basic_of_conv/
作者
林正
发布于
2023年4月22日
许可协议