深度学习 - 神经网络结构
上图中 中间2层黑箱,每个黑箱是16个神经元,总共4层,这些数字都是便于新手学习,实际操作的时候都可以调整的。这种模式是仿照生物学的神经元,第一层的神经元可以激活下一层,一层一层传到。比如这个图,第一层784个神经元,输入了784个各自的灰度值,那么这层激活值的图案会让下层的激活值产生某种特殊图案,再让再下层产生特殊的图案,最终在输出层得到某种结果,而输出层最亮的神经元就代表这个神经网络最终的选择。
这样一来,我们只需要学习,哪些部件能组成哪些数字即可。那么识别这些小部件,比如识别圆圈和识别直线就很难啊。怎么办?
但网络是真的这么做的吗?通过这种层状结构最后得出想要的结果?
更进一步的讲,若神经网络真的能识别这类边缘和图案,它们就能很好的应用到其他图像的识别任务上来,甚至不光是图像,比如音频,都可以拆分成小块,转化为抽象元素,一层层抽丝剥茧。
所以这个神经元的激活值,实际上就是对 加权和 到底有多“正”的打分。那么这个加权和有多 “正” 才表示激活呢? 此时你要加个 偏置值
,保证不能随意被激发,比如当加权和 大于等于 10 时候,才能激发。
那么,我们还可以推算出来,第一层输入层,一共784个神经元,第二次一共16个神经元,第一层的784个神经元都要对应第二层每一个神经元,那么这个计算量:784*16
个权重值;以及16个 偏置值。计算起来,上述神经网络需要权重值: 786*16 + 16*16 + 16*10
;偏置值:16+16+10
,总数130000多,相当于有130000多个按钮需要你去调节。所以我们讨论机器如何学习的时候,实际上是讨论如何设置这一大堆数字参数,才能让它正确的解题
我们把每个神经元想象成容器只是便于理解,其实这是错误观点。神经元实际上是一个函数,它的输入是上一层所有神经元的输出,而它的输出是一个0~1的值,不过这个函数非常复杂,它有13000个 权重参数
和 偏置参数
,并不停的用到矩阵乘法和sigmoid
映射运算,但它终究是个函数而已。
深度学习 - 梯度下降法
我们想要一种算法,你可以给这个网络一大堆训练数据,其中包括一堆不同的数字手写 图像,以及它们代表哪个数字的标记,算法会依据此调整130000个权重值和偏置值,以提高网络对数据训练的表现。
我们希望这种分层结构可以举一反三,识别训练数据之外的图像。训练好后,我们会给它更多的带标记的之前未见过的数据作为测试,你就能看到它对这些新图像分类的准确度。
虽然机器“学习”这个说法很大胆,但深入了解后,这看起来不像是科幻场面,而是一道微积分习题了。
从概念上讲,每一个神经元都与上一层所有神经元相连,决定其激活值加权和中的权重,可以理解为该联系的强弱大小,而偏置值则表示了神经元是否更容易被激活。
在这一开始,我们会重置所有的 权重值和偏置值, 那么可想而知,输出的结果有多随机,所以当结果出来后,你要告诉系统,只有正确的那个值是接近1,其他应该接近0,不然就是错误的。
然后怎么处理?你可以将每个垃圾输出激活值,与你期望的值的差的平方加起来。
接下来,我们就要考虑,手头几万个训练样本中,代价的平均值。而我们就用这个值来评价这个神经网络是好是坏。
要记得,网络不过是个函数,有784个输入值,即像素灰度,最后输出的是10个数,而所有的权重和偏置值就组成了这个函数的参数。而代价 函数函数还要更抽象一层,这13000个权重和偏置值作为它的参数,最后输出一个数,来表示这些权重和偏置的好坏。而代价函数取决网络对于上万个综合数据的表现。
再仔细想想,你告诉电脑,这个代价值,这个网络不好,没有用,告诉它怎么改,怎么调整这些 权重值和偏置值 才有进步。
为了简化问题,我们先考虑一个函数,只有一个输入变量,只有一个输出值。要怎么找到x值,使得函数的输入值最小呢?显而易见,求导嘛,求导得出斜率,斜率值为0,就找到最小值了。
想象一个更复杂的,两个输入一个输出的 二元函数:
熟悉多元微积分的人会清楚,函数的梯度指出了函数的最陡增长方向,即是说,按照梯度值的方向走,函数的增长值就越快(具体参考多元微积分知识)。现在我们只需要知道,我们能算出这个向量,它能指出哪个方向下山最快,路有多陡就可以了。
你只需要知道,让函数最小值的算法,不过是先计算梯度,然后按照梯度反方向走一小步下山,然后循环。处理带130000个输入的函数也是同样的道理。
计算梯度
的算法是神经网络的核心,我们叫做反向传播算法
。
当我们提到网络学习,实际上就是让代价函数的值最小。为了达到此目的,代价函数必须是平滑的,这样我们才能一点点的移动,最后找到局部最小值。这也解释了为什么神经元的激活值是连续的。这种按照负梯度的倍数,不断调整函数输入值的过程,叫做梯度下降法
。
我们回到神经网络的话题来,神经网络本身是带一个784个输入和10个输出的函数,由各种加权和所定义,代价函数则是更复杂一层,把130000多个权重和偏置作为输入,通过训练数据,得出一个对网络糟糕程度的评分,而代价函数的梯度,则在此基础上更复杂一层,告诉我们如何微调权重和偏置的值,才可以让代价函数的结果改变的最快,也可以理解为,改变了哪些权重,对结果影响最大。
那么,当你随机初始化权重和偏置的时候,并通过梯度下降法调整了多次参数之后,神经网络来识别它从未见过的图像时,表现又会如何?我们不能强求100%,能做到识别绝大部分情况就很不错了。
接着上面话题,这个神经网络,它能够很好的识别0-9之间的数字了,但当你给它一个不属于0-9的数字,比如一个五角星,它也会自信的把五角星识别成0-9中的一个数。这就是说,这个网络,它根本不明白输出的结果是什么,它只是照着做而已。究其原因,就是这个网络在很窄的框架里。但是深层次研究隐含层的工作内容,你会发现它没有那么智能。
深度学习 - 反向传播算法
首先复习一下:
所谓的学习,就是找到一个合适的权重和偏置值,使得代价函数的值最小。要计算一个训练样本的代价,你需要求出 网络的输出 与 理论期待的输出 之间每一项差的 平方和,然后对于成千上万的样本,都这么算一遍,取平均值,就得到了整个网络的代价值.
我们要 算的就是代价函数的负梯度,它告诉你如何改变这个网络所 有连线上的权重和偏置,能让代价下降的最快。(这个负梯度就能求出最佳的权重和偏置值)
反向传播算法,就是来求这个梯度的。
我希望大家能够牢牢记住之前提到的一点,想象一个130000多维度梯度向量过于抽象,换个思路,梯度向量 每一项大小是在告诉大家,代价函数对每个参数有多敏感,越大的参数对代价函数的影响越大
如上图,我们第一次输入一个2的数字训练样本,它会随机给出10个输出,这个输出对应的激活值不是我们想要的,我们期望我们要的2的激活值提高,其他的降低。
为了增大2对应的激活值,我们有3条路:
- 先看看看如何增加权重,连接线 前一层最亮神经元(最亮就是值最大)的那根线的 权重,增大它会迅速增大该激活值(wa相乘嘛),增加权重,我们一般就找这样高性价比的线去增加,使得连接性更强。
- 再看看调整上一层的激活值。
对于整个网络全局来看,以上,只是2这个最终输出神经元对于 网络的期待,我们还需要把最后一层不需要的神经元的激活值给弱化,所以,我们可以把神经元2的期待和 别的神经元的期待累加起来,作为对如何改变倒数第二层神经元的指示。
以上只是对2这个测试样本的训练调整。
实际使用中,这种算法下来,计算量非常大,有更优的方法,这里我们只作为学习理解。机器学习领域的人,最熟悉的难关,莫过于 获取 标记好的数据了。
反向传播算法 算的是 单个训练样板想怎么样修改 权重和偏置,不仅仅是说每个参数应该变大还是变小,还包括了这些变化的比例是多大,才能最快的降低代价。真正的梯度下降,得对好几万个训练样板都进行这样的操作,然后对这些变化取平均值,但算起来太慢了,所以你可以考虑将样板分到各个 Minibatch 中,计算一个 Minibatch 作为梯度下降的一步,计算每一个 Minibatch,调整参数不断循环,最后你会收敛到 代价函数 的一个最小值上,此时,你就可以说,你的神经网络对付数据训练已经很不错了。总而言之,我们实现反向传播的每一句代码,其实或多或少都对应大家已经知道的内容。
附录:反向传播算法的微积分原理
难度较大,难以理解,暂搁置。