本案例演示了如何训练简单的卷积神经网络(CNN)来对MNIST数字进行分类。这个简单的网络将在MNIST测试集上实现99%以上的准确率。
当我们学习编程的时候,编写的第一个程序一般是实现打印"Hello World"。而机器学习(或深度学习)的入门教程,一般都是 MNIST 数据库上的手写识别问题。原因是手写识别属于典型的图像分类问题,比较简单,同时MNIST数据集也很完备。MNIST数据集作为一个简单的计算机视觉数据集,包含一系列如下图1所示的手写数字图片和对应的标签。图片是28x28的像素矩阵,标签则对应着0~9的10个数字。每张图片都经过了大小归一化和居中处理。
本案例中,从简单的Softmax回归模型开始,了解手写字符识别,并改进模型,利用多层感知机(MLP)和卷积神经网络(CNN)优化识别效果。
基于MNIST数据集训练一个分类器,在介绍本案例使用的三个基本图像分类网络前,我们先给出一些定义:
X X X是输入:MNIST图片是 28 × 28 28\times28 28×28 的二维图像,为了进行计算,我们将其转化为 784 784 784维向量,即 X = ( x 0 , x 1 , … , x 783 ) X=\left ( x_0, x_1, \dots, x_{783} \right ) X=(x0,x1,…,x783)。
Y Y Y是输出:分类器的输出是10类数字(0-9),即 Y = ( y 0 , y 1 , … , y 9 ) Y=\left ( y_0, y_1, \dots, y_9 \right ) Y=(y0,y1,…,y9),每一维 y i y_i yi代表图片分类为第 i i i类数字的概率。
L a b e l Label Label是图片的真实标签: L a b e l = ( l 0 , l 1 , … , l 9 ) Label=\left ( l_0, l_1, \dots, l_9 \right ) Label=(l0,l1,…,l9)也是10维,但只有一维为1,其他都为0。例如某张图片上的数字为2,则它的标签为 ( 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) (0,0,1,0,0,0,0,0,0,0) (0,0,1,0,0,0,0,0,0,0)
最简单的Softmax回归模型是先将输入层经过一个全连接层得到特征,然后直接通过 softmax 函数计算多个类别的概率并输出[9]。
输入层的数据 X X X传到输出层,在激活操作之前,会乘以相应的权重 W W W ,并加上偏置变量 b b b ,具体如下:
y i = softmax ( ∑ j W i , j x j + b i ) y_i = \text{softmax}(\sum_j W_{i,j}x_j + b_i) yi=softmax(j∑Wi,jxj+bi)
图2为softmax回归的网络图,图中权重用蓝线表示、偏置用红线表示、+1代表偏置参数的系数为1。
图2. softmax回归网络结构图
对于有 N N N 个类别的多分类问题,指定 N N N 个输出节点, N N N 维结果向量经过softmax将归一化为 N N N 个[0,1]范围内的实数值,分别表示该样本属于这 N N N 个类别的概率。此处的 y i y_i yi 即对应该图片为数字 i i i 的预测概率。
在分类问题中,我们一般采用交叉熵代价损失函数(cross entropy loss),公式如下:
L c r o s s − e n t r o p y ( l a b e l , y ) = − ∑ i l a b e l i l o g ( y i ) L_{cross-entropy}(label, y) = -\sum_i label_ilog(y_i) Lcross−entropy(label,y)=−i∑labelilog(yi)
Softmax回归模型采用了最简单的两层神经网络,即只有输入层和输出层,因此其拟合能力有限。为了达到更好的识别效果,我们考虑在输入层和输出层中间加上若干个隐藏层[10]。
图3为多层感知器的网络结构图,图中权重用蓝线表示、偏置用红线表示、+1代表偏置参数的系数为1。
图3. 多层感知器网络结构图
在多层感知器模型中,将图像展开成一维向量输入到网络中,忽略了图像的位置和结构信息,而卷积神经网络能够更好的利用图像的结构信息。LeNet-5是一个较简单的卷积神经网络。图4显示了其结构:输入的二维图像,先经过两次卷积层到池化层,再经过全连接层,最后使用softmax分类作为输出层。下面我们主要介绍卷积层和池化层。
图4. LeNet-5卷积神经网络结构
卷积层是卷积神经网络的核心基石。在图像识别里我们提到的卷积是二维卷积,即离散二维滤波器(也称作卷积核)与二维图像做卷积操作,简单的讲是二维滤波器滑动到二维图像上所有位置,并在每个位置上与该像素点及其领域像素点做内积。卷积操作被广泛应用与图像处理领域,不同卷积核可以提取不同的特征,例如边沿、线性、角等特征。在深层卷积神经网络中,通过卷积操作可以提取出图像低级到复杂的特征。
图5. 卷积层图片
图5给出一个卷积计算过程的示例图,输入图像大小为 H = 5 , W = 5 , D = 3 H=5,W=5,D=3 H=5,W=5,D=3,即 5 × 5 5 \times 5 5×5大小的3通道(RGB,也称作深度)彩色图像。
这个示例图中包含两(用 K K K表示)组卷积核,即图中 F i l t e r W 0 Filter W_0 FilterW0 和 F i l t e r W 1 Filter W_1 FilterW1。在卷积计算中,通常对不同的输入通道采用不同的卷积核,如图示例中每组卷积核包含( D = 3 ) D=3) D=3)个 3 × 3 3 \times 3 3×3(用 F × F F \times F F×F表示)大小的卷积核。另外,这个示例中卷积核在图像的水平方向( W W W方向)和垂直方向( H H H方向)的滑动步长为2(用 S S S表示);对输入图像周围各填充1(用 P P P表示)个0,即图中输入层原始数据为蓝色部分,灰色部分是进行了大小为1的扩展,用0来进行扩展。经过卷积操作得到输出为 3 × 3 × 2 3 \times 3 \times 2 3×3×2(用 H o × W o × K H_{o} \times W_{o} \times K Ho×Wo×K表示)大小的特征图,即 3 × 3 3 \times 3 3×3大小的2通道特征图,其中 H o H_o Ho计算公式为: H o = ( H − F + 2 × P ) / S + 1 H_o = (H - F + 2 \times P)/S + 1 Ho=(H−F+2×P)/S+1, W o W_o Wo同理。 而输出特征图中的每个像素,是每组滤波器与输入图像每个特征图的内积再求和,再加上偏置 b o b_o bo,偏置通常对于每个输出特征图是共享的。输出特征图 o [ : , : , 0 ] o[:,:,0] o[:,:,0]中的最后一个 − 2 -2 −2计算如图5右下角公式所示。
在卷积操作中卷积核是可学习的参数,经过上面示例介绍,每层卷积的参数大小为 D × F × F × K D \times F \times F \times K D×F×F×K。在多层感知器模型中,神经元通常是全部连接,参数较多。而卷积层的参数较少,这也是由卷积层的主要特性即局部连接和共享权重所决定。
局部连接:每个神经元仅与输入神经元的一块区域连接,这块局部区域称作感受野(receptive field)。在图像卷积操作中,即神经元在空间维度(spatial dimension,即上图示例H和W所在的平面)是局部连接,但在深度上是全部连接。对于二维图像本身而言,也是局部像素关联较强。这种局部连接保证了学习后的过滤器能够对于局部的输入特征有最强的响应。局部连接的思想,也是受启发于生物学里面的视觉系统结构,视觉皮层的神经元就是局部接受信息的。
权重共享:计算同一个深度切片的神经元时采用的滤波器是共享的。例如图4中计算 o [ : , : , 0 ] o[:,:,0] o[:,:,0]的每个每个神经元的滤波器均相同,都为 W 0 W_0 W0,这样可以很大程度上减少参数。共享权重在一定程度上讲是有意义的,例如图片的底层边缘特征与特征在图中的具体位置无关。但是在一些场景中是无意的,比如输入的图片是人脸,眼睛和头发位于不同的位置,希望在不同的位置学到不同的特征 (参考斯坦福大学公开课)。请注意权重只是对于同一深度切片的神经元是共享的,在卷积层,通常采用多组卷积核提取不同特征,即对应不同深度切片的特征,不同深度切片的神经元权重是不共享。另外,偏重对同一深度切片的所有神经元都是共享的。
通过介绍卷积计算过程及其特性,可以看出卷积是线性操作,并具有平移不变性(shift-invariant),平移不变性即在图像每个位置执行相同的操作。卷积层的局部连接和权重共享使得需要学习的参数大大减小,这样也有利于训练较大卷积神经网络。
关于卷积的更多内容可参考阅读。
图6. 池化层图片
池化是非线性下采样的一种形式,主要作用是通过减少网络的参数来减小计算量,并且能够在一定程度上控制过拟合。通常在卷积层的后面会加上一个池化层。池化包括最大池化、平均池化等。其中最大池化是用不重叠的矩形框将输入层分成不同的区域,对于每个矩形框的数取最大值作为输出层,如图6所示。
更详细的关于卷积神经网络的具体知识可以参考斯坦福大学公开课、Ufldl 和 图像分类教程。
性别: [0, 1] 表示女 [1, 0] 表示男
独热编码的优点在于:
1、能够处理非连续型数据的特征
2、在一定程度上扩充了特征
3、在神经网络中,独热编码其实具有很强的容错性。
[0, 0.1, 0.2, 0.7, 0, 0, 0, 0, 0, 0] 表示数字3
[0, 0.4, 0.6, 0.8, 0, 0, 0, 0, 0, 0] 表示数字3