从神经网络到深度学习
Posted 菜鸟的翅膀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从神经网络到深度学习相关的知识,希望对你有一定的参考价值。
本篇文章是综合了几篇博主觉得写的不错的文字。唯一的原创是把它们挑出来组合在一起。
1、反向传播神经网络极简入门
我一直在找一份简明的神经网络入门,然而在中文圈里并没有找到。直到我看到了这份162行的Python实现,以及对应的油管视频之后,我才觉得这就是我需要的极简入门资料。这份极简入门笔记不需要突触的图片做装饰,也不需要赘述神经网络的发展历史;要推导有推导,要代码有代码,关键是,它们还对得上。对于欠缺的背景知识,利用斯坦福大学的神经网络wiki进行了补全。
单个神经元
神经网络是多个“神经元”(感知机)的带权级联,神经网络算法可以提供非线性的复杂模型,它有两个参数:权值矩阵{Wl}和偏置向量{bl},不同于感知机的单一向量形式,{Wl}是复数个矩阵,{bl}是复数个向量,其中的元素分别属于单个层,而每个层的组成单元,就是神经元。
神经元
神经网络是由多个“神经元”(感知机)组成的,每个神经元图示如下:
这其实就是一个单层感知机,其输入是由和+1组成的向量,其输出为,其中f是一个激活函数,模拟的是生物神经元在接受一定的刺激之后产生兴奋信号,否则刺激不够的话,神经元保持抑制状态这种现象。这种由一个阈值决定两个极端的函数有点像示性函数,然而这里采用的是Sigmoid函数,其优点是连续可导。
Sigmoid函数
常用的Sigmoid有两种——
单极性Sigmoid函数
或者写成
其图像如下
双极性Sigmoid函数
或者写成
把第一个式子分子分母同时除以ez,令x=-2z就得到第二个式子了,换汤不换药。
其图像如下
从它们两个的值域来看,两者名称里的极性应该指的是正负号。从导数来看,它们的导数都非常便于计算:
对于有,对于tanh,有。
视频作者Ryan还担心观众微积分学的不好,细心地给出了1/(1+e^-x)求导的过程:
一旦知道了f(z),就可以直接求f‘(z),所以说很方便。
本Python实现使用的就是1/(1+e^-x)
也可以使用双曲正切函数tanh
其导数对应于:
神经网络模型
神经网络就是多个神经元的级联,上一级神经元的输出是下一级神经元的输入,而且信号在两级的两个神经元之间传播的时候需要乘上这两个神经元对应的权值。例如,下图就是一个简单的神经网络:
其中,一共有一个输入层,一个隐藏层和一个输出层。输入层有3个输入节点,标注为+1的那个节点是偏置节点,偏置节点不接受输入,输出总是+1。
定义上标为层的标号,下标为节点的标号,则本神经网络模型的参数是:,其中是第l层的第j个节点与第l+1层第i个节点之间的连接参数(或称权值);表示第l层第i个偏置节点。这些符号在接下来的前向传播将要用到。
前向传播
虽然标题是《(误差)后向传播神经网络入门》,但这并不意味着可以跳过前向传播的学习。因为如果后向传播对应训练的话,那么前向传播就对应预测(分类),并且训练的时候计算误差也要用到预测的输出值来计算误差。
定义为第l层第i个节点的激活值(输出值)。当l=1时,。前向传播的目的就是在给定模型参数的情况下,计算l=2,3,4…层的输出值,直到最后一层就得到最终的输出值。具体怎么算呢,以上图的神经网络模型为例:
这没什么稀奇的,核心思想是这一层的输出乘上相应的权值加上偏置量代入激活函数等于下一层的输入,一句大白话,所谓中文伪码。
另外,追求好看的话可以把括号里面那个老长老长的加权和定义为一个参数:表示第l层第i个节点的输入加权和,比如。那么该节点的输出可以写作。
于是就得到一个好看的形式:
在这个好看的形式下,前向传播可以简明扼要地表示为:
在Python实现中,对应如下方法:
其中,ai、ah、ao分别是输入层、隐藏层、输出层,而wi、wo则分别是输入层到隐藏层、隐藏层到输出层的权值矩阵。在本Python实现中,将偏置量一并放入了矩阵,这样进行线性代数运算就会方便一些。
后向传播
后向传播指的是在训练的时候,根据最终输出的误差来调整倒数第二层、倒数第三层……第一层的参数的过程。
符号定义
在Ryan的讲义中,符号定义与斯坦福前向传播讲义相似但略有不同:
:第l层第j个节点的输入。
:从第l-1层第i个节点到第l层第j个节点的权值。
:Sigmoid函数。
:第l层第j个节点的偏置。
:第l层第j个节点的输出。
:输出层第j个节点的目标值(Target value)。
输出层权值调整
给定训练集和模型输出(这里没有上标l是因为这里在讨论输出层,l是固定的),输出层的输出误差(或称损失函数吧)定义为:
其实就是所有实例对应的误差的平方和的一半,训练的目标就是最小化该误差。怎么最小化呢?看损失函数对参数的导数呗。
将E的定义代入该导数:
无关变量拿出来:
看到这里大概明白为什么非要把误差定义为误差平方和的一半了吧,就是为了好看,数学家都是外貌协会的。
将=(输出层的输出等于输入代入Sigmoid函数)这个关系代入有:
对Sigmoid求导有:
要开始耍小把戏了,由于输出层第k个节点的输入等于上一层第j个节点的输出乘上,即=,而上一层的输出是与到输出层的权值变量无关的,可以看做一个常量,是线性关系。所以对求权值变量的偏导数直接等于,也就是说:=()=。
然后将上面用过的=代进去就得到最终的:
为了表述方便将上式记作:
其中:
隐藏层权值调整
依然采用类似的方法求导,只不过求的是关于隐藏层和前一层的权值参数的偏导数:
老样子:
还是老样子:
还是把Sigmoid弄进去:
把=代进去,并且将导数部分拆开:
又要耍
以上是关于从神经网络到深度学习的主要内容,如果未能解决你的问题,请参考以下文章