神经网络和深度学习
神经网络:一种可以通过观测数据使计算机学习的仿生语言范例
深度学习:一组强大的神经网络学习技术
神经网络和深度学习目前提供了针对图像识别,语音识别和自然语言处理领域诸多问题的最佳解决方案。传统的编程方法中,我们告诉计算机如何去做,将大问题划分为许多小问题,精确地定义了计算机很容易执行的任务。而神经网络不需要我们告诉计算机如何处理问题,而是通过从观测数据中学习,计算出他自己的解决方案。自动地从数据中学习看起来很有前途。然而直到2006年我们都不知道如何训练神经网络使得它比传统的方法更好,除了一些特定问题。直到2006年称为深度神经网络的学习技术被提出,这些技术现在被称为深度学习。它们得到了很好的发展,今天,深度神经网络和深度学习在计算机视觉、语音识别和自然语言处理等许多重要问题上取得了出色的表现。
初识神经网络
人类的视觉系统是世界上最棒的系统之一,比如下列一串手写数字:
大多数人都可以一眼看出它是504192。在我们大脑的每一个半球,都有主要的视觉皮质V1V1,它包含了1.4亿个神经元,在这些神经元之间有数百亿的接触。然而人类的视觉不仅仅包含了V1V1,而是一系列的视觉皮质V1,V2,V3,V4,V5V1,V2,V3,V4,V5,逐步进行更复杂的图像处理。我们大脑里有一台超级计算机,通过数亿年的进化,可以很好的适应这个视觉世界。识别手写数字并不容易,我们人类惊人地可以理解我们眼睛所看到的东西,但这些工作都是在我们不知不觉中就完成了,我们根本不知道我们大脑完成了多么负责的工作。
神经网络解决这类问题通过不一样的方式。思想是把大量的手写数字作为训练样本,然后生成一个可以通过训练样本学习的系统。换句话说,神经网络使用样本自动地推断出识别手写数字的规则。此外,通过增加训练样本的数量,该网络可以学到更多,并且更加准确。因此,当我展示下图100个训练样本时,可能我们可以通过使用成千上万甚至上亿的训练样本来建立一个更好的手写识别系统。、
该文我们将写一个程序实现一个神经网络,学习如何识别手写数字。在不使用神经网络代码库的情况下,74行代码就可以完成。但是这短短的代码识别数字的准确率超过96%。此外,后面的文章我们将可以实现准确率高达99%的方法。事实上,最好的商业神经网络现在已经很好了,银行可以用它们来处理支票,并通过邮局来识别地址。
的确,如果这篇文章只是描述如何实现一个手写数字识别的代码,那么很短的篇幅就可以讲完。但是在这个过程中,我们会讲到许多神经网络的核心思想,包括两种重要类型的神经元(感知机和sigmoid神经元),和标准的神经网络的学习算法,被称为随机梯度下降法。整篇文章我致力于解释为什么这样做,并且建立你的神经网络观念。在本文的结尾,我们将了解深度学习是什么,和为什么它很重要。
感知机
感知机是一类人造神经元,在许多神经网络中,主要的神经元模型是sigmoid神经元。我们将很快的了解什么是sigmoid神经元,但是想要知道为什么sigmoid要这么定义,就需要我们花点时间去了解感知机。
感知机如何工作?一个感知机通过一些二进制的输入x1,x2,...x1,x2,...,然后产生一个二进制的输出:
在上图中,感知机有三个输入x1,x2,x3x1,x2,x3,通常它可以有更多或者更少的输入。Rosenblatt提出了一个简单的规则来计算输出,它用权重w1,w2...w1,w2...来表示各个输入对输出的重要性。神经元的输出,要么是0要么是1,由权重和∑jwjxj∑jwjxj的值是否小于或者大于某一阈值。和权重一样,阈值也是一个实数,它是神经元的一个参数。用代数式表达就是:
以上就是感知机的工作原理。
这是基本的数学模型,你可以认为感知机是一种通过权衡各个因素做出决定的设备。举个例子,假设周末就要来了,你们城市有一场奶酪节,你很喜欢奶酪,你正在犹豫要不要去参加,你可能通过权衡下面三个因素来做出你的决定:
当天天气怎么样
你的男朋友或者女朋友要不要一起去
交通是否方便
我们可以通过对应的二进制变量x1,x2,x3x1,x2,x3来表示这三个因素。比如,x1x1表示天气很好,x1=0x1=0表示天气很差,同样x2=1x2=1表示女朋友想去,以此类推。
现在,假设你真的非常喜欢奶酪,以至于你无论你女朋友去不去,或者交通十分不便,你都很想去。但是可能因为你又非常非常讨厌恶劣天气导致你绝对不会参加。这时你可以使用感知机来模拟这种决策。因为天气对你的影响最大,你可以选择w1=6w1=6来表示天气的权重,w2=2,w3=2w2=2,w3=2来表示其他的因素,w1w1的权重最大表示天气因素对你影响最大。最后假设你选择了5作为阈值,这样以来,你的感知机决策模型就建立好了。也就是说这个模型在天气好的时候会输出1,天气不好的时候输出0,其实和其他两个因素没关系。
显然,人类的决策模型不仅仅只有感知机。但是这个例子说明了感知机如何做出决定的。一个复杂的感知机网络可以做出更加精准的决定似乎是合理的:
在这个网络中,第一列感知机——我们称作第一层感知机,通过权衡输入用来做三个很简单的决定。那么第二层的感知机是干什么的呢?这些感知机每一个都通过权衡第一层输出的结果作为输入而做决定。这样以来第二层的感知机可以比第一层做出更加复杂和抽象的决策。更复杂的决策可以在第三层做出。通过这种方式,一个第一层的感知机网络可以进行十分复杂的决策。
顺便说一下,我们定义的一个感知机都只有一个输出,上图的多层感知机看起来一个感知机有很多个输出,其实它只是把同一个输出传递给不同的下一层感知机用来利用,如果不嫌难看,你也可以先画一条输出线,然后再分支。
让我们简化一下感知机的描述方式,首先我们可以使用向量点积的方式代替∑jwjxj∑jwjxj,即W⋅X=∑jwjxjW·X=∑jwjxj,其中W和XW和X分别是权重值和输入值所组成的向量。其次,我们可以把阈值threshold移到不等式的另一边,即b=−thresholdb=−threshold,其中b被称为感知机的偏差。通过偏差代替阈值,综上,感知机规则改写为:
你可以把偏差b看作衡量感知机输出1的难易程度。从生物学的角度来讲,偏差衡量一个感知机是否容易激活。如果偏差b是个很大的实数,那么该感知机就很容易输出1。显然,目前引入偏差让我们对感知机的描述只是产生了很小的改变,后面我们将会看到它导致的进一步简化。后文我们将不再使用阈值而是使用偏差。
前面已经说过感知机是一个权衡输入做决定的方法。感知机的另一种使用方法是计算我们通常认为是底层计算的基本逻辑函数,如AND、OR和NAND。比如,假设我们有一个感知机有两个输入,每一个的权重都是-2,偏差是3,下图是该感知机模型:
然后我们看到输入值为[0,0]的话,感知机输出值就为1,因为(−2)∗0+(−2)∗0+3=3(−2)∗0+(−2)∗0+3=3是正数。这里使用*表示乘法是显而易见的。同样无论输入[0,1]还是[1,0],最后产生的结果都是1,但是当输入[1,1]的时候产生的结果是0,因为计算出来的表达式为-1。其实我们的感知机在这里实现了一个NAND功能。
该例子说明了感知机可以用来计算简单的逻辑函数。事实上,我们可以使用感知机网络计算任何逻辑函数。因为任何逻辑计算都可以通过NAND组合而产生。比如,我们可以使用NAND门来构建一个含有两位的电路x1和x2x1和x2。这需要按位求和,x1⊕x2x1⊕x2,也需要在x1和x2x1和x2都为1时该位设为1,也就是做按位乘积x1x2x1x2:
为了得到等价的感知机网络,我们将所有的NAND门替换为拥有两个输入,输入权重均为-2,偏差全为3的感知机。下图是所得的网络。
需要注意的时,最左侧的感知机的输出被最下方的感知机作为输入使用了两次。前面的感知机模型的定义中并没有说是否允许一个输出被同一个感知机使用多次。事实上这并不重要。如果我们不想允许这种情况存在,我们可以简单的将两天直线合并,用一根权重为-4的线代替这两根权重为-2的线。然后上述感知机网络变为下面这个等价的网络,其中没有标记的输入权重仍是-2:
到目前为止,我都是把像x1,x2x1,x2这样的输入当作变量画在了网络的左侧,事实上,通常我们会画一个额外的感知机——输入层,对输入进行编码:
可以看到输入感知器有输出但没有输入.
但它实际上并不是一个没有输入的感知机。如果我们确实有一个没有输入的感知机,那么∑jwjxj∑jwjxj的值一直都是0,因此感知机的输出就只和偏差b有关,这时感知机仅仅输出一个固定的值,而不是期望得到的值。我们最好把输入感知机看作是一个特殊的单元,用来简单的定义为了输出所需要的那些值x1,x2...x1,x2...
上述的例子论证了一个感知机网络可以用来模拟许多包含了NAND门的电路。因为NAND门是通用的计算方法,因此感知机也通用于计算。
感知机的计算普遍性既让人欣慰,又让人失望。安心是因为感知机网络可以和其他任意的计算设备相媲美,失望是因为它看起来仅仅像是一种新型的逻辑门,而不是什么NB的技术。
然而事实上并不是这这样的,事实证明我们可以设计出能够自动调节人工神经元网络参数和偏差的学习算法。这种调参是对外部刺激的相应,不需要程序员的干预。这些学习算法使我们能够以一种与传统的逻辑门截然不同的方式使用人工神经元。它并不是明确的列出门电路,我们的神经网络可以简单的学习解决问题,有些问题是很难通过设计传统电路就能解决的。
Sigmoid神经元
学习算法看起来非常好。但是我们如何才能为神经网络设计一个这样的算法呢?假设我们有一个感知器网络,我们想让它学习着去解决一些问题。举个例子,网络的输入可能是手写数字的原始扫描像素数据。我们想让这个网络学习出一个可以识别出对应数字的参数和偏差。为了了解如何学习,假设我们对网络中的权重和偏差做了一些小的改变。我们想要这个小的权重的改变造成一点网络中对应的输出的改变,这个特性让学习变得可能。下图是我们想要的(这个网络太简单不能做手写数字的识别):
如果对权重和偏差一个晓得调节可以造成输出的很小的变化,然后我们就可以根据这个事实修改权重和偏差,使得我们的网络以我们想要的方式做得更多。举个例子,假设这个网络总是把9分类为8,我们可以想办法对网络的权重和偏差做一些小的改变,使得网络可以将图片分为9。然后我们重复这样做,一次又一次改变权重和偏差,使得输出越来越好,网络就得到了学习。
问题是当你的网络包含感知机时不会发生这种情况。事实上,任何一个感知机上发生一点小的改变有时可能导致感知机的结果翻转(要么翻转要么不变),由0变为1或者相反。这样的翻转可能造成造成一系列连锁反应,造成其他所有感知机的复杂变化。也就是当你可能调节到数字9可以被很好的识别时,网络在其他图像上的行为已经变得完全难以控制。这使得我们通过一点点调试参数和偏差让网络更接近期望的行为变得艰难。或许有一些巧妙得方法来解决这个问题,但是如何使用一个感知机网络学习并不是那么容易的事情。
我们可以通过一种新的人造神经元来解决上述问题——sigmoid神经元。Sigmoid神经元和感知机很相似,但是它却可以实现当对权重和偏差做微小的改变时,输出量的改变也是微小的。这将使得sigmoid神经元网络可以学习成为了可能。
下面开始描述sigmoid神经元。我们将像描述感知机那样描述sigmoid神经元:
和感知机一样,sigmoid函数也拥有输入向量,但是它的输入向量不再仅限于0和1,而是0到1之间的连续值。比如,0.1314可以作为sigmoid神经元的输入值。同样,sigmoid神经元对每个输入都有分配权重和一个总的偏差。但是输出也不再是0和1,而是σ(w⋅x)+bσ(w⋅x)+b,其中σσ被称为sigmoid函数,定义为:
一个拥有输入x1,x2...x1,x2...权重w1,w2...w1,w2...偏差b的sigmoid神经元的输出为:
这个式子咋一看比感知机的公式复杂很多,事实上,它和感知机很相似。为了体现和感知机的相似性,假设z=w⋅x+bz=w⋅x+b是一个很大的正数,那么e−z≈0e−z≈0,那么σ(z)≈1σ(z)≈1。也就是说当z=w⋅x+bz=w⋅x+b是一个很大的正数时,sigmoid神经元的输出就接近于1,这就像一个感知机一样。反之当z=w⋅x+bz=w⋅x+b是一个很小的负数时,sigmoid的输出结果趋近于0,这和感知机的行为很相似。只有当w⋅x+bw⋅x+b的值不大不小的时候,sigmoid的输出才和感知机不一样。
对于σσ的代数式我们该如何理解?事实上,对于σσ的精确表达并不重要,重要的是σσ所形成的函数图形:
该函数图形是阶跃函数的平滑处理之后的样子。
如果σσ改为一个阶跃函数,那么sigmoid神经元就等同于感知机,因为他的输出结果和感知机的输出结果情况一模一样,当w⋅x+bw⋅x+b为正输出1,反之输出0。通过上面的描述,我们通过使用函数σσ得到一个平滑版本的感知机。函数σσ的平滑功能比它具体的代数表达式要重要得多。有了平滑处理,才使得我们在稍微改变权重或者偏差的时候,神经元的输出值才会有些许改变,而不是要么不变要么翻转。事实上,微积分告诉我们输出值得改变量可以近似表达为:
其中求和是对于所有的权重而言, ∂output/∂wj∂output/∂wj和∂output/∂b∂output/∂b分别表示输出在wjwj和偏差b方向上的偏导数。不要因为这里有求偏导而感到惊慌,虽然是在求偏导,但实际上他在说一件十分简单的东西:ΔoutputΔoutput是一个自变量为Δwj和ΔbΔwj和Δb的线性函数。这样的线性关系使得在改变微小的权重和偏差时可以的到期望的输出的微小改变成为一件容易的事情。虽然sigmoid神经元和感知机在行为上有很多相似之处,但是他可以很轻松的知道如何微小的改变权重和偏差使得输出改变。
如果σσ函数的形状比其代数表达式重要,那么我们为什么又要指定它的代数表达式为等式(3)那样呢?事实上,在后文我们也会偶尔考虑使用其他激活函数。在使用不同激活函数时,唯一的改变时方程(5)中的偏导数的改变。通过计算发现,使用σσ这样一个指数函数对于分化是有好处的。无论如何,σσ函数是最常见的激活函数。
我们应该如何解释sigmoid神经元的输出呢?显然,感知机和sigmoid神经元之间最大的不同在于,sigmoid输出的值不止0和1.他们可以输出0到1之间的所有实数。这将会是很有用的,比如:如果我们想要使用输出值表示输入到一个神经网络的像素图像的平均强度。但有时候这也是很烦人的一件事。假设我们想要从网络中获得输出值来表示是否“图像表示的是9”或者“图像表示的不是9”,显然,感知机的输出0和1会更加清楚。但是在实际使用的时候,我们会建立一个共识来解决这个问题,比如输出的值大于0.5我们认为它是9,反之不是9.
神经网络的架构
在下一节我将介绍一个可以很好识别手写数字的神经网络。在此之前,先解释一下网络中的各部分的专业术语。假设我们有一个网络:
正如前面提到的,最左边的一层称为输入层,位于这一层的神经元称为输入神经元。最右边的输出层包含了输出神经元,本例只有一个输出神经元。中间的层被称为隐藏层,因为这些神经元既不是输出也不是输入。隐藏层听起来很神秘,我第一次听到这个词的时候,我觉得它一定有深刻的哲学或数学意义。但是他真的其实就只意味着既不是输入也不是输出而已。上图的神经网络中只包含了一个隐藏层,但是有些网络有许多隐藏层,比如下图的四层网络结构,含有两个隐藏层:
因为历史的原因,这样的多层网络有时候被称作多层感知机(MLPs),尽管这个网络是有sigmoid组成的而不是感知机。本文不会使用MLP这个术语,但是你应该知道它的存在。
网络中的输入和输出层一般都被设计的很简单。比如:假设我们试图识别一幅图像是否是9,一个自然的方法就是将该图片的灰度值编码作为神经元的输入。如果这个图片是64X64的灰度图,那么我们的输入神经元就有64X64=4096个输入神经元,它的值随着灰度在0到1里适当的变化。输出神经元只有一个,输出的值小于0.5表示这个数字不是9,反之就是9.
虽然输入输出层的设计很简单,但是隐藏层的设计却是门艺术。我们不可能通过一些简单的经验法则来总结隐藏层的设计过程。相反,神经网络的研究人员已经开发了隐藏层的许多的最优设计规则,这可以帮助人们从他们的网络中的到预期的行为。比如,这种启发式可以帮助人们决定如何权衡网络的隐藏层数和训练网络所需的时间。我们将在后面见到几种这样的最优设计规则。
到目前为止,我们所讨论的神经网络都是上一层的输出作为下一层的输入。这样的网络被称为前馈神经网络(FeedforwardNerralNetworksFeedforwardNerralNetworks)。这意味着在网络中没有环状,信息总是往前走的,不会反向。如果我们确实有环,我们将会遇到函数σσ的输入依赖于其输出,这很难理解,所以我们不允许这样的循环。
然而,有些人造神经网络中存在反馈回路是可能的。这样的模型称为递归神经网络。这些模型的思想是让神经元在有限时间里激活,然后保持非激活状态。这种激活可以刺激其他神经元在稍后一段时间激活。这会导致许神经元激活,随着时间推移,我们将获得一串激活神经元。在这样的模型中,循环不会引起问题,因为一个神经元的输出只会在稍后的时间影响它的输入,而不是马上就影响。
递归神经网络的影响力比前馈神经网络的小,一部分原因是到目前为止,递归网络的学习算法不那么强大。但是递归网络仍然很有研究意义。比起前馈网络,它更接近我们大脑的思维方式。递归网络可能解决一些前馈网络很难解决的问题。本书目前只专注于更广泛使用的前馈网络。
作者:goooGuo
来源:CSDN
原文:https://blog.csdn.net/qq_31192383/article/details/77145993
版权声明:本文为博主原创文章,转载请附上博文链接!