使用卷积神经网络识别手写数字(理论篇一)

“识别手写数字” 在几天以前对我来讲仍是以为很厉害的一件事,或许这须要很高深的机器学习的算法?可是这几天看了一些关于神经网络的文章,才发现识别数字实际上是一个很简单的事情(固然这里指的是最基本的识别单个数字),甚至能够算是 计算机视觉(Computer Vison)的 “Hello World”。html

而在计算机视觉领域,卷积神经网络(Convolution Neural Networks)的出现引领了一场技术革命,它在图像识别方面能够说是大显身手。本文就基于卷积神经网络,对单个数字进行识别。git

概览

本质上来说,识别手写数字要作的事情是图像识别,无论图里面是数字也好,小猫小狗也好,实质上是同样的。咱们的输入是一张图片,输出是一个识别结果。github

与人类天生拥有的识别能力不一样,计算机只能读取一串串二进制数字。为何程序可以识别图片?这里并无什么浪漫色彩,不是由于计算机产生了智慧,而仅仅只是一系列数学公式起了做用。算法

设想咱们是如何分别一张照片是否有人脸的,虽然是一眼就能看出,但想象你才刚出生,为何你能知道照片里那个东西是我的脸,而不是别的东西?网络

实际上,咱们也是通过一步步训练而具有这种能力的。咱们首先会辨别,这里有没有一个头?头的左上角、右上角有没有一只眼睛?中间有没有一只鼻子?最后这些答案大部分都是 “有” 的状况下,咱们会得出结论:哦,这是一张脸。机器学习

而计算机也是同样的道理,它也能够经过判断一张脸的组成是否都存在来判断是不是一张脸。ide

因此它先辨别有没有一只眼睛,但它怎么知道这是否是眼睛?那由于眼睛由眼珠、眼白组成,他能够先辨别有没有眼珠。但它怎么知道这是否是眼珠?……函数

你可能已经明白了,这个问题能够一直细分下去,计算机最后能识别的是一个一个像素点。根据像素点的组成,计算机能够判断是不是一个眼睛,同理往上识别一张人脸。这实际上也就是卷积层划分的本质,咱们接下来会谈到。post

因此,识别其实也没有什么神奇的地方,能够说是数理统计的结果。不过,设计算法并无这么简单,一张图由数千数万的像素点组成,如何进行训练也是一个关键的问题。这就引出了卷积神经网络,咱们会先对图片进行扫描,而后进行压缩,最后才进行计算:学习

不要被上面的图吓到了,咱们识别手写数字也是同样的思路,但看完本文,你会发现它所作的事情其实并不复杂。

神经网络基础

提到卷积神经网络,就不得不先说一下 神经网络(Neural Networks)。我想即便没有研究过机器学习,大部分人对神经网络这个概念也不陌生,它借鉴了生物学上大脑的神经结构,抽象出了计算机领域的神经网络的模型。

一个简单的神经网络能够表示以下:

神经网络分为三个部分:输入层(Input Layer)、隐藏层(Hidden Layer)和 输出层(Output Layer)。层的个数和每层中节点的个数不是固定的,好比在上图的神经网络中只有一个隐藏层,而在实践中,根据场景不一样,隐藏层的数量也不尽相同。

每一层由若干个 感知器(perceptrons)组成,也就是图中的节点。感知器接收一些输入,而后产生一个输出。另外,输入层的感知器没有输入,他们分别做为了隐藏层的输入,在隐藏层中,每一个感知器进行计算,产出的输出分别做为了输出层的输入,最后经由输出层计算,产出最终结果。

显然,咱们能够把感知器看做一个函数:

output = f(x_1, x_2, x_3)

很幸运,这里的 f 很是简单,是一个线性函数。这里有三个输入,因此咱们再定义三个 权重(weight)w一、w二、w3 和一个 误差(bias)b,上式就能够表示为:

output = w_1 * x_1 + w_2 * x_2 + w_3 * x_3 + b

因此,能够简单理解上面提到的神经网络实际上就是进行以下的计算(这里省略了 Sigmoid 函数,以后再提到):

h1 = w_1 * x_1 + w_2 * x_2 + b_1 \\
h2 = w_3 * x_1 + w_4 * x_2 + b_2 \\
o1 = w_5 * h_1 + w_6 * h_2 + b_3

对于这个神经网络而言,训练集包含的是 x一、x2 对应的 o1 值,而咱们须要肯定的是 w1 到 w6 和 b1 到 b3 一共 9 个变量的值。由于肯定这 9 个值后,咱们就能根据任意的 x一、x2 来预测对应的 o1 了。

