http://www.cnblogs.com/python27/p/MachineLearningWeek05.htm
这一章多是Andrew Ng讲得最不清楚的一章,为何这么说呢?这一章主要讲后向传播(Backpropagration, BP)算法,Ng花了一大半的时间在讲如何计算偏差项δ,如何计算Δ的矩阵,以及如何用Matlab去实现后向传播,然而最关键的问题——为何要这么计算?前面计算的这些量到底表明着什么,Ng基本没有讲解,也没有给出数学的推导的例子。因此此次内容我不打算照着公开课的内容去写,在查阅了许多资料后,我想先从一个简单的神经网络的梯度推导入手,理解后向传播算法的基本工做原理以及每一个符号表明的实际意义,而后再按照课程的给出BP计算的具体步骤,这样更有助于理解。html
简单神经网络的后向传播(Backpropagration, BP)算法
1. 回顾以前的前向传播(ForwardPropagration, FP)算法
FP算法仍是很简单的,说白了就是根据前一层神经元的值,先加权而后取sigmoid函数获得后一层神经元的值,写成数学的形式就是:python
2. 回顾神经网络的代价函数(不含regularization项)
J(Θ)=−1m[∑i=1m∑k=1Ky(i)klog(hθ(x(i)))k+(1−y(i)k)log(1−(hθ(x(i)))k)]web
3. 一个简单神经网络的BP推导过程
BP算法解决了什么问题?咱们已经有了代价函数J(Θ),接下来咱们须要利用梯度降低算法(或者其余高级优化算法)对J(Θ)进行优化从而获得训练参数Θ,然而关键问题是,优化算法须要传递两个重要的参数,一个代价函数J(Θ),另外一个是代价函数的梯度∂J(Θ)∂Θ,BP算法其实就是解决如何计算梯度的问题。算法
下面咱们从一个简单的例子入手考虑如何从数学上计算代价函数的梯度,考虑以下简单的神经网络(为方便起见,途中已经给出了前向传播(FP)的计算过程),该神经网络有三层神经元,对应的有两个权重矩阵Θ(1)和Θ(2),为计算梯度咱们只须要计算两个偏导数便可:∂J(Θ)∂Θ(1)和∂J(Θ)∂Θ(2)。网络
首先咱们先计算第2个权重矩阵的偏导数,即∂∂Θ(2)J(Θ)。首先咱们须要在J(Θ)和Θ(2)之间创建联系,很容易能够看到J(Θ)的值取决于hθ(x),而hθ(x)=a(3), a3又是由z(3)取sigmoid获得,最后z(3)=Θ(2)×a(2),因此他们之间的联系能够以下表示:数据结构
按照求导的链式法则,咱们能够先求J(Θ)对z(3)的导数,而后乘以z(3)对Θ(2)的导数,即函数
由z(3)=Θ(2)a(2)不难计算∂z(3)∂Θ(2)=(a(2))T,令∂∂z(3)J(Θ)=δ(3),上式能够重写为post
接下来仅须要计算δ(3)便可,由上一章的内容咱们已经知道g′(z)=g(z)(1−g(z)), hθ(x)=a(3)=g(z(3)),忽略前面的1/m∑i=1m(这里咱们只对一个example推导,最后累加便可)优化
至此咱们已经获得J(Θ)对Θ(2)的偏导数,即atom
接下来咱们须要求J(Θ)对Θ(1)的偏导数,J(Θ)对Θ(1)的依赖关系以下:
根据链式求导法则有
咱们分别计算等式右边的三项可得:
带入后得
令δ(2)=δ(3)(Θ(2))Tg′(z(2)), 上式能够重写为
把上面的结果放在一块儿,咱们获得J(Θ)对两个权重矩阵的偏导数为:
观察上面的四个等式,咱们发现
- 偏导数能够由当前层神经元向量a(l)与下一层的偏差向量δ(l+1)相乘获得
- 当前层的偏差向量δ(l)能够由下一层的偏差向量δ(l+1)与权重矩阵Δl的乘积获得
因此能够从后往前逐层计算偏差向量(这就是后向传播的来源),而后经过简单的乘法运算获得代价函数对每一层权重矩阵的偏导数。到这里算是终于明白为何要计算偏差向量,以及为何偏差向量之间有递归关系了。尽管这里的神经网络十分简单,推导过程也不是十分严谨,可是经过这个简单的例子,基本可以理解后向传播算法的工做原理了。
严谨的后向传播算法(计算梯度)
假设咱们有m个训练example,L层神经网络,而且此处考虑正则项,即
J(Θ)=−1m[∑i=1m∑k=1Ky(i)klog(hθ(x(i)))k+(1−y(i)k)log(1−(hθ(x(i)))k)]+λ2m∑l=1L−1∑i=1sl∑j=1sl+1(Θ(l)ji)2
初始化:设置Δ(l)ij=0 (理解为对第l层的权重矩阵的偏导累加值)
For i = 1 : m
- 设置 a(1)=X
- 经过前向传播算法(FP)计算对各层的预测值a(l),其中l=2,3,4,…,L
- 计算最后一层的偏差向量 δ(L)=a(L)−y,利用后向传播算法(BP)从后至前逐层计算偏差向量 δ(L−1),δ(L−1),…,δ(2), 计算公式为δ(l)=(Θ(l))Tδ(l+1).∗g′(z(l))
- 更新Δ(l)=Δ(l)+δ(l+1)(a(l))T
end // for
计算梯度:
BP实际运用中的技巧
1. 将参数展开成向量
对于四层三个权重矩阵参数Θ(1),Θ(2),Θ(3)将其展开成一个参数向量,Matlab code以下:
1
|
thetaVec = [Theta1(:); Theta2(:); Theta3(:)];
|
2. 梯度检查
为了保证梯度计算的正确性,能够用数值解进行检查,根据导数的定义
Matlab Code 以下
1
2
3
4
5
6
7
|
for
i
= 1 : n
thetaPlus = theta;
thetaPlus(
i
) = thetaPlus(
i
) + EPS;
thetaMinus = theta;
thetaMinus(
i
) = thetaMinus(
i
) - EPS;
gradApprox(
i
) = (J(thetaPlus) - J(thetaMinus)) / (2 * EPS);
end
|
最后检查 gradApprox 是否约等于以前计算的梯度值便可。须要注意的是:由于近似的梯度计算代价很大,在梯度检查后记得关闭梯度检查的代码。
3. 随机初始化
初始权重矩阵的初始化应该打破对称性 (symmetry breaking),避免使用全零矩阵进行初始化。能够采用随机数进行初始化,即 Θ(l)ij∈[−ϵ,+ϵ]
如何训练一个神经网络
- 随机初始化权重矩阵
- 利用前向传播算法(FP)计算模型预测值hθ(x)
- 计算代价函数J(Θ)
- 利用后向传播算法(BP)计算代价函数的梯度 ∂J(Θ)∂Θ(l)
- 利用数值算法进行梯度检查(gradient checking),确保正确后关闭梯度检查
- 利用梯度降低(或者其余优化算法)求得最优参数Θ
附:一个简短的后向传播教学视频
参考文献
[1] Andrew Ng Coursera 公开课第五周
[2] Derivation of Backpropagation. http://web.cs.swarthmore.edu/~meeden/cs81/s10/BackPropDeriv.pdf
[3] Wikipedia: Backpropagation. https://en.wikipedia.org/wiki/Backpropagation
[4] How the backpropagation algorithm works. http://neuralnetworksanddeeplearning.com/chap2.html
[5] 神经网络和反向传播算法推导. http://www.mamicode.com/info-detail-671452.html