吴恩达机器学习:神经网络 | 反向传播算法

上一周我们学习了 神经网络 | 多分类问题。我们分别使用 逻辑回归神经网络 来解决多分类问题,并了解到在特征数非常多的情况下,神经网络是更为有效的方法。这周的课程会给出训练 神经网络 所使用的 代价函数,并使用 反向传播 算法来计算梯度。笔者会给出 反向传播 算法中重要的思路和推导,但不会包含所有的计算步骤。

点击 课程视频 你就能不间断地学习 Ng 的课程,关于课程作业的 Python 代码已经放到了 Github 上,点击 课程代码 就能去 Github 查看( 无法访问 Github 的话可以点击 Coding 查看 ),代码中的错误和改进欢迎大家指出。

以下是 Ng 机器学习课程第四周的笔记。

代价函数

假设我们的多分类问题有 K K 个分类,神经网络共有 L L 层,每一层的神经元个数为 sl s l ,那么神经网络的 代价函数 为:

J(Θ)=1mi=1mk=1K(y(i)klog(hΘ(x(i)))k+(1y(i)k)log(1(hΘ(x(i)))k))+λ2ml=1L1i=1slj=1sl+1(Θ(l)ji)2 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

其中的第二项为 正则化 项,是网络中所有权值的平方和。第一项与逻辑回归中的 代价函数 类似,但这里我们需要累加所有输出神经元的误差。

梯度计算

为了能够使用 梯度下降 算法来训练网络,我们需要计算代价函数的梯度。一种很直观的方法就是使用数值计算,对于某个 Θij Θ i j ,给它加上减去一个很小的量 ϵ ϵ 来计算梯度:

J(θ)θjJ(θ1,,θj+ϵ,,θn)J(θ1,,θjϵ,,θn)2ϵ ∂ J ( θ ) ∂ θ j ≈ J ( θ 1 , ⋯ , θ j + ϵ , ⋯ , θ n ) − J ( θ 1 , ⋯ , θ j − ϵ , ⋯ , θ n ) 2 ϵ

但稍微分析一下算法的复杂度就能知道,这样的方法十分缓慢。对于每一组数据,我们需要计算所有权值的梯度,总的计算次数 = 训练数据个数 x 网络权值个数 x 前向传播计算次数 。在通常情况下这样的复杂度是无法接受的,所以我们仅使用这个方法来验证 反向传播 算法计算的梯度是否正确。

链式法则

为了能够理解之后对于 反向传播 公式的推导,我们首先要了解一个关于多元复合函数求导的 链式法则。对于多元函数 z=f(u,v) z = f ( u , v ) ,其中 u=h(x,y) u = h ( x , y ) v=g(x,y) v = g ( x , y ) ,那么:

zx=zuux+zvvxzy=zuuy+zvvy ∂ z ∂ x = ∂ z ∂ u ∂ u ∂ x + ∂ z ∂ v ∂ v ∂ x ∂ z ∂ y = ∂ z ∂ u ∂ u ∂ y + ∂ z ∂ v ∂ v ∂ y

链式法则 告诉我们有多个层次的多元复合函数,下一层次的导数可以由上一层次推得。
吴恩达机器学习:神经网络 | 反向传播算法_第1张图片
上图中笔者有意多加了一层,这里 p p u,v u , v 的函数, q q u,v u , v 的函数, z z p,q p , q 的函数。对于要计算的 zx ∂ z ∂ x zy ∂ z ∂ y ,上式仍成立,原因是我们可以把 z z 看作 u,v u , v 的函数。这相当于我们把:

zx=zppuux+zppvvx+zqquux+zqqvvx ∂ z ∂ x = ∂ z ∂ p ∂ p ∂ u ∂ u ∂ x + ∂ z ∂ p ∂ p ∂ v ∂ v ∂ x + ∂ z ∂ q ∂ q ∂ u ∂ u ∂ x + ∂ z ∂ q ∂ q ∂ v ∂ v ∂ x

简化为了只与上一层相关,利用上一层计算完成的结果 zu ∂ z ∂ u zv ∂ z ∂ v 而不用从头算起:

zx=zuux+zvvx ∂ z ∂ x = ∂ z ∂ u ∂ u ∂ x + ∂ z ∂ v ∂ v ∂ x

一般的,对于函数 y y ,如果它能看做 z1,z2,zn z 1 , z 2 ⋯ , z n 的函数,而 zi z i t t 的函数,则:

yt=i=1nyzizit ∂ y ∂ t = ∑ i = 1 n ∂ y ∂ z i ∂ z i ∂ t

神经网络就是一个层次很多的多元函数,我们可以隐约从 链式法则 中感觉到反向传播的意味。

公式推导

为了施展 反向传播 的魔法,我们首要要引入一个中间变量 δ δ ,定义为:

δlj=Jzlj δ j l = ∂ J ∂ z j l

其中 l l 为第几层, j j 表示第 l l 层的第几个神经元, z z 为上次课程提到的中间变量( 为了让式子看上去更清晰,反向传播 中的公式上标不使用括号 )。 δ δ 被称为第 l l 层第 j j 个神经元的误差。反向传播 就是先计算每一层每个神经元的误差,然后通过误差来得到梯度的。

首先来看输出层的误差:

δLj=JzLj δ j L = ∂ J ∂ z j L

对它使用 链式法则 得到:

δLj=k=1KJaLkaLkzLj δ j L = ∑ k = 1 K ∂ J ∂ a k L ∂ a k L ∂ z j L

而只有当 k==j k == j 时,右边部分才不为 0 0 ,所以:

δLj=JaLjaLjzLj=JaLjg(zLj)=aLjyLj(1) (1) δ j L = ∂ J ∂ a j L ∂ a j L ∂ z j L = ∂ J ∂ a j L g ′ ( z j L ) = a j L − y j L

对于其它层的误差:

δlj=Jzlj δ j l = ∂ J ∂ z j l

使用 链式法则

δlj=k=1sl+1Jzl+1kzl+1kzlj=k=1sl+1δl+1kzl+1kzlj δ j l = ∑ k = 1 s l + 1 ∂ J ∂ z k l + 1 ∂ z k l + 1 ∂ z j l = ∑ k = 1 s l + 1 δ k l + 1 ∂ z k l + 1 ∂ z j l

而其中:

zl+1k=p=1slΘlkpg(zlp)+blk z k l + 1 = ∑ p = 1 s l Θ k p l g ( z p l ) + b k l

求偏导得:

zl+1kzlj=Θlkjg(zlj) ∂ z k l + 1 ∂ z j l = Θ k j l g ′ ( z j l )

所以:

δlj=k=1sl+1Θlkjδl+1kg(zlj)=k=1sl+1Θlkjδl+1kalj(1alj)(2) (2) δ j l = ∑ k = 1 s l + 1 Θ k j l δ k l + 1 g ′ ( z j l ) = ∑ k = 1 s l + 1 Θ k j l δ k l + 1 a j l ( 1 − a j l )

最后同样使用 链式法则 来计算:

JΘlij=k=1sl+1Jzl+1kzl+1kΘlij=k=1slδl+1kzl+1kΘlij ∂ J Θ i j l = ∑ k = 1 s l + 1 ∂ J ∂ z k l + 1 ∂ z k l + 1 ∂ Θ i j l = ∑ k = 1 s l δ k l + 1 ∂ z k l + 1 ∂ Θ i j l

由于:

zl+1k=p=1slΘlkpg(zlp)+blk z k l + 1 = ∑ p = 1 s l Θ k p l g ( z p l ) + b k l

只有当 k=i k = i p=j p = j 时留下一项:

JΘlij=g(zlj)δl+1i=aljδl+1i(3) (3) ∂ J Θ i j l = g ( z j l ) δ i l + 1 = a j l δ i l + 1

反向传播

有了 (1) (2) (3) 式,就可以来完成 反向传播 算法了( 需要注意的是刚才所推导的式子都是针对一组训练数据而言的 )。

  1. 对于所有的 l,i,j l , i , j 初始化 Δlij=0 Δ i j l = 0
  2. 对于 m m 组训练数据, k k 1 1 取到 m m
    • a1=x(k) a 1 = x ( k )
    • 前向传播,计算各层激活向量 al a l
    • 使用 (1) 式,计算输出层误差 δL δ L
    • 使用 (2) 式,计算其它层误差 δL1,δL2,...,δ2 δ L − 1 , δ L − 2 , . . . , δ 2
    • 使用 (3) 式,累加 Δlij Δ i j l Δlij:=Δlij+aljδl+1i Δ i j l := Δ i j l + a j l δ i l + 1
  3. 计算梯度矩阵:
    Dlij=1mΔlij+λmΘlij1mΔ(l)ijif j0if j=0 D i j l = { 1 m Δ i j l + λ m Θ i j l if  j ≠ 0 1 m Δ i j ( l ) if  j = 0
  4. 更新权值 Θl:=Θl+αDl Θ l := Θ l + α D l

权值初始化

最后提一下权值的初始化。对于神经网络,不能像之前那样使用相同的 0 值来初始化,这会导致每层的 逻辑单元 都相同。因此我们使用随机化的初始化方法,使得 δΘlijδ − δ ≤ Θ i j l ≤ δ

So~,这周学完了 神经网络 和它的学习算法,大家有没有觉得很神奇呢?

你可能感兴趣的:(吴恩达机器学习,吴恩达,Coursera,神经网络,反向传播,Python)