一开始,能够对这 9 个值进行随机赋值,而后直接开始训练。从输入到输出,这是一个 前向(forward)的过程,不过这样只是生成预测值。而根据预测值,咱们能够判断神经网络的预测值和真实值相差多少,而后利用 梯度降低 (Gradient Descent)、反向传播(Backward Propagation)从后往前来改变节点的权重和误差,这样实现一个 “学习” 的过程。

举一个简单的例子,咱们对吉他调音的时候,咱们首先弹一个音,调音器说 “音高了!”,因而咱们将旋钮顺时针扭一下而后再弹,调音器仍是说 “音高了!”,因而咱们再将旋钮顺时针扭一下,这时调音器说 “音低了!”,咱们再逆时针扭 …… 如此反复,最后获得旋钮的最佳位置。

这里调整的过程就是 梯度降低 的过程,能够参考 以前翻译的一篇文章

神经网络的入门推荐阅读 Machine Learning for Beginners: An Introduction to Neural Networks

卷积神经网络基础

简单讲,卷积神经网络是在神经网络上加入了 卷积层(Convolutional layers),卷积层由一些 滤波器(filter)组成,它对原始图像进行扫描,在扫描窗口内,与原始图像作内积(逐个元素相乘再求和)。这个操做就是所谓的 “卷积” 操做,也是卷积神经网络的名字来源。

卷积层

咱们的卷积神经网络的第一层就是卷积层,如上所述,它使用滤波器对图片进行扫描。

举个例子,假设图片是 4 * 4 尺寸,滤波器为 3 * 3,那么滤波器将扫描 4 次,产出一个 2 * 2 的矩阵。

原始图片和滤波器:

扫描过程以下:

想想这是在干什么?咱们说过图像识别实际上作的事情就是判断原始图像中是否存在目标物体的组成部分。这个滤波器实际上就是在作这件事情。

再假设滤波器的像素组成为:

那么当原始图像的窗口内有滤波器的图像时,卷积结果就会很大,反之就越小。实际上使用这个图片能够判断原始图片是否有一个老鼠的组成部分:

你也能想到,由于一只老鼠有不少特征,一个滤波器固然是不够的,因此在卷积层里,会有多个滤波器。每个滤波器扫描完生成一个图层,那么一共就有滤波器数量个图层。

咱们要识别的手写数字图片是 28 * 28 像素的,本文中将使用 8 个滤波器。因此卷积层的输入为 28 * 28 = 784 个,经由卷积层处理后,输出为 26 * 26 * 8 个节点。(3 * 3 的滤波器会使尺寸缩小一圈)

池化层

卷积神经网络的第二层称为 池化层(Pooling Layer),它用来下降卷积层输出的特征向量,同时改善结果(不易出现过拟合)。

常见的池化操做有 平均池化(Mean Pooling)和 最大池化(Max Pooling)。本文将使用最大池化。它实际上就是将上层的输入再经过 2 * 2 的滤波器扫描取最大值:

由于像素点之间的值其实是很是近的,咱们没有必要保留全部相邻的像素点,使用池化层处理后,像素点能显著减小,它的输出节点变为 13 * 13 * 8 个。

Softmax 层

Softmax 层是本文中的最后一层,它将神经网络的输出变成了一个几率分布。

这也是咱们在神经网络基础一节提到的实际使用公式计算的位置,Softmax 层输入的节点个数为 13 * 13 * 8 = 1352 个,输出节点个数为 10 个,因此咱们会有 1352 * 10 个权重,10 个误差,对十种可能性进行计算。它们分别表示原始图片是 0 - 9 的几率大小,其中的最大值所在位置就是神经网络预测的数字值:

p_0 = w_{(1,1)} * x_1 + w_{(1,2)} * x_2 + ... + w_{(1,1352)} * x_1352 + b_1 \\
p_1 = w_{(2,1)} * x_1 + w_{(2,2)} * x_2 + ... + w_{(2,1352)} * x_{1352} + b_2 \\
... \\
p_9 = w_{(10,1)} * x_1 + w_{(10,2)} * x_2 + ... + w_{(10,1352)} * x_{1352} + b_{10} \\

以上就是整个前向反馈的过程,通过这些实现后,神经网络就能够对一个图片进行预测,但如今只是瞎猜(由于没有任何学习的过程)。接下来须要使用反向传播对权重和误差进行调整,咱们下篇继续。

参考

相关文章
相关标签/搜索