Chapter1

使用神经网络辨识手写数字

人类的视觉系统是自然界的一大奇迹。试看如下的手写数列:

绝大多数人都能毫不费劲地认出这些数字是504192,而这会让人产生识别数字非常简单的错觉。人类大脑的每个半球都有初级视觉皮层,其中一个可以被记作V1,包含有1亿4千万的神经元以及它们之间数以百亿计的相互连接。何况人类的视觉系统不仅只有V1,而还包括其他所有的初级视觉皮层:V2,V3,V4和V5,逐步负责着不同复杂程度的图像处理。我们的大脑里有一台超级计算机,经过数亿年的进化,能够极好地适应理解视觉世界。辨识手写数字并不容易。相反,是我们人类对于眼睛看到的信息有惊人、令人惊奇的理解能力。何况几乎所有的工作都是在不被感知的情况下完成的。所以我们经常不能理解,我们视觉系统解决的问题究竟有多困难。

如果你尝试写一个计算机程序来识别如上的手写数列,那么视觉模式识别的难度显而易见。有些事情就是看着容易做着难。一个直觉就是,我们是如何识别形状的——“9这个数字在顶上有一个圆圈,然后在右下角有一条竖线”——这看起来并不能很好地用算法来描述。当你试图明确一些规则的时候,你很快地就会迷失在异常、意外和特殊情况的泥沼里。这看起来可让人绝望。

神经网络用一种完全不同的想法接近问题所在。就是提取大量的手写数字,作为训练样本,

然后创造一个能从这些样本中自主学习的系统。换一句话说,神经网络用样本自动生成识别手写数字所需要的规则。此外,随着样本数量的增加,神经网络能够学习有关手写字体的更多特征,从而提高它的识别精度。所以,虽然之前只展示了100个训练样本,我们也能通过使用更大的训练样本,创造一个更好的手写字体识别器。

在本章我们会写一个使用神经网络的计算机程序,用来学习并识别手写数字。这个程序的代码只有约74行长,并且没有使用特殊的神经网络库。但这个小程序能够在无人介入的前提下,以约96%的准确率识别手写数据。此外,在以后的章节我们会延伸更好的方法将准确率提高到99%+。事实上,最好的商业神经网络目前正因为其出色的表现,被银行业和邮政行业用于处理支票、辨识地址。

我们着重于手写字体识别,是因为一般地它是很棒的神经网络原型问题。作为一个原型它有着一个巨大优势:具有挑战性。识别手写数字既不容易,也不需要一个极端复杂或者计算量巨大的解决方法。此外,这也是一个发展更先进技术的好方向,比如深度学习。而且贯穿整本书之后,我们将又回到识别手写数字这个问题上来。在这本书之后的内容,我们将讨论计算机视觉里,究竟是如何将这些方法应用到不同问题上的。比如语音合成、自然语言处理及其他领域。

当然,如果本章的目的仅是写出一个识别数字的程序的话,那么它的篇幅将会短小许多。在这一路上,我们将延伸出许多关于神经网络的关键思想,包括最重要的两种人工神经元(感知机和Sigmoid神经元),还有神经网络的标准学习算法,随机梯度下降法。自始至终,我都会把精力放在解释为什么事情是这样发生的,以及打造你自己的神经网络直觉上。对比只说明基本的技巧,这需要一段冗长的讨论。但为了使自己的理解更加深刻,这是值得的。付诸努力之后,在本章节的最后我们将会理解什么是深度学习,以及它为何如此重要。

感知机

什么是神经网络?为了开篇,我会介绍一种叫作感知机的人造神经元。感知机是由科学家Frank RosenblattWarren McCullochWalter Pitts早期工作的启发下,于20世纪5060年代发明的。在今天,使用其他的人工神经元模型更为流行—在本书和多数现代的神经网络工作中,主要使用的人工神经元模型被称作Sigmoid神经元。我们很快就会讲到这个,但为了理解Sigmoid神经元的定义,以及它是如何被定义的,花一些时间来了解感知机是值得的。

