首先,我们需要定义一些后面用到的变量:
和前面一样,想要使得模型最优,我们必须要 min J ( Θ ) \min J(\Theta) minJ(Θ),为了实现这一目标,最关键的就是要求解 ∂ ∂ Θ i , j ( l ) J ( Θ ) \frac{∂}{∂\Theta_{i,j}^{(l)}}J(\Theta) ∂Θi,j(l)∂J(Θ)。何以求解?我们遵循下面的步骤就可以了。
反向传播算法步骤:
假设我们有数据集 { ( x ( 1 ) , y ( 1 ) ) . . . ( x ( m ) , y ( m ) ) } \{(x^{(1)},y^{(1)})...(x^{(m)},y^{(m)})\} {(x(1),y(1))...(x(m),y(m))}
对于1至m样本
不得不说,反向传播算法还是比较复杂和晦涩难懂的,吴恩达教授在视频中也提到,其实他也没能完全吃透神经网络这个黑盒子的机制道理。但不得不承认神经网络所训练出来的模型确实好用,准确度很高。
如何理解 δ \delta δ呢?我们还是先回忆一下神经网络的代价函数。
J ( Θ ) = − 1 m ∑ i = 1 m ∑ k = 1 K [ y k ( i ) l o g ( ( h Θ ( x ( i ) ) ) k ) + ( 1 − y k ( i ) ) l o g ( 1 − ( h Θ ( x ( i ) ) ) k ) ] + λ 2 m ∑ l = 1 L − 1 ∑ i = 1 s l ∑ j = 1 s l + 1 ( Θ j , i ( l ) ) 2 J(\Theta)=-\frac{1}{m}\sum\limits_{i=1}^{m}\sum\limits_{k=1}^{K}[y_k^{(i)}log((h_\Theta(x^{(i)}))_k)+(1-y_k^{(i)})log(1-(h_\Theta(x^{(i)}))_k)]+\frac{\lambda}{2m}\sum\limits_{l=1}^{L-1}\sum\limits_{i=1}^{s_l}\sum\limits_{j=1}^{s_{l+1}}(\Theta_{j,i}^{(l)})^2 J(Θ)=−m1i=1∑mk=1∑K[yk(i)log((hΘ(x(i)))k)+(1−yk(i))log(1−(hΘ(x(i)))k)]+2mλl=1∑L−1i=1∑slj=1∑sl+1(Θj,i(l))2
如果我们假设我们是二分类(K=1),而且没有正则化。那么代价函数为:
c o s t ( t ) = y ( t ) l o g ( h Θ ( x ( t ) ) ) + ( 1 − y ( t ) ) l o g ( 1 − h Θ ( x ( t ) ) ) cost(t)=y^{(t)}log(h_{\Theta}(x^{(t)}))+(1-y^{(t)})log(1-h_\Theta(x^{(t)})) cost(t)=y(t)log(hΘ(x(t)))+(1−y(t))log(1−hΘ(x(t)))
直观来看, δ j ( l ) \delta^{(l)}_j δj(l)就是 a j ( l ) a^{(l)}_{j} aj(l)的相对于准确值误差,更正规地来讲, δ j ( l ) \delta^{(l)}_j δj(l)是代价函数的导数值。
即: δ j ( l ) = ∂ ∂ z j ( l ) c o s t ( t ) \delta^{(l)}_j=\frac{∂}{∂z_{j}^{(l)}}cost(t) δj(l)=∂zj(l)∂cost(t)
接下来用一个例子来演示一下。
看上面这张图,假设我们要计算 δ 2 ( 2 ) \delta^{(2)}_2 δ2(2),我们需要找到其所在节点右侧连接的下一层的所有节点及其连接边( δ 1 ( 3 ) , δ 2 ( 3 ) , Θ 12 ( 2 ) , Θ 22 ( 2 ) \delta^{(3)}_1,\delta^{(3)}_2,\Theta^{(2)}_{12},\Theta^{(2)}_{22} δ1(3),δ2(3),Θ12(2),Θ22(2))。然后计算 δ 2 ( 2 ) = Θ 12 ( 2 ) δ 1 ( 3 ) + Θ 22 ( 2 ) δ 2 ( 3 ) \delta^{(2)}_2=\Theta^{(2)}_{12}\delta^{(3)}_1+\Theta^{(2)}_{22}\delta^{(3)}_2 δ2(2)=Θ12(2)δ1(3)+Θ22(2)δ2(3)。
按照这个规律,我们就是从右至左,利用下一层的信息和连接边的权重,不断的更新 δ j ( l ) \delta^{(l)}_j δj(l),这就是反向传播。
为了更好的用代码实现反向传播过程,有时候,我们要把一些参数进行展开,向量化。比如:
Θ ( 1 ) , Θ ( 2 ) , Θ ( 3 ) , . . . \Theta^{(1)},\Theta^{(2)},\Theta^{(3)},... Θ(1),Θ(2),Θ(3),...
D ( 1 ) , D ( 2 ) , D ( 3 ) , . . . D^{(1)},D^{(2)},D^{(3)},... D(1),D(2),D(3),...
它们用下面的代码展开:
thetaVector = [ Theta1(:); Theta2(:); Theta3(:); ]
deltaVector = [ D1(:); D2(:); D3(:) ]
如果Theta1的维度是10*11,Theta2的维度是10*11,Theta3的维度是1*11,我们通过下面的代码可以转换回来。
Theta1 = reshape(thetaVector(1:110),10,11)
Theta2 = reshape(thetaVector(111:220),10,11)
Theta3 = reshape(thetaVector(221:231),1,11)
为了保证导数计算出的梯度的正确性,我们使用传统数学方法粗略的计算某一点附近的( − ϵ , ϵ -\epsilon,\epsilon −ϵ,ϵ)大致梯度,从而实施梯度检查。
我们知道,一个函数的导数可以这样写:
∂ ∂ Θ J ( Θ ) ≈ J ( Θ + ϵ ) − J ( Θ − ϵ ) 2 ϵ \frac{∂}{∂\Theta}J(\Theta)≈\frac{J(\Theta+\epsilon)-J(\Theta-\epsilon)}{2\epsilon} ∂Θ∂J(Θ)≈2ϵJ(Θ+ϵ)−J(Θ−ϵ)
当存在多变量时, ∂ ∂ Θ j J ( Θ ) ≈ J ( Θ 1 , . . . , Θ j + ϵ , . . . , Θ n ) − J ( Θ 1 , . . . , Θ j − ϵ , . . . , Θ n ) 2 ϵ \frac{∂}{∂\Theta_j}J(\Theta)≈\frac{J(\Theta_1,...,\Theta_j+\epsilon,...,\Theta_n)-J(\Theta_1,...,\Theta_j-\epsilon,...,\Theta_n)}{2\epsilon} ∂Θj∂J(Θ)≈2ϵJ(Θ1,...,Θj+ϵ,...,Θn)−J(Θ1,...,Θj−ϵ,...,Θn)
一般情况下 ϵ = 1 0 − 4 \epsilon=10^{-4} ϵ=10−4,效果比较好,太小会导致数值问题。
对应的matlab代码如下:
epsilon = 1e-4;
for i = 1:n,
thetaPlus = theta;
thetaPlus(i) += epsilon;
thetaMinus = theta;
thetaMinus(i) -= epsilon;
gradApprox(i) = (J(thetaPlus) - J(thetaMinus))/(2*epsilon)
end;
值得注意的一点是,一旦你确定了偏微分的正确性,便可以禁用梯度检查代码。因为如果不这样做,代码运行速度会大大降低。
在神经网络中,如果将 Θ \Theta Θ全部初始为0,那么神经网络将无法被良好的训练,因为这样的情况下,经过反向传播,同一层所有节点都会被更新到相同的值和状态,也就是说,同一层节点再多也没用。
那么如何进行随机初始化呢?,请看下图:
总之,就是要将 Θ \Theta Θ随机限定在 [ − ϵ , ϵ ] [-\epsilon,\epsilon] [−ϵ,ϵ]内。
对应MATLAB代码如下:
If the dimensions of Theta1 is 10x11, Theta2 is 10x11 and Theta3 is 1x11.
Theta1 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
Theta2 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
Theta3 = rand(1,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
首先选择一个合适的神经网络结构,包括:
接着训练神经网络,步骤为:
下面这张图演示了当反向传播计算时,代价函数的变化情况:
可以看出,有时候,我们可能不会进入全局最优,而会陷入局部最优。
链接: Coursera Machine Learning.