注:本文转载自https://github.com/ysh329/Chinese-UFLDL-Tutorial
因为github上的makedown格式显示的不够完全,看的非常不方便,因此放到CSDN上比较好查阅学习。
多层神经网络(Multi-Layer Neural Network)
考虑一个监督学习问题,即使用带标签的训练样本 (x(i),y(i)) 。神经网络给出一种定义复杂非线性假设的形式 hW,b(x) ,该形式有参数 W,b ,可被用来拟合数据。
说到神经网络,我们从一个最简单的单个神经元的神经网络开始。下面这幅图就表示单个神经元:
该神经元是一个接收 x1,x2,x3 输入的计算单元(其中,有一个输入 +1 是截距项),它会输出 hW,b(x)=f(WTx)=f(∑3i=1Wixi+b) 。其中, f:R↦R 称为“激活函数”。本文选择 S 型函数作为激活函数 f(⋅) :
该神经元被定义为一种逻辑斯特回归形式的输入-输出映射。
尽管本文使用的激活函数是
S
型函数,但双曲正切或正切函数也是常见的激活函数
最近的研表明了一种与众不同的激活函数,校正线性函数(
the Rectified Linear Function
,译者注:但实际中没人这么说,一般都称为
ReLU
),对于深层神经网络的训练,其效果更好。这种激活函数与
S
型函数和双曲正切函数
下图是
S
型函数,双曲正切函数
双曲正切函数
tanh(z)
是
S
型函数的一个缩放版本,其输出范围是
需注意的是,与其它地方( OpenClass ,以及部分 CS229 的课程)不同,截距项的表示没有按照惯例用
最后,说一个在后文有用的恒等式:
神经网络模型(Neural Network model)
神经网络是通过将众多简单的神经元连接在一起得到的,一个神经元的输出可作为另一神经元的输入。例如,这里有一个小神经网络:
图中,用圆圈表示网络输入。圈里被标为 “+1” 的圆圈称为偏置单元,对应于截距项。网络最左边的那一层称为输入层,而输出层即最右层(在这个例子中,输出层只有一个节点)。介于最左(输入层)和最右(输出层)的中间层称为隐藏层,称为“隐藏”是因为其值在训练集中无法观察到。该例中的神经网络有 3 个输入单元(不计偏置单元计算在内), 3 个隐藏单元,和 1 个输出单元。
nl
表示网络的层数;在该例中的神经网络层数
nl=3
。第一层
l
表示为
在后文中,还将用
z(l)i
表示第
l
层的第
需要注意的是,后一种写法更紧凑。具体来说,将激活函数
f(⋅)
应用到向量中的每一个元素上(例如,
f([z1,z2,z3])=[f(z1),f(z2),f(z3)]
),那么可以把上述方程写成一种更紧凑的形式:
这一步称为前向传播(
Forward Propagation
)。可以写成更一般的情况,回顾一下先前使用
a(1)=x
表示输入层的值(译者注:为与下一句对应,因为输入层没有激活函数,输入层
a(1)
相当于第一层的输出),那么第
l
层的激活(输出)表示为
通过组织原本的参数到矩阵中,可以充分利用矩阵操作进行网络参数的快速计算。
从开始到现在,我们都集中在一开始的神经网络的架构上,但也可以建立其它体系结构(即神经元之间的连接模式),比方包括多个隐藏层。最常见的是一个
nl
层网络,层
1
为输入层,层
神经网络的输出层可以有多个输出单元。例如,下图是一个有着 L2 和 L3 两个隐含层,以及在输出层 L4 有两个输出单元的神经网络:
为训练该网络,需要带类别标签的训练样本 (x(i),y(i)) ,其中 y(i)∈R2 。若您的预测需要有多个输出,那么就可以使用这种网络架构。(例如,在医学诊断中的应用,输入特征是向量 x 表示病人的某些特征,需要的输出可能表明不同种疾病(译者注:多个类别)是否存在。)
反向传播算法(Backpropagation Algorithm)
假设有一组固定的训练集
这是一个(半)平方误差函数。给定一组有 m 个样本的训练集,成本函数定义为:
在 J(W,b) 定义中的第一项是均方差项。第二项是一个正则化项(也叫权重衰减项),它会降低权重的大小,并有助于防止过拟合。
(注:权重衰减通常不用在偏置项 b(l)i ),比如 J(W,b) 在定义中就没有使用权重衰减。一般来说,将权重衰减应用到偏置单元中只会对最终的神经网络产生很小的影响。如果您在斯坦福选修过 CS229 (机器学习)课程,或者在 YouTube 上看过该课程视频,您也许会认识到这里的权重衰减,其实是课上提到的贝叶斯正则化方法的变种,在贝叶斯正则化中,高斯先验概率被引入到参数中计算 MAP (极大后验)估计(而不是极大似然估计)。
权重衰减参数
λ
用于控制公式中两项的相对重要性。在此重申一下这两个复杂函数的含义:
以上的代价函数通常被用来解决分类和回归问题。在分类问题上,分别用
y=0
或
1
来表示这两个类标签(回顾一下
优化的目标是最小化把
W
和
梯度下降法中每一次迭代都按照如下公式对参数 W 和 b 进行更新:
其中, α 是学习率,上述公式中一个关键步骤是计算偏导数。现在来讲一下 反向传播 ( Backpropagation )算法,它是一种计算偏导数的高效方法。
首先讲反向传播是如何计算 ∂∂W(l)ijJ(W,b;x,y) 和 ∂∂b(l)iJ(W,b;x,y) 的,以及针对一个样本 (x,y) 的代价函数 J(W,b;x,y) 的偏导数。一旦把这些计算出来了,将会很容易地得到计算所有样本的代价函数 J(W,b) 的偏导数:
上述两个公式略有不同,因为权重衰减应用在参数
W
上,而不是参数
反向传播算法背后的过程如下:给定一个训练样本
(x,y)
,首先前向传递计算整个网络的每层激活,以及假设最终输出的
hW,b(x)
。之后反向回传误差,对每层
l
的每个节点
对输出层节点而言,可以直接计算出网络在该节点的输出值(即激活值)和真实目标值的差距,该值就是误差项 δ(nl)i (第 nl 层是输出层)。
那隐单元的误差项呢?对隐含单元来说,基于误差项的加权平均,即把 a(l)i 作为输入的节点的误差项的加权平均,来计算 δ(l)i ,反向传播算法的描述如下:
- 前向传递计算层 L2,L3 直到输出层 Ln 的激活函数值。
- 对第
Ln
层的第
i
个输出单元,计算该输出单元的误差项
δ(nl)i=∂∂z(nl)i12∥∥y−hW,b(x)∥∥2=−(yi−a(nl)i)⋅f′(z(nl)i) - 循环层数。
For l=nl−1,nl−2,nl−3,…,2
- 循环当前层(第
l
层)节点(第
i 个节点),设定
δ(l)i=⎛⎝∑j=1sl+1W(l)jiδ(l+1)j⎞⎠f′(z(l)i)
- 循环当前层(第
l
层)节点(第
- 计算所需部分的偏微分,如下已给出:
∂∂W(l)ijJ(W,b;x,y)∂∂b(l)iJ(W,b;x,y)=a(l)jδ(l+1)i=δ(l+1)i.
用矩阵或向量的符号标记来重写算法。使用 ∙ 来表示逐个元素的点乘操作(在 Matlab 或 Octave 中,用 .* 表示点乘操作,也称为 Hadamard 乘积)。两个向量对应元素的点乘是 a=b∙c ,逐个元素的点乘表示为 ai=bici 。 f(⋅) 和 f′(⋅) 也都可以应用到向量上,从原本逐个元素的形式改写成等价的形式: f′([z1,z2,z3])=[f′(z1),f′(z2),f′(z3)] 。
现在,矩阵形式的反向传播算法描述如下:
- 前馈传播计算第 2 和 第 3 层( L2,L3 )直到输出层 Ln 的激活函数值。
- 计算输出层(即第
nl
层)与实际值的误差
δ(nl)=−(y−a(nl))∙f′(z(nl)) - 反向循环层数
l
。
For l=nl−1,nl−2,nl−3,…,2 ,反向计算各层每个神经元的误差
δ(l)=((W(l))Tδ(l+1))∙f′(z(l)) - 计算所需部分的偏微分,如下已给出:
∇W(l)J(W,b;x,y)∇b(l)J(W,b;x,y)=δ(l+1)(a(l))T,=δ(l+1).
实现须知:在以上所述的第 2 、第 3 步中,需要计算第
l
层中每个节点
现在,便可以描述完整的梯度下降算法了。下面是伪代码,
- 对所有层
l
,设定矩阵或向量中元素值均为
0 : ΔW(l):=0 , Δb(l):=0 。 -
For i=1 to m
,
- 使用反向传播计算 ∇W(l)J(W,b;x,y) 和 ∇b(l)J(W,b;x,y) 。
- 设定 ΔW(l):=ΔW(l)+∇W(l)J(W,b;x,y) 。
- 设定 Δb(l):=Δb(l)+∇b(l)J(W,b;x,y)
- 更新参数:
W(l)b(l)=W(l)−α[(1mΔW(l))+λW(l)]=b(l)−α[1mΔb(l)]
现在,就可以通过反复迭代上述梯度下降的步骤来训练神经网络,来寻找成本函数 J(W,b) 最小值时候的参数值。