(主要参考书籍《神经网络与深度学习》)
1. 什么是神经网络
1.1 从感知器说起……
什么是感知器?很简单,前面我们已经说过了:
什么意思呢?我们有一些输入,我们会根据这些输入做出一个决定:YES OR NOT。我们可能会想这么简单有什么用呢?那我们得想一下电脑——CPU和人脑的组成了。
先从简单的CPU说起:只需要简单与或非三个门电路,我们就能组合出足够复杂的CPU!同理,只要我们把感知器视为一个个单元,经过组合,就能模拟实现足够复杂的功能。
用感知器实现与或门:
假设
x1,x2∈{0,1}
,
只要令
w=(−1,1,1)T
,输出
y=sign(−1+x1+x2)
——这就是一个与门;
只要令
w=(−1,2,2)T
,输出
y=sign(−1+2x1+2x2)
——这就是一个或门;
只要令
w=(1,−2)T
,输出
y=sign(1−2x1)
——这就是一个非门;
有了这三个基本元件,我就就可以用感知器组合出无限复杂的数字电路!譬如异或门:
XOR(x1,x2)=OR(AND(NOT(x1),x2),AND(x1,NOT(x2))
但是呢,这里注意一点。异或是由NOT-AND-OR三种基本单元串联/级联而成。无论与或非门怎么并联也无法实现复杂的功能。所以说,只有当多个感知器按层次组织起来的时候,才能发挥出巨大的功能。
再说人脑。我们知道人脑是由很多神经元以某种复杂结构组合而成。当信号刺激某一神经元,且刺激强度超过某一阈值,那么此神经元就会被激活,将传导冲动到与它先连接的神经元。——每个神经元与上述的感知器类似。
根据上面的论述,我们知道感知器应该以类似如下的形式组织:
第⼀列感知器——我们称其为第⼀层感知器——通过权衡输⼊依据做出三个⾮常简单的决定。那第⼆层的感知器呢?每⼀个都在权衡第⼀层的决策结果上做出决定。以这种⽅式,⼀个第⼆层中的感知器可以⽐第⼀层中的做出更复杂和抽象的决策。在第三层中的感知器甚⾄能进⾏更复杂的决策。以这种⽅式,⼀个多层的感知器⽹络可以从事复杂巧妙的决策。这种形式称为神经网络。
理论上来讲,神经网络可以实现任何函数。
1.2 神经网络的基本形式
通过将感知器与与非门的对比,看起来感知器只是另一种形式的逻辑电路——跟传统电路没什么区别。其实不然。
感知器运算的通⽤性既是令⼈⿎舞的,⼜是令⼈失望的。令⼈⿎舞是因为它告诉我们感知器⽹络能和其它计算设备⼀样强⼤。但是它也令⼈失望,因为它看上去只不过是⼀种新的与⾮⻔。
然⽽,实际情况⽐这⼀观点认为的更好。其结果是我们可以设计学习算法,能够⾃动调整⼈⼯神经元的权重和偏置。这种调整可以响应外部的刺激,⽽不需要⼀个程序员的直接⼲预。这些学习算法是我们能够以⼀种根本区别于传统逻辑⻔的⽅式使⽤⼈⼯神经元。有别于显式地设计与⾮或其它⻔,我们的神经⽹络能简单地学会解决问题,这些问题有时候直接⽤传统的电路设计是很难解决的。
1.2.1 S型神经元/感知器
(下文中我们将神经元与感知器混用,其含义是一致的。)
根据上面的论述,我们知道神经网络的关键在于设计学习算法来自动调整权重和偏置。更确切地说,任何权重(或偏置)中的微小改变能引起一个输出的微小改变——这是学习算法能自动调整权重和偏置的基础:
假设我有一个神经网络用于手写数字识别。现在输入一个手写字图像“8”,它的输出是“9”。那么我们可以根据“对权重(或者偏置)的微⼩的改动仅仅引起输出的微⼩变化”,我们能够计算出怎么对权重和偏置做些⼩的改动,这样⽹络能够接近于把图像分类为“ 8”。然后我们要重复这个⼯作,反复改动权重和偏置来产⽣更好的输出。这时⽹络就在学习。
但是对于我们的感知器,“对权重(或者偏置)的微⼩的改动仅仅引起输出的微⼩变化”这件事不会发生。根据 f(x)=sign(wTx+b) ,⽹络中单个感知器上⼀个权重或偏置的微⼩改动有时候会引起那个感知器的输出完全翻转,如 0 变到 1。那样的翻转可能接下来引起其余⽹络的⾏为以极其复杂的⽅式完全改变。因此,虽然你的“ 9”可能被正确分类,⽹络在其它图像上的⾏为很可能以⼀些很难控制的⽅式被完全改变。这使得逐步修改权重和偏置来让⽹络接近期望⾏为变得困难。也许有其它聪明的⽅式来解决这个问题。但是这不是显⽽易⻅地能让⼀个感知器⽹络去学习。
问题出在了sign函数阶跃性上,我们如果选用一个平滑的函数来代替sign函数,那么问题就得到了解决,根据我们在logistic regression算法的讲述,我们知道s型函数就是一个非常好的选择。这里我们用σ来表示:
σ(x)=11+exp(−x)
1.2.2 神经网络基本构架
其中的每个单元都是S型神经元。
这个⽹络中最左边的称为输⼊层,其中的神经元称为输⼊神经元。最右边的,即输出层包含有输出神经元,中间层,既然这层中的神经元既不是输⼊也不是输出,则被称为隐藏层。
输入层就是输入空间x,如果是64*64手写数字图像,那么输入层神经元为4906,且数值为像素的灰色值。输入层非常直观简单。
输出层
如果是二分类问题,则输出层只需要一个神经元即可,回答0/1。
但是对于手写数字图像来说,我们要识别数字,这是一个10分类问题,那么直觉上来说输出层需要10个神经元,输入为一个向量。其中
(1,0,0,0,0,0,0,0,0,0)T
表示输出为0,…,
(0,0,0,0,0,0,0,0,0,9)T
表示输出为9。
那么一个自然而言的问题是:⼀个看起来更⾃然的⽅式就是使⽤ 4 个输出神经元,把每⼀个当做⼀个⼆进制值,结果取决于它的输出更靠近 0 还是 1
。四个神经元⾜够编码这个问题了,因为 24 = 16 ⼤于 10 种可能的输⼊。为什么我们反⽽要⽤ 10 个神经元呢?经验主义的回答是:我们可以实验两种不同的⽹络设计,结果证明对于这个特定的问题⽽⾔, 10 个输出神经元的神经⽹络⽐ 4 个的识别效果更好。
而我们想探究的是:有没有启发性的的⽅法能提前告诉我们⽤ 10 个输出编码⽐使⽤ 4
个输出编码更有好呢?(这有助于我们理解神经网络是在做什么)⾸先考虑第⼀个输出神经元,它告诉我们⼀个数字是不是
0。它能那么做是因为可以权衡从隐藏层来的信息。隐藏层的神经元在做什么呢?假设隐藏层的第⼀个神经元只是⽤于检测如下的图像是否存在:
隐藏层
我们来总结一下:对于二分类问题,输出层只需要一个神经元;对于多分类问题,输出层是一个向量——这足够简单直观。相比之下。隐藏层的设计则堪称⼀⻔艺术。特别是,通过⼀些简单的经验法则来总结隐藏层的设计流程是不可⾏的。相反,神经⽹络的研究⼈员已经为隐藏层开发了许多设计最优法则,这有助于⽹络的⾏为能符合⼈们期望的那样。
1.3 迈向深度学习
我们考虑这样一个问题:识别图片中有没有人脸。我们如何做呢?
我们受到启发的⼀个想法是将这个问题分解成⼦问题:图像的左上⻆有⼀个眼睛吗?右上⻆有⼀个眼睛吗?中间有⼀个⿐⼦吗?下⾯中央有⼀个嘴吗?上⾯有头发吗?诸如此类。如果⼀些问题的回答是“是”,或者甚⾄仅仅是“可能是”,那么我们可以作出结论这个图像可能是⼀张脸。相反地,如果⼤多数这些问题的答案是“不是”,那么这张图像可能不是⼀张脸。
当然,这仅仅是⼀个粗略的想法,⽽且它存在许多缺陷。也许有个⼈是秃头,没有头发。也许我们仅仅能看到脸的部分,或者这张脸是有⻆度的,因此⼀些⾯部特征是模糊的。不过这个想法表明了如果我们能够使⽤神经⽹络来解决这些⼦问题,那么我们也许可以通过将这些解决⼦问题的⽹络结合起来,构成⼀个⼈脸检测的神经⽹络。
子网络也可以继续分解:
这些⼦问题也同样可以继续被分解,并通过多个⽹络层传递得越来越远。最终,我们的⼦⽹络可以回答那些只包含若⼲个像素点的简单问题。举例来说,这些简单的问题可能是询问图像的⼏个像素是否构成⾮常简单的形状。这些问题就可以被那些与图像中原始像素点相连的单个神经元所回答。
最终的结果是,我们设计出了⼀个⽹络,它将⼀个⾮常复杂的问题——这张图像是否有⼀张⼈脸——分解成在单像素层⾯上就可回答的⾮常简单的问题。它通过⼀系列多层结构来完成,在前⾯的⽹络层,它回答关于输⼊图像⾮常简单明确的问题,在后⾯的⽹络层,它建⽴了⼀个更加复杂和抽象的层级结构。包含这种多层结构——两层或更多隐藏层——的⽹络被称为深度神经⽹络。
还是跟之前所说的一样,这仅仅是一个启发性的想法。我们并不能知道神经网络具体做了什么,怎么做的。
2. 学习一个神经网络
一个典型地神经网络结构:
我们还是将偏置和权重放置在一起。其中
w(l)ij
代表的是连接第l层第j个神经元到第(l+1)层第i个神经元的权重(注意i和j的顺序,你可能觉得反过来更加合理。接下来会告诉你为什么要这样做)。
那么就有:
则有:
现在假设神经网络有L层;
2.1 反向传播算法
假设我们使用二次代价函数,则有
那么 ∂C∂s(l+1)i 怎么计算呢?我们可以观察到: s(l)i 的变化,会引起这样的连锁反应:
我们定义 δ(l)i=∂C∂s(l)i ,则有
也就是说: δ(l)i 可以由 δ(l+1)i 反向计算。
其中,对于输出层有:
将(公式1,2,3)向量化,有:
由此:我们总结反向传播算法如下:
使用随机梯度下降或者小批量梯度下降法。
2.2 代价函数
感知器就是之前用过的logistic regression算法,很自然地,我们想到使用交叉熵代价函数,但是现在我们提供一个更深层次的思考。
只有一个感知器的情况下,假设使用二次代价函数,那么有:
根据σ的曲线,我们可以看到,如果对于数据点x=1.y=0。如果初始的权重使得输出接近1,那么此时 aσ′(s) 很小,也即学习速度非常缓慢;等到权重使得输出为0.5时,此时学习速度最快;等到权重使得输出接近于0时,速度又慢下来。
这不是一个好的代价函数,好的代价函数应该使得:当预测值与实际值误差大时,学习速度快;误差小时学习速度慢。
现在再来看交叉熵代价函数:
现在介绍一种新的输出层:softmax柔性最大值输出层。
此时输出层上,第j个神经元有:
某一神经元值的增加会导致其他神经元值的减小——因为总和是1.
如果使用对数似然代价函数,则表现与交叉熵代价函数相同。把⼀个具有对数似然代价的柔性最⼤值输出层,看作与⼀个具有交叉熵代价的 S 型输出层⾮常相似,这是很有⽤的。
3. 改进神经网络
3.1 正则化
根据之前我们讲到的正则化,则有:
那么,在进行梯度下降时有什么效果?
正则化的优点:
- 重申一点:规范化的神经⽹络常常能够⽐⾮规范化的泛化能⼒更强,这只是⼀种实验事实( empirical fact),规范化能够给我们⼀种计算上的魔⼒帮助神经⽹络更好地泛化,但是并不会带来原理上理解的指导,甚⾄不会告诉我们什么样的观点才是最好的
再补充一点:
为啥不对偏置进行正则化呢?
我们再来看一下L1正则化:
对比于之前的L2正则化技术,我们发现:
在 L1 规范化中,权重通过⼀个常量向 0 进⾏缩⼩。在 L2 规范化中,权重通过⼀个和 w 成⽐例的量进⾏缩⼩的。
所以,当⼀个特定的权重绝对值 |w| 很⼤时, L1 规范化的权重缩⼩得远比 L2 规范化要小得多。相反,当⼀个特定的权重绝对值 |w| 很⼩时, L1 规范化的权重缩⼩得要比 L2 规范化⼤得多。最终的结果就是: L1 规范化倾向于聚集⽹络的权重在相对少量的⾼重要度连接上,⽽其他权重就会被驱使向 0 接近。(定义sgn(0)=0)
我们希望能够有很多的w=0,显然L1正则化比L2正则化更为合适。但是L1正则化不连续(这好像也没什么关系。。。),经常使用
3.2 应用Dropout技术和人为扩展数据
待补充
3.3 权重初始化问题
对于non-convex,我们使用梯度下降法,不太容易找到全局最优值;多数情况下找到的是局部最优值。所以不同的初始权重可能会导致不同的结果,我们要尽量多的实验不同的初始权重值。
那么初始值有什么特别的要求没有?
假设输入神经元有1000个,其中500个是1,500个是0。假设我们用均值为0,方差为1的高斯分布来生成初始权重和偏置,那么某一隐藏神经元有 s=wTx+b ,将会服从均值为0,方差为 501−−−√≈22.4 的高斯分布。什么意思?大多数隐藏神经元的输出都会变为1. 也就表⽰我们的隐藏神经元会饱和。所以当出现这样的情况时,在权重中进⾏微⼩的调整仅仅会给隐藏神经元的激活值带来极其微弱的改变。结果就是,这些权重在我们进⾏梯度下降算法时会学习得⾮常缓慢。这其实和我们在本章前⾯讨论的问题差不多,前⾯的情况是输出神经元在错误的值上饱和导致学习的下降。我们之前通过代价函数的选择解决了前⾯的问题。不幸的是,尽管那种⽅式在输出神经元上有效,但对于隐藏神经元的饱和却⼀点作⽤都没有。
所以我们要使用小的初始化权重。假设有n个输入神经元,那么就用均值为0,方差为 1n 的高斯分布初始化权重。偏置可以仍然用N(0,1)来初始化,因为他不影响神经元的饱和。
3.4 正则化的另一种方法:提前终止
使用梯度下降法时,迭代次数越多,可以访问的w越多,也即:
dvc
越大,所以减少迭代次数也可以作为一种正则化技术:
什么时候终止?
Early stopping 表⽰在每个回合的最后,我们都要计算验证集上的分类准确率。当准确率不再提升,就终⽌它。这让选择回合数变得很简单。
我们需要再明确⼀下什么叫做分类准确率不再提升,这样⽅可实现 Early stopping。正如我们已经看到的,分类准确率在整体趋势下降的时候仍旧会抖动或者震荡。如果我们在准确度刚开始下降的时候就停⽌,那么肯定会错过更好的选择。⼀种不错的解决⽅案是如果分类准确率在⼀段时间内不再提升的时候终⽌。例如,我们要解决 MNIST 问题。如果分类准确度在近 10 个回合都没有提升的时候,我们将其终⽌。