第17章:多层感知机——把神经元叠起来

第17章:多层感知机——把神经元叠起来
前面两章我们做了两件事。第15章讲了怎么判断一个模型是真的学会了还是在背答案。第16章讲了怎么用梯度下降一步步地调参数。这两样东西——评估方法和优化方法——是所有机器学习模型都要用的。线性回归用它逻辑回归用它SVM也用它虽然SVM的优化形式稍微特殊一点。到了深度学习它们更是核心。现在要问的是这些方法要往什么东西上套如果只用一个神经元——就像逻辑回归或感知机那样——你能解决XOR问题吗不能。我们在第3章已经聊过了那个单层感知机被XOR彻底难住了。但如果堆两层呢这一章我们就看两件事。第一两层神经元为什么能解决XOR。第二这个“堆叠”的直觉是怎么一路延伸到几百层的。先回到那个难住所有人的问题XOR逻辑是这样的。两个输入每个可以是0或1。如果两个输入相同输出0如果不同输出1。0 XOR 0 00 XOR 1 11 XOR 0 11 XOR 1 0把四个点画在坐标纸上(0,0)输出0(1,1)输出0(0,1)输出1(1,0)输出1。两类点在坐标平面上呈对角线分布——输出0的在左下和右上输出1的在左上和右下。你画不出一条直线把它们切开。一个单层感知机——或者一个逻辑回归——只能画一条直线。所以它搞不定。那两层呢两层的意思是你先有两个独立的线性分类器每个都把输入空间切成两半。然后你再用一个线性分类器把这两个切割结果组合起来。在XOR这个例子里你可以让第一个分类器关注“x₁是否大于0.5”——它把平面竖着切一刀把左边的(0,0)和(0,1)归为一类右边的(1,0)和(1,1)归为另一类。第二个分类器关注“x₂是否大于0.5”——它横着切一刀把下面的(0,0)和(1,0)归为一类上面的(0,1)和(1,1)归为另一类。然后你让第三个分类器看前两个分类器的输出组合只有当第一个分类器说“右边”且第二个分类器说“上面”——也就是(1,1)——或者第一个说“左边”且第二个说“下面”——也就是(0,0)——才输出0。其他情况输出1。这就是多层感知机解决XOR的方式。第一层的两个神经元各自画一条直线。第二层的一个神经元把两条直线切割出来的区域重新组合。你最终得到的是一个非线性的决策边界——两条直线交叉形成一个菱形或十字形刚好把对角线上的两类点分开。关键是你不需要手动设计这些切割。你只需要告诉网络“这是输入这是正确的输出”然后让反向传播自己去学。它会在第一层里长出两个合适的线性分类器然后在第二层学会怎么组合它们。隐藏层的意义从特征到特征上面那个例子里的“第一层”在神经网络里有一个专门的名字——隐藏层。为什么叫“隐藏”因为它的输出既不是原始的输入你给了它什么也不是最终的输出你想要什么。它在中间你看不到它具体在做什么但它做的事情是把原始数据“翻译”成更适合后续处理的中间表示。在XOR例子里隐藏层的两个神经元把原始的二维坐标——(x₁, x₂)——映射成了两个新特征“是否在右边”和“是否在上方”。这两个新特征组合起来就足以区分XOR的四类点。你注意到这个过程的本质了吗神经网络不是一步到位地画出最终的决策边界。它先在不同的空间里重新表达数据让数据变得更“好分”然后再做最终分类。一个深层网络就是把这个“重新表达”的过程重复很多次。第一层从原始像素里找出边缘。第二层从边缘里组合出局部形状。第三层从局部形状里组合出部件。最后一层从部件里判断“是猫还是狗”。每一层都在做同一件事——把上一层的输出作为输入变换成更抽象、更有利于当前任务的表示。深度为什么有用你可能已经想到了如果一层隐藏层就能解决XOR那为什么我们需要很多层答案是层数越多你需要的“手工设计”就越少。单层隐藏层足够解决任意复杂的问题——理论上一个足够宽的隐藏层可以逼近任何函数。这是“万能逼近定理”在说的东西。但“理论上”有一个代价你需要极其宽的一层。一个两层网络如果想学会识别一张高清图片里的猫它的隐藏层可能需要几百万个神经元——参数数量大到无法训练而且会极度过拟合。而深层网络用“窄而深”替代了“宽而浅”。它不试图在一个巨大的层里做所有的变换而是把变换拆分成一系列小的、渐进的步骤。每一层只做一点点变化——把某些特征稍微突出把另外一些特征稍微压制。经过几十层之后一个像素点被逐步扭曲成“猫”的判断。这个“渐进扭曲”有一个直观的比喻雕一块木头。你不会一斧头把木头劈成雕像。你从大块开始先砍出轮廓再换小刀削出细节再换更细的刀雕出眼睛和眉毛。每层神经元在做类似的粗加工到细加工。深层网络之所以在2010年代之后爆发就是因为人们发现层数堆得越深模型在图像、语音、文字这些复杂数据上的表现就越好——而且层数增加带来的收益远远大于它带来的过拟合风险只要你有足够的数据和合适的正则化。前向传播数据是怎么流过去的现在我们知道了一个多层网络的结构。但数据是怎么从输入流到输出的这个过程叫前向传播。输入向量进入第一层。每个神经元把输入的每个分量乘上对应的权重求和加上偏置再通过一个激活函数下章专门讲——得到第一个隐藏层的输出向量。这个向量作为第二层的输入重复同样的操作。一直传到最后一层得到最终输出。每一层的操作公式完全一样h^{(l)} f( W^{(l)} · h^{(l-1)} b^{(l)} )其中 h^{(l-1)} 是上一层的输出W 是这一层的权重矩阵b 是偏置向量f 是激活函数。你看到了吗这个公式跟线性回归一模一样——线性变换W·x b再加一个非线性f。唯一的区别是这个操作被重复了很多次。每一次的输出都成了下一次的输入。这就是为什么“矩阵乘法”在深度学习里这么重要。每一层的前向传播就是一次大矩阵乘法。一个深度网络就是一连串的矩阵乘法交替着非线性激活。还缺一块拼图我们已经把多层网络的结构讲清楚了。输入→隐藏层→激活→隐藏层→激活……→输出。但你注意到没有我们还漏了一个关键问题最后一层输出的是什么如果是分类任务输出应该是一个概率分布而不是一个任意数字。如果是回归任务输出应该是一个连续值。这个“输出层怎么设计”的问题跟“损失函数怎么选”的问题紧密相关。分类用交叉熵损失所以输出层要用Softmax把它变成概率。回归用均方误差损失所以输出层直接输出线性的计算结果。下一章我们专门聊激活函数——正是它把“一连串矩阵乘法”变成了“非线性变换”。没有它堆叠一百层也等于一层。再下一章我们聊损失函数——分类用交叉熵回归用MSE它们为什么匹配、怎么起作用。两层就能解决XOR几十层就能认出一只猫。从XOR到猫中间只差一件事你知道怎么把网络搭得更深并且知道每一层该用什么方式激活、最终用什么方式输出。参考文献Nielsen, M. (2015).Neural Networks and Deep Learning. 第1章Using neural nets to recognize handwritten digits。在线免费书籍http://neuralnetworksanddeeplearning.com/推荐理由Nielsen在第1章里用识别手写数字的完整例子展示了从输入层到隐藏层到输出层的完整前向传播过程。他把“层”的概念拆解得极其清楚——每一层的权重矩阵、偏置向量、激活函数、输出形状都配有直观的图示。读完这一章你会对“数据是怎么流过去的”有一个完整的画面。3Blue1Brown. (2017). “But what is a neural network? | Chapter 1, Deep Learning”. YouTube.推荐理由这期视频用手写数字识别作为载体从头开始搭建了一个两层神经网络。它用极慢的速度展示了输入像素如何通过第一层权重矩阵变成隐藏层的激活值再通过第二层权重矩阵变成输出层的概率。配合本篇的“XOR两层”文字描述视频里的“手写数字两层”会给你一个更具体的参照物。Goodfellow, I., Bengio, Y., Courville, A. (2016).Deep Learning. MIT Press. 第6章Feedforward Deep Networks。推荐理由第6章是深度学习教材里对“前馈网络”最系统的介绍——从“为什么需要隐藏层”开始到“隐藏层能学习什么表示”到“万能逼近定理”的直觉证明。虽然偏数学但开篇几节的文字解释非常清晰适合在读完本篇后作为概念对照。