AI技术百科
神经网络和深度学习: 一 使用神经网络识别手写数字
前言:
这一系列主要翻译自neural networks and deep learning 这本电子书,之所以决定翻译这本书,是因为我觉得这本书将视觉领域的深度学习的理论方面讲得非常透彻,也希望大家也可以从中学到很多。
人类的视觉系统是世界上的一大奇迹,考虑下面一串手写数字:
大多数人可以毫不费力地识别这串数字为504192。这种“貌不费力”具有欺骗性。在人类的每个大脑半球
有一个初级视觉皮层(primary visual cortex), 称之为V1,包含了1.4亿个神经元,在神经元之间有百亿数量级的连接。而且人类的大脑不仅有V1, 还有V2, V3,V4及V5视皮层,可以处理更加复杂的图像识别任务。人类的大脑可以看成是一个超级电脑,经过几千万年的进化,已经非常好地适应了外界的视觉环境。手写数字识别并不是一个简单的任务,但是人类却非常善于理解我们眼睛看到的事物。由于所有的过程都是无意识的,所以我们通常并不惊叹于我们视觉系统的这种能力。
如果你试着写一个程序来识别手写数字,那么这个任务的难度就会变得很显然。一个简单的直觉是识别不同数字特有的形状。比如: “9” 上面有一个圈,下面是一个勾。但是,这些形状非常难于使用算法来表示。而且,当你试着使用算法来实现时,你会迷失在各种不同的形状海洋中,这会让你觉得这个任务似乎无法完成。
神经网络使用另外一种方法来解决这个问题。它使用很多手写数字作为训练数据集,如下所示:
然后我们开发一个系统从这些训练数据集来学习识别这些数字。也就是说,神经网络可以使用这些例子来自动推断识别不同手写数字的内在规则。而且,通过增加训练的例子,神经网络可以学习到更多,从而提高准确度。所以通常训练例子不只是上面的100个,可能有成千上万个。
在这一章,我们将写一个学习识别手写数字的神经网络程序。这个程序只有74行,没有使用任何神经网络的库。但是这个简短的程序识别手写数字的准确度可以达到96%。而且,在后面的章节中,我们将加入另外一些想法,将识别准确度提高到99%。实际上,商业的神经网络已经工作地非常好,以至于它们已经被银行用于处理支票,邮局用于识别地址。
我们使用手写数字作为例子,是因为它是一个学习神经网络非常好的例子。而且在这个基础上,可以开发更加先进的技术,比如深度学习。所以,在这本书中,我会反复地提及识别手写数字的例子。在这本书的后半部分,我们还会讨论这些想法是如何应用到其他计算机视觉任务中,以及语音,自然语言处理等其他领域当中。
当然,如果这一章的重点只在于如何写出一个计算机程序来识别手写数字的话,那么这一章会变得非常短。所以,在介绍这个程序的过程中,我还会介绍很多神经网络的重要思想,包括两种非常重要的人工神经元(感知机及sigmoid神经元)及神经网络的一般学习算法:随机梯度下降。在整本书中,我会关注于解释 为什么 要这样做以及建立神经网络的一些直觉。这会比只介绍神经网络的机制花费更长的内容。但是这些更深层次的理解是非常值得的。当你读完这一章后,你会理解深度学习是什么 以及 为什么它会如此重要。
感知机
在介绍神经网络之前, 首先我会介绍一种人工神经元,称之为 感知机(perceptron)。感知机在1950~1960间由科学家 Frank Rosenblatt提出,他受 Warren McCulloch 和 Walter Pitts 早期工作的启发。在现代,我们更多地是使用其他的人工神经元,其中一个重要的神经元是sigmoid神经元。我们马上会谈到sigmoid神经元。但是为了理解为什么sigmoid神经元,我们需要首先需要花点时间来理解感知机。
那么,感知机是如何工作的呢?一个感知机包括几个二元输入, , 并产生一个二元输出,如下图所示:
一个简单的感知机示意图
上图的感知机有三个输入: 。输入的个数可以更多或更少。Rosenblatt 提出了一个简单的规则来计算输出。他引入了权重值 , 这些实数表达了不同输入的重要性。感知机的输出为0或1,由 是否大于某个 阈值 决定。与权重一样,阈值也是一个需要设置的实数参数。使用数学表达式可以表示为:
这是感知机工作原理的全部。
这是基本的数学模型。我们可以将感知机看做是通过权衡不同因素来做决策的设备。举一个不太真实却非常容易理解的例子。假设周末快要来临,你听说在你的城市在周末会举行奶酪节。你非常喜欢奶酪,所以你现在需要决定周末是否过去。你通过权衡三个因素来决定是否去参加:
天气好不好?
你的女(男)朋友是否愿意陪你去?
去奶酪节是否交通方便?
我们将这三个因素表示为 。如果天气非常好, 则 ;反之 。同样地,如果你女(男)朋友愿意陪你去,那么 ; 反之 。最后一个因素也类似。
现在,假设你非常喜欢奶酪,以至于如果你的女(男)朋友不陪你去或交通不便,你也非常乐意去参加。但是如果是坏天气的话,你可能会选择不去。你可以使用感知机来模拟这个决策过程。一种方式是将天气的权重 设为6, 其他两个因素的权重都设为2。 的值偏大,说明相对于后两者,天气因素对你决策更重要。最后,将感知机的阈值设为5。通过这些设定,感知机就可以实现决策模型,当天气好的时候,不管其他因素如何,你都会选择去;反之,如果天气不好,那么无论如何你都会选择不去。
通过改变权重值及阈值,我们可以得到不同的决策模型。比如,假设我们将阈值设为3, 那么,当天气好或者后两个条件满足时,你会选择去奶酪节。减少阈值意味着你自己想去奶酪节的想法就越强烈。
当然,奶酪节并不是一个完整人类决策模型。但是这个例子表明一个感知机如何通过权衡不同的因素来做出决策。所以,通过构建一个感知机网络能够更精准地模拟决策的过程。如下图所示:
在上面的网络中,第一列的感知机-我们称之为第一层感知机-通过权衡不同的输入因素,做了三个非常简单的决策,对于网络中的第二层,每个感知机通过权衡第一层的结果来做出决定,通过这种方法,第二层的感知机能够做出更加复杂及抽象的决策,而第三层的感知机在第二层输出的基础上,会做出更加复杂及抽象的决策。这样,一个多层的感知机网络就可以模拟一个复杂的决策过程了。
当我定义感知机的时候,我说过感知机只有一个输出,但是在上面的网络中,感知机似乎有多个输出。实际上,感知机还是只有一个输出,只不过一个输出被后面一层多个感知机使用。
下面让我们来简化感知机的描述方式。条件 有点繁琐,我们将从两个方面来简化它。首先,将 简化为 ,其中 都是向量。第二个改变是将threshold 移到不等式的左边, 并用 偏置值(bias) 替代,即 。通过以上两个方面的改进,感知机的公式可以重写为:
你可以将偏置值看成是感知机输出1的容易程度。或者用生物学的术语,偏置值可以测量感知机 激活 的容易程度。如果一个感知机有较大的偏置值,那么它会比较容易输出1。在后面的章节,我们会进一步简化这个公式。在后面的章节中,我们不再使用阈值,都会使用偏置值。
我已经介绍了感知机如何通过权衡不同因素来模型人类的决策行为,我们还可以使用感知机来计算基本的逻辑函数
,比如 AND, OR, NAND等。比如,假设我们有一个 两个输入 的感知机,每个输入的权重都为-2,偏置值为3。感知机的示意图如下:
当两个输入为00, 01,或10时, 感知机的输出都为1;而当输入为11时,感知机的输出为0。所以这个感知机实现了 NAND 门。
这个 NAND 例子表明我们可以使用感知机来计算简单的逻辑函数。 实际上,我们可以使用感知机计算任何逻辑函数,因为NAND门是一个基础的逻辑门,比如,我们可以使用 NAND 门来构建一个实现位加运算的电路。对于输入 , 我们需要计算逐位和 和只有当两个输入都为1时才输出1的进位运算,位加运算的电路图如下所示:
为了得到对应的感知机网络,我们将 NAND 门替换为对应的感知机,结果如下图所示:
上图还可以进一步简化,我们可以看到,最左边的感知机与最下面的感知机之间由两个连接,我们可以将这两个连接合成一个连接,并将权重改变为-4。简化的示意图如下所示:
到现在为止,我们都是使用符号 等表示输入。其实,一个通常的做法是将输入也用一层感知机表示,称之为输入层(但输入层中的感知机符号并不是真正的感知机,因为它没有权重和偏置值这些参数,应该把它看成是一种特殊的单元)。于是,位加的感知机网络如下图所示:
这个位加操作的例子说明感知机网络可以通过模拟 NAND 门来模拟各种其他的计算操作。但是感知机网络还可以做得更多。我们可以通过引入 学习算法,从而可以自动调节神经网络的权重值及偏置值。这种方法与模拟逻辑门完全不同,因为模拟逻辑门需要我们预先设定权重值及偏置值,但是神经网络可以通过学习,自动调节网络中的参数,从而可以解决更加复杂的问题。
Sigmoid 神经元
学习算法听起来有点难以设计,如何才能为神经网络设计这样一个算法呢?假设我们现在有一个感知机网络来识别手写数字,输入为手写数字的原始像素值。我们希望这个网络能够自己学习权重值和偏置值,将图像中的数字分类。为了理解神经网络是如何工作的,假设我们稍微改变感知机网络中某个神经元的权重(偏置)值,我们期望这个小改变能够导致神经网络输出的一个小改变。我们马上就会明白,就是这种性质,使得学习成为可能。
如果网络中权重(偏置)值的小改变能够导致网络输出的小改变,那么我们可以通过改变网络中的参数,使得网络的输出能够如我们所愿。比如,一个网络错把 “9” 分类成“8”, 我们可以找到一种方法,改变网络的参数值,使得网络能够更加倾向于把这张图片分类成“9”。通过重复这个操作,神经网络就会越来越将这张图片分类成“9”, 从而这个网络就可以学习了。
但是如果我们网络中的神经元为感知机时,却无法做到。实际上,权重值或偏置值的一个小改变可能会彻底改变网络的输出,比如从0改变为1。这种“大”改变可能会导致剩余的网络发生无法预料的变化。所以,尽管在某个时刻你的网络可以正确识别书写数字“9”,但是其他的图片会以一种不可控制的方式彻底地改变着网络,这会使得网络很难通过慢慢改变权重值及偏置值使得网络能够变得更接近我们的目标。也许有更聪明的方式来解决这个问题。
我们通过引入一个新的人工神经元-sigmoid神经元-来解决这个问题。sigmoid神经元和感知机类似,但是在sigmoid神经元中,参数微小的变化会导致神经元输出的微小改变。这就是sigmoid神经元能够学习的关键。
下面我们来描述下sigmoid神经元, sigmoid神经元与感知机非常类似,其结构如下图所示:
和感知机一样,sigmoid神经元也有输入 , 但是与感知机不一样,sigmoid神经元的输入不是二元的,而是实数输入,是一个0~1范围内的实数。和感知机一样,sigmoid神经元也有权重 以及偏置值。与感知机不同,sigmoid神经元的输出不是0或1,而是 ,其中 表示sigmoid函数
。有时候, 也称之为 logistic 函数,sigmoid神经元也称之为 logistic神经元
。记住这些术语非常重要,因为这些术语被很多使用神经网络的科学家使用。然而,我们还是使用sigmoid这个术语,它的计算公式为:
对于一个sigmoid神经元来说,假设其输入为 , 其权重为 ,偏置值为 , 那么sigmoid 神经元
的计算公式为:
乍一看,感知机与sigmoid神经元有非常大的不同,如果你不熟悉sigmoid函数,你会觉得这个公式非常复杂。实际上,这两种神经元非常类似。为了理解这两种神经元的相似性,假设 是个非常大的正数。那么我们可以计算出 ,和感知机的结果一样。如果 是一个非常小的负数,那么 。这也和感知机的结果非常类似,当 的是不大不小时, 就是一个0~1之间的值。
我们怎么理解 的数学形式呢?其实,它的数学形式并不是很重要,重要的是函数的几何形状,sigmoid的形状如下所示:
是阶梯函数(step function)的光滑版本:
如果 是一个阶梯函数,那么sigmoid神经元就变成了一个感知机。所以sigmoid神经元可以看成是一个光滑版本的感知机。 的光滑性非常重要,因为这种光滑性意味着权重值或偏置值小的改变只能引起神经元输出的小的变化。下面从数学的角度进行描述。微积分的知识告诉我们,sigmoid神经元的输出变化可以近似为:
其中 和 分别表示输出对 和 的偏导数。如果你对偏导数不熟悉,也不同紧张,尽管这个式子看起来非常复杂,但是它告诉了我们一个好消息:sigmoid神经元的输出改变量 可以近似为权重的改变值 和偏置值的改变值 的线性组合。这种线性关系可以保证当权重值或偏置值微小的改变也只能导致神经元输出的微小改变,这也使得学习成为可能。
如果真正重要的是 的几何形状,而不是它的具体数学表达形式,那么我们为什么使用公式(3)中的形式呢?实际上,在后面的章节,我们还会遇到其他种类的神经元 ,其中 称之为激活函数。当我们使用不同的激活函数时,主要的变化是公式(5)中偏导的改变。当我们把 作为激活函数时,它的导数会非常简单,在本书中,我们主要是使用 作为激活函数。
我们怎样解释sigmoid神经元的输出呢?与感知机不同,sigmoid的输出是0~1范围内的实数。这会带来一些麻烦,如果我们要做手写数字分类任务,我们期望神经网络的输出为这个数字是“9”或者“这个数字不是9”(只有两种答案)。现在输出结果有无数种可能。一般的做法是以0.5作为分界,如果小于0.5,则认为不是“9”,如果大于0.5,则认为是“9”。经过这样的约定,那么sigmoid神经元组成的神经网络就可以识别手写数字了。
https://zhuanlan.zhihu.com/p/35920748