所以感知机是如何工作的?一个感知机采用一组二值化数据作为输入,比如x1,x2,…,并输出一个01

例子里展示了这个感知机具有三个输入值,x1,x2,x3。一般地,感知机也可以有更多或者更少的输入值。Rosenblatt提出了一条简单的规则来产生输出。他使用权值(weights)w1,w2,…,一些实数来表示不同输入的重要性。这类神经元的输出,具体是0还是1,取决于输入值加权求和之后 ( )是大于,还是小于阈值(threshold value)。就和权值(weights)一样,阈值(threshold)也是一个实数,并是神经元的一个参数。将以上规则通过更严谨的代数形式表达出来就是:

这就是感知机工作的所有原理。

以上是最基础的数学模型。一种对感知机的理解就是,它是一种通过权衡输入进行决策的机器。让我举个例子,它可能不是一个现实的例子,但非常好理解。现在假设周末将至,而你听说在你的城市即将会举行一个奶酪节。你喜欢奶酪,并且正准备做决定去还是不去。你有可能对以下三个因素进行权衡,再做决定。

  1. 天气是否良好?

  2. 你的男/女票有打算陪你一起去吗?

  3. 这个奶酪节的公共交通方不方便?(假设你没有车)

我们用三个二值化变量x1,x2,x3代表这三个因素。令x1=1代表天气良好,x1=0代表天气很坏。相似的,x2=1代表有人陪你,x2=0代表你没人陪。再同样的,x3的值代表着交通状况是否方便。

现在,让我们假设你特别喜欢奶酪,喜欢到不管男/女票有没有兴趣陪你,如果能去奶酪节的话你都会非常开心。但你又非常、非常厌恶坏天气,而且天气一坏交通就特别不方便。你可以使用感知机来给这类决策建模。一种方法是赋予一个权值(weight)w1=6给天气,w2=2w3=2给其他的变量。w1的值越大,意味着天气对你的影响越大,远比男/女票去不去、公共交通是否邻近重要。

通过改变权值(weight)和阈值(threshold),我们能获得不同的决策模型。举个例子,假设我们将阈值(threshold)设为3。这样感知机就会作出选择,只要是好天气,或者交通良好并且男/女票愿意陪同的时候你就应该去参加奶酪节。换一句话说,这将变成一个不同的决策模型。调低阈值(threshold)意味着你更倾向于参加奶酪节。

显然地,感知机不是一个完整的人类决策模型。但这个例子揭示的是,感知机是如何通过对凭据施加权重,从而做出决策的。利用一个复杂的感知机网络作出十分精细的决策,似乎可行:

在这个网络里,第一列的感知机——我们将它们称作第一层感知机,通过对输入进行加权,做出三个非常简单的决策。那第二层感知机又是干什么的呢?这一层的每一个感知机,都把第一层感知机的输出作为自己的输入,通过进行加权做出自己的决策。这样的话,第二层的感知机就能相对第一层感知机,在更复杂和抽象的层次上进行决策。同理,第三层的感知机也能做出比上一层更复杂的决策。以此类推,一个多层感知机网络能够做出复杂而又巧妙的决策。

顺便的,我在定义感知机的时候说过它只有一个输出。然而在上图展示的网络中,感知机似乎具有很多个输出。事实上,感知机仍然只有一个输出,这些代表输出的箭头只是一种常见的表达方式,用来表示该感知机的输出被多个感知机用作输入。这比把图画成完全单输出的形式要简明一些。

让我们再简化一下感知机的描述。 ∑ j w j x j >threshold  这种表示方法繁琐而冗长,我们可以改变两种符号约定来简化它。首先我们将∑ j w j x j 写成点积的形式,令 w⋅x≡∑ j w j x j,其中w和x各自代表权值(weight)和输入(input)向量。接下来我们把阈值(threshold)移项到不等号的另一端,并且用感知机偏差 b≡−threshold  替换阈值。经过这样的处理,我们可以把感知机的逻辑用以下形式表达:

你可以把这个偏置看作是对神经元输出1难易程度的衡量。或者从生物学角度考虑,这个偏执是神经元激活的一个门槛。对于有着大偏置的神经元,激活它们使其输出1是非常容易的。但是如果这个偏置是一个很小的负数,那么激活它就是一件很苦难的事了。显然地,介绍偏置这个概念只是我们对神经元概念描述的一个小小的变动,但过一会我们会发现它能引入更简化的符号形式。正是出于这方面的考虑,在本书我们不是用阈值(threshold)这个概念,而是使用偏置(bias)。

我已经介绍了神经元是对凭据施加权重进行决策的一种方法。在另一个层面上,神经元可以用作基础逻辑运算单元。比如与逻辑 (AND)、或逻辑(OR)、与非逻辑(NAND)。举个例子,假设我们有一个二输入的神经元,且其权值均为-2,而偏置为3,则以下有这个神经元:

我们知道,此时如果输入00则能够得到输出1,因为(-2)*0+(-2)*0+3=3大于0。在这里,我用“*”号来描述显式乘法。同样的,我们输入01或者10时都能得到输出1。但是如果输入11则会得到输出0,因为(-2)*1+(-2)*1+3=-1小于0。至此我们发现,这个神经元其实就是一个与非门(NAND gate)!

这个与非门(NAND gate)的例子告诉我们,我们可以利用神经元来构造基础逻辑运算单元。事实上,我们利用神经元构造一个网络,来表示任意的逻辑运算。原因在于与非门(NAND Gate)对于逻辑运算来说具有最普遍的性质,我们可以利用与非门(NAND gate)构造任何逻辑运算。举个例子,我们可以用与非门(NAND gate)来构造一个2比特加法器(x1和x2)。这需要按位进行计算,x1⊕x2,当x1与x2均为1时,按照二进制加法,它们相加时就需要在进位位上加1。换言之进位位的值只是x1、x2按位计算的产物:

我们把所有的与非门(NAND gate)替换成二输入、权值(weight)均为-2、偏置为3的神经元,就能得到一个等效网络。以下就是等效后的网络,请注意我把等效右下角与非门的神经元稍微挪动了一下,不过仅仅是为了让图示的箭头更好画而已:

一个值得注意的地方是,最左侧神经元的输出被两次用作最下面神经元的输入。之前在定义神经元的时候,我没说过这种对单一神经元的二重输出是可以的。事实上,这不算啥事。如果我们真不允许这种情况,解决办法也很简单。我们可以把最下面那个神经元的输入权重从-2更改为-4,然后最左侧神经元的二重输出就能等效成一个单输出了。(如果这种说法你理解起来很困难,那你应该停下来好好琢磨这为什么是等效的。)作了以上改变之后,网络如下所示。未标示的权值均为-2,所有神经元的偏置都是3,其中一个神经元的输入权值是-4,具体如标记所示:

[译][待续]Chap1.Using neural nets to recognize handwritten digits的更多相关文章

  1. 使用神经网络识别手写数字Using neural nets to recognize handwritten digits

    The human visual system is one of the wonders of the world. Consider the following sequence of handw ...

  2. chapter1:using neural nets to recognize handwritten digits

    two important types of artificial neuron :the perceptron and the sigmoid neuron Perceptrons 感知机的输入个数 ...

  3. 使用CNN(convolutional neural nets)关键的一点是检测到的面部教程(四):学习率,学习潜能,dropout

    第七部分 让 学习率 和 学习潜能 随时间的变化 光训练就花了一个小时的时间.等结果并非一个令人心情愉快的事情.这一部分.我们将讨论将两个技巧结合让网络训练的更快! 直觉上的解决的方法是,開始训练时取 ...

  4. Machine Learning, Homework 9, Neural Nets

    Machine Learning, Homework 9, Neural NetsApril 15, 2019ContentsBoston Housing with a Single Layer an ...

  5. (zhuan) Using convolutional neural nets to detect facial keypoints tutorial

    Using convolutional neural nets to detect facial keypoints tutorial   this blog from: http://danieln ...

  6. 神经网络可以拟合任意函数的视觉证明A visual proof that neural nets can compute any function

    One of the most striking facts about neural networks is that they can compute any function at all. T ...

  7. A visual proof that neural nets can compute any function

    http://neuralnetworksanddeeplearning.com/chap4.html In essence, we're using our single-layer neural ...

  8. CS231n 2016 通关 第五、六章 Fully-Connected Neural Nets 作业

    要求:实现任意层数的NN. 每一层结构包含: 1.前向传播和反向传播函数:2.每一层计算的相关数值 cell 1 依旧是显示的初始设置 # As usual, a bit of setup impor ...

  9. neural network and deep learning笔记(1)

    neural network and deep learning 这本书看了陆陆续续看了好几遍了,但每次都会有不一样的收获. DL领域的paper日新月异.每天都会有非常多新的idea出来,我想.深入 ...

随机推荐

  1. hdu 1217

    判断通过货币的兑换能否获利,,最短路,这里是乘法,, #include<stdio.h> #include<string.h> double map[31][31],ans[3 ...

  2. 从零开始学C++之对象的使用(二):四种对象生存期和作用域、static 用法总结

    一.四种对象生存期和作用域 栈对象 隐含调用构造函数(程序中没有显式调用) 堆对象 隐含调用构造函数(程序中没有显式调用),要显式释放 全局对象.静态全局对象 全局对象的构造先于main函数 已初始化 ...

  3. php提供service总结---wsdl篇

    越来越多的架构偏向于面向接口和面向服务的设计了,当我们把抽象的落地变为实际的时候,我们感觉到了代码的厚度.而当我们把具体的业务再进一步抽象,我们就能发现藏在细节深处的回馈. php可以提供servic ...

  4. Struts入门(二) 配置文件的讲解

    上一章我们演示了Struts项目的搭建  可以看到里面有几个重要的配置文件  下面我们来说明一下这3个配置文件 1.web.xml 2.strtus.xml 3.struts.properties 1 ...

  5. 用浅/深拷贝、和HTML5方法解决js对象的引用的问题

    先来看一个例子 例一: var a=[1,2,3]; var b=a; b.push(4); alert(b);//1,2,3,4 alert(a);//1,2,3,4 var a=[1,2,3]; ...

  6. 标签<a>的注意事项1

    使用a标签时,其子元素可以为其他元素,但是不能包含<a>标签,否则会造成布局改变! 因此请尽量不要在a标签里放太多子元素,可以在外层套一个div,其他子元素放在a标签同级下. 正确布局: ...

  7. WIN10使用管理员权限运行VS2013

    学习WCF时出现报错-- 其他信息: HTTP 无法注册 URL http://+:8083/User/.进程不具有此命名空间的访问权限(有关详细信息,请参见 http://go.microsoft. ...

  8. VC 2008 Express下安装OpenCV2.3.1

    VC 2008 Express下安装OpenCV2.3.1   注意: 下列文档以VC2008 Express为例,VC2010下的配置应与本文档类似. VC 6.0不被OpenCV 2.3.1支持. ...

  9. eclipse中svn提交过滤不需要的文件

    eclipse>Preference>Team>Ignored Resource 添加   .settings   .classpath   .project

  10. Noip 2016

    Day1 思路: 大致是 把一个环拆成链, 找某个人无非是向右找或向左找(即对当前点加或减) 若加上要移动的位置后坐标大于总人数, 就把当前坐标减去总人数, 若减去要移动的位置后坐标小于0, 就把当前 ...