目录
- 前言
- 1. 总览
- 2. 回顾
- 3. 训练数据的使用
- 4. 代价函数
- 5. 梯度下降法
- 6. 梯度向量
- 7. 梯度下降小结
- 8. 分析网络
- 9. 网络如何学习的研究
- 相关资料
- 结语
前言
3Blue1Brown 视频笔记,仅供自己参考
这个章节主要介绍梯度下降的思想,之后进一步探索网络的能力以及隐含层神经元的真实目的
官网:https://www.3blue1brown.com
视频:https://www.bilibili.com/video/BV1Ux411j7ri
1. 总览
在上一个章节中我讲解了神经网络的结构,我会在这里快速回顾一下,帮大家唤醒记忆
接着我在这章内容里有两个主要目标,首先是介绍梯度下降的思想,它不仅仅是神经网络学习的基础,机器学习中很多其他技术也是基于这个方法
之后,我们将进一步探索一下上图所示这个网络的能力,以及那些隐含层神经元的真实目的
2. 回顾
回顾一下,我们的目标是实现手写数字识别这个经典范例,即神经网络中的 “Hello World”
手写数字的图像分辨率为 28x28 像素,每个像素的灰度值在 0 和 1 之间,它们决定了网络输入层中 784 个神经元的激活值
接着下一层的每个神经元的激活值等于上一层所有激活值的加权和,再加上一些叫做偏置值的数字,最后把这个和输进 sigmoid 或者 ReLU 之类的压缩函数
我比较随意地选取了两个隐含层,每层有 16 个神经元,整个网络有 13000 多个权重偏置值可供我们调整,正是这些数值决定了网络实际会做什么工作
当我们说这个网络对一个给定的数字进行分类时,我们的意思是,最后一层 10 个神经元中最亮的那个就对应了这个数字
要记得,我们在这里使用分层结构是出于这样的理由:没准第二层可以识别短边,说不定第三层会识别圆圈和直线等图案,最后在最后一层将这些图案拼凑起来,识别出数字
Note:这里提到的 pattern “图案” 就等价于 “模式识别” 中的模式
3. 训练数据的使用
那这章我们就来研究神经网络是怎么学习的,OK,现在我们想要这么一种算法,你可以给这个网络看一大堆训练数据,其中包括一堆不同的手写数字图像,以及它们代表哪个数字的标记,算法会调整这 13000 个权重和偏置值,以提高网络对训练数据的表现
我们希望这种分层结构可以让它学会举一反三,识别训练数据之外的图像。训练好网络之后,我们会给它更多以前从未见过的带标记的数据作为测试,你就能看到它对这些新图像进行分类的准确度
这例子之所以能广泛用于入门,是因为有幸 MNIST 数据库背后的好心人搜集了数以万计的手写数字图像,并分别都标记上了它们所表示的数字
虽然机器会 “学习” 的说法很大胆,但当你实际看到它的工作原理之后,这听起来就不再像是疯狂的科幻场面,而更像是一道微积分习题了,我是指这实际上是在找某个函数的最小值
4. 代价函数
从概念上讲,我们认为每个神经元都与上一层的所有神经元相连接,决定其激活值的加权和中的权重有点像是那些连接的强弱,而偏置值则表明神经元是否更容易被激活
在一开始,我们会完全随机地初始化所有的权重和偏置值,可想而知,这个网络对于给定的训练示例会表现得非常糟糕,毕竟它只是在做一些随机的判断
例如,你输入一个 3 的图像后,输出层看起来就一团糟,这时你就要定义一个 “代价函数” 来告诉电脑这是一个不好的结果,其他神经元输出的激活值应该基本上是 0,只有 3 这个神经元是 1,但你给我的结果完全错误
用更加数学的语言来说,你要将每个错误输出激活值与你想要的值之间的差的平方加起来,我们称之为训练单个样本的 “代价”
Note:单个样本上代价也叫做 Loss,“损失/误差”,不过现在很多人将 loss function、cost function 混着用了
注意一下,网络能对图像进行正确的分类时,这个平方和就比较小,但如果网络糊里糊涂找不着北的话,这个平方和就很大
你接下来就要考虑手头上几万个训练样本中代价的平均值,而我们就用这个平均代价值来评价这个网络有多糟糕
Note:代价的平均值也叫 Empirical Risk,“经验风险”
但这东西挺复杂的,要记得网络本身不过是个函数,有 784 个输入值,即像素的灰度,最后的输出值是 10 个数字,而所有的权重和偏置值可以说就组成了这个函数的参数
而代价函数还要再抽象一层,这 13000 多个权重和偏置值作为它的参数,它输出的是单个数值,来表示这些权重和偏置值有多差劲,而且代价函数取决于网络对于上万个训练数据的综合表现
内容很多,需要慢慢消化,但如果你只告诉电脑这个网络它有多糟糕,那并不是很有用,你还得告诉它,怎么改变这些权重和偏置值才能有进步
为了简化问题,我们先不去想一个有 13000 个变量的函数,而先考虑简单的一元函数,只有一个输入变量,只输出一个数字,要怎么找输入值 w w w 使得函数值最小化呢?学过微积分的都知道,有时候你可以直接算出这个最小值
不过函数很复杂的话,就不一定能写出来,而我们这个超复杂 13000 元的代价函数就更加是不可能做到的了
一个更灵活的技巧是,先随便挑一个输入值,然后考虑向左还是向右走,函数值才会变小,准确地说,如果你找到了函数在这里的斜率,那么斜率为正就向左走,斜率为负就向右走。在每一个点上都这样子重复,计算新斜率,再适当地走一步的话,你就会逼近函数的某个局部最小值
你可以想象一个小球滚下山坡,要注意,就算是这个很简单的一元函数,由于不知道一开始输入值在哪里,最后你可能会落到许多不同的坑里,而且无法保证你落到的局部最小值就是代价函数可能达到的全局最小值
我们的神经网络也会遇到这个问题,值得一提的是如果每步的大小和斜率成比例,那么在最小值附近斜率会越来越平缓,每步会越来越小,这样可以防止调过头
5. 梯度下降法
想象一个更复杂的,两个输入一个输出的二元函数,输入空间可以想象成 XY 平面,代价函数是平面上方的曲面
现在我们不问函数的斜率,而应该问在输入空间内沿哪个方向走才好让输入结果下降得最快,换句话说,哪个方向下山最快,这里同样可以套用球滚下山的场景方便思考
熟悉多元微积分的人已经知道,函数的 梯度 指出了函数的 最陡增长方向,也就是说按梯度的方向走,函数值增长得就最快,那么沿梯度的负方向走,函数值自然就降低得最快了,而且,这个梯度向量的长度就代表了这个最陡的斜坡到底有多陡
但如果你不熟悉多元微积分,想了解更多的话,推荐你们可以去看看之前的多元微积分课程。然而大家现在只需要知道,我们有办法算出这么个向量,它能够指出哪个方向下山最快,路有多陡就可以了,知道了这一点,具体细节掌握不牢靠也无所谓
你只要懂得让函数值最小的算法其实不过是先计算梯度,再按梯度反方向走一小步下山,然后循环
处理带 13000 个输入的函数也是一个道理,想象把 13000 个权重偏置都放到一个列向量里,那么代价函数的负梯度也不过是个向量,负梯度正是指出了在这个大到爆炸的函数输入空间内,具体如何改变每一项参数才可以让代价函数的值下降得最快
那么,对于这个我们特别设计的代价函数,更新权重和偏置来降低代价函数的值,意味着输入训练集的每一份样本的输出都更接近期待的真实结果,而不是一串 10 个随机数字
要注意的是这个代价函数取了整个训练集的平均值,所以最小化的意思是,对所有的样本得到的总体结果都会更好一点
这个计算梯度的算法是神经网络的核心,我们叫做 反向传播算法(Back Propagation,BP),那就是下个章节的内容了,到时,我会从头到尾梳理一遍单个训练数据会具体让每个权重和每个偏置产生怎么样的变化,不再死磕相关的微积分和公式的概念,而是给大家直观上的感受
此时此刻,除了怎么实现这个算法,我主要想强调当我们提到让网络学习,实质上就是让代价函数的值最小,而为了达到这个效果,代价函数非常有必要是平滑的,这样我们才能每次挪一点点,最后找到一个局部最小值
这也顺便解释了,为什么人工神经元的激活值是连续的,而非直接沿袭生物学神经元那种二元式的,要么激活要么非激活的取值模式
这种按照负梯度的倍数不断调整函数输入值的过程就叫做 梯度下降法(Gradient descent),这是一种可以让你收敛到代价函数图中某一个 “坑” 里,即一个局部最小值的地方
这里我依然展示的是一个二元函数图,毕竟人脑想象一个 13000 维的输入空间中的变动实在是略困难,但其实我们还有一种漂亮的思路,不用借助空间
负梯度中的每一项都告诉了我们两件事,正负号很明显在告诉我们输入向量的这一项该调大还是调小,但重要的是,每一项的相对大小更告诉了我们改变哪个值的影响更大
可以看到我们的网络中,调整其中一个权重对于代价函数的影响就比调整别的权重大得多,对训练数据来说,其中某些连线就是更加的重要
6. 梯度向量
所以,你在看到这个复杂到爆炸的代价函数它的梯度向量时,就可以把它理解为各个权重偏置的相对重要度,标记出了改变哪个参数性价比最高
这也是理解方向的另一种方式,举个简单的例子,假设有个输入两个变量的二元函数,你算出来这个函数在某个点的梯度是 [3, 1],一种解读就是,你站在这个点,顺着这个梯度的方向移动,函数值增加得最快
当你把这个函数曲面画出来时,你沿这个向量的方向走就是径直向上的
但我们还有另外一种解读,即第一个变量的重要性是第二个变量的 3 倍,也就是说,起码在这一块取值区域内,改变 x 的值会造成更大的影响
7. 梯度下降小结
好吧,我们回到对网络的讨论中来,小结一下,神经网络本身是一个带 784 个输入和 10 个输出的函数,由各种加权和所定义的
代价函数则是更复杂一层,把那 13000 多个权重偏置作为输入,通过训练数据得出一个对网络糟糕程度的评分
而代价函数的梯度,则在上边还要复杂一层,告诉我们如何微调权重偏置的值才可以让代价函数的结果改变得最快,也就是可以理解为改变了哪些权重影响力最大
8. 分析网络
那么,当你随机初始化权重和偏置,并通过梯度下降法调整了很多次参数之后,神经网络来识别它从未见过的图像时,表现又会如何呢?
对于这个带 2 层 16 个神经元隐含层的神经网络来说,其实表现并不赖,它可以正确分类 96% 的新图像
老实说,如果你去检查下它搞错了的图像的话,你自己也会觉得不应该那么强求它
如果我们再修改下隐含层的结构的话,准确率可以上到 98%,这的确够好了,当然不是最好,换成更加复杂的网络比原版的肯定效果会更好
但既然图像识别本来任务就很艰巨,我觉得神经网络在我们从未告诉它该识别什么图案的情况下,能准确识别出从未见过的图像,已经很了不起了
一开始我介绍这种结构期望的是,它的第二层能识别出短边,第三层能把短边拼成圈或长笔画,最后把这些部件拼成数字,那么神经网络真的是这么做的吗?
好吧,对于这个网络而言,完全不是嘛
还记得上一章中我们可以把第一层所有神经元和第二层某一神经元间所有的权重表示为第二层神经元所识别的一个像素图案吗,然而实际应用中,第一层和第二层之间的权重,之前说它们能识别出各种散落的短边,但其实它们看起来没什么规律,中间只有一些松散的图案,感觉就像在如深海一般的 13000 维参数空间中,我们的网络找到了一个还不错的局部最小值住了下来,尽管它可以成功对绝大多数图像做分类,但它并不会如期望一般识别出图像中的各种图案
看个最明显的例子,我们把一个随机的图像输入进去,如果网络很智能,你可能会期待它要么会感到不确定,10 个输出神经元一个都不激活,要么就激活全部的 10 个神经元,激活值都差不多
但结果却是,网络总是很自信地给你一个没道理的回答,正如它能把一张真正的 5 确定成 5 一般,它也能把一张随机的噪声图识别成 5
换句话来讲,虽然网络可以很好地识别数字,但它也并不知道自己如何写数字
究其原因,很大程度上是因为它的训练被限定在了很窄的框架内,试想一下神经网络的第一视角,从它的角度看,整个宇宙都是由小网格内清晰定义的静止数字所组成的,而它的代价函数则只会促使它对最后的判断有绝对的自信
那么,上面这张图真的显示了第二层神经元的工作过程吗?
你可能想知道,为什么我一开始在介绍这个网络的时候,我想让你们觉得它们在识别图案和短边,毕竟,神经元根本就没这么做,是不是
其实,我们不应该把这看做我们讨论的终点,而应该当做学习的起点,这种网络其实是在早八九十年代就已经研究过的旧技术,你确实需要先理解这些旧的才好理解现代变种的细节,而显然旧方法也足以解决些有趣的问题
不过,你越深究隐含层的工作过程,你会觉得它也没那么智能
9. 网络如何学习的研究
最后,我们来谈下几篇 paper,它们都深入研究了更先进的图像识别是如何学习的:
- Understanding deep learning requires rethinking generalization
- A Closer Look at Memorization in Deep Networks
- The Loss Surfaces of Multilayer Networks
我们先来看第一篇
这篇文章选取了一个图像识别做得特别好的深度神经网络,但不给它一个正确标记过的训练集,而是用了个标记被打乱了的训练集,显然测试的准确率不比随机猜测的好,毕竟所有的标记都被打乱了
但训练的时候,它依然能达到相同的训练准确率,就当跟用了个正确标记的训练集一样,即是说这个网络数以百万计的权重足以让它记忆下所有随机的数据
但问题就来了,我们让代价函数最小到底是对应上了图像中的某些结构呢,还是只是单纯的死记硬背罢了
在 ICML 会议上的一篇论文,即我们讨论的第二篇论文,提出了一些想法认为这些网络其实做到了更智能的东西
观察下它的准确率曲线,如果训练用了一个随机的训练集的话,代价下降得就特别的慢,跟一个线性方程差不多
也就是说你很难得找到可能存在的局部最小值,也能难找到让你准确率上升的权重
而当你用了 “结构化” 的训练集,拥有标记正确的数据的话,你一开始代价值会上下浮动,但后来一下就降到很低的地方了,表示达到了一定准确率,所以某种程度上讲就更容易找到局部最小值
这个问题正好可以引出另外一篇已经发表了好几年的论文,它那里面用到的网络每一层都简化了许多
但论文的一个结论就是,你看下代价函数的优化结果就会发现,网络倾向收敛到的各个局部最小值其实都差不多一样大,你可以认为如果数据集已经结构化了,那么你就能更轻松地找到局部最小
相关资料
- 神经网络和深度学习的书籍 | Michael Nielsen
- http://neuralnetworksanddeeplearning.com/
- https://github.com/mnielsen/neural-networks-and-deep-learning
- MNIST 数据库
- https://yann.lecun.com/exdb/mnist/
- 博客 | Chris Olah
- https://colah.github.io/
- 机器学习视频 | Welch Labs
- Learning To See [Part 1:Introduction]
- Neural Networks Demystified [Part 2:Data and Architecture]
- 深度学习书籍 | Goodfellow、Bengio、Courville
- https://www.amazon.com/Deep-Learning-Adaptive-Computation-Machine
结语
这个章节我们主要学习了神经网络是怎么学习的,它主要是通过梯度下降法,最小化代函数来更新网络中的各个参数,以达到学习的目的,而其中计算梯度的算法是神经网络的核心,叫做反向传播算法,我们下章会详细讲解
OK,以上就是本章的全部内容了,下章我们来讲反向传播算法,敬请期待😄