Day-11 Backpropagation 介绍

  • 我们前面提到过深度学习就是模仿神经网路建构一个庞大的训练模型,来达到特徵的选取(调整 weight 的数值来达到决定输入特徵的权重),那我们看过 Gradient Descent 的数值更新状况概念很简单,但实际上我们可以想像当结构变复杂之时,我们可以预期 Gradient Descent 的计算将会变得太过复杂
  • Baskpropagation(反向传递法),就是希望让 neural network 的 training 变得更加有效率
  • 回顾一下 Gradient Descent
    • Network parameters https://chart.googleapis.com/chart?cht=tx&chl=%24%5Ctheta%20%3D%20%7Bw_1%2C%20w_2%2C%20...%2C%20b_1%2C%20b_2%2C%20...%7D%24
    • 先选择一个初始的参数 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Ctheta%5E0%24 ,然後计算这个 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Ctheta%5E0%24 对於我们的 loss function 的 Gradient https://chart.googleapis.com/chart?cht=tx&chl=%24%5Cnabla%20L(%5Ctheta%5E0)%24 ,也就是计算每一个 network 里面的参数对於 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Cnabla%20L(%5Ctheta)%24 的偏微分 https://chart.googleapis.com/chart?cht=tx&chl=%24%24%5Cnabla%20L(%5Ctheta)%20%3D%20%5Cleft%20%5B%20%5Cbegin%7Barray%7D%7Bcc%7D%20%5Cpartial%20L(%5Ctheta)%20%2F%20%5Cpartial%20w_1%20%5C%5C%20%5Cpartial%20L(%5Ctheta)%20%2F%20%5Cpartial%20w_2%20%5C%5C%20%5Ccdots%20%5C%5C%20%5Cpartial%20L(%5Ctheta)%20%2F%20%5Cpartial%20b_1%20%5C%5C%20%5Ccdots%20%5Cend%7Barray%7D%20%5Cright%20%5D%24%24
    • 那我们就会拿到 Gradient,这个 Gradient 会是一个 Vector,就可以利用 Vector 来更新我们的参数 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Ctheta%5E1%20%3D%20%5Ctheta%5E0%20-%20%5Ceta%20%5Cnabla%20L(%5Ctheta%5E0)%24
  • 那我们会重复这个流程直到我们的期望次数,所以可以发现在一般的 Logistic Regression 或是 Linear Regression 在这边的操作是没太多区别的,唯一的问题是 Neural network 的参数非常的多,我们的 Gradient Vector 会变得非常巨大,所以如何有效地去计算这个 Vector,就是 Backpropagation 在做的事情
  • 所以 Backpropagation 并不是一个全新的方法,他说白了就是 Gradient Descent,只是它是一个更有效率的演算法,目的在於更有效率地去取得 Gradient Vector,这也是为什麽之後提到的 PyTorch Gradient Calculation 会交给 Backpropagation 做计算

About Backpropagation

  • 我们提到过 Backpropagation 可以想成一个更有效率的 Gradient Descent 了,那 Backpropagation 有没有特别需要注意的部分呢?
  • 对於 Backpropagation 最重要的的观念就是 Chain Rule(连锁律)

Chain Rule

  • Chain Rule 连锁律其实就是在强调数值之间的关系,那这边为甚麽会这麽重要是因为回顾一下神经网路传递的方式,他们是一层一层的往下传递,因此就最终结果而言,其实是受到初始参数的影响一路往下层层变化的,那这些参数之间对於结果的关系是什麽?其实就会受到连锁律的影响,因此基本的连锁律概念我们在这里简单的帮大家 Summarize 一下
  • Case 1:
    • https://chart.googleapis.com/chart?cht=tx&chl=%24y%20%3D%20g(x)%2C%20z%20%3D%20h(y)%24 的话,如果 x 受到影响,会影响到 y ,进而影响到 z,也就是 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Ctriangle%20x%20%5Cto%20%5Ctriangle%20y%20%5Cto%20%5Ctriangle%20z%24
    • 所以如果我们今天要计算 https://chart.googleapis.com/chart?cht=tx&chl=%24%7Bdz%20%5Cover%20dx%7D%24 ,可以先把它转换成 https://chart.googleapis.com/chart?cht=tx&chl=%24%7Bdz%20%5Cover%20dy%7D%20%7Bdy%20%5Cover%20dx%7D%24
  • Case 2:
    • https://chart.googleapis.com/chart?cht=tx&chl=%24x%20%3D%20g(s)%2C%20y%20%3D%20h(s)%2C%20z%20%3D%20k(x%2C%20y)%24
    • 也就是说 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Ctriangle%20s%20%5Cto%20%5Ctriangle%20x%20%5Cto%20%5Ctriangle%20z%24 ,还有 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Ctriangle%20s%20%5Cto%20%5Ctriangle%20y%20%5Cto%20%5Ctriangle%20z%24 ,s 透过了两个路径去影响到了 z
    • 所以如果我们今天要计算 https://chart.googleapis.com/chart?cht=tx&chl=%24%7Bdz%20%5Cover%20ds%7D%24 ,可以先把它转换成 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20z%20%5Cover%20%5Cpartial%20x%7D%20%7Bdx%20%5Cover%20ds%7D%20%2B%20%7B%5Cpartial%20z%20%5Cover%20%5Cpartial%20y%7D%20%7Bdy%20%5Cover%20ds%7D%24
  • 我们已经回顾了基本的 Chain Rule 在微分时会需要注意的部分,让我们回到 Nueral Network

Basic Nueral Network

  • 我们回到基本的训练过程去做思考,今天我们的 Nueral Network 在做训练的过程是怎麽做训练的?就是我们传递了一笔资料,经过神经网路的计算之後,会得到一个答案,那这个答案可能跟我们的预期答案有所落差,因此我们就可以利用这个落差的总和得到我们的 total loss

    • 所以这边的 https://chart.googleapis.com/chart?cht=tx&chl=%24C%5En%24 就代表着 https://chart.googleapis.com/chart?cht=tx&chl=%24y%5En%24https://chart.googleapis.com/chart?cht=tx&chl=%24%5Chat%20y%5En%24 之间的落差
    • 那如果我们对 loss 和某一个 w 去做偏微分,我们可以发现就等於我把每个参数的 loss 对特定参数 w 的微分加总,就是 loss 对指定的 w 做偏微分了,因此我们之後就可以不用考虑去计算 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20L(%5Ctheta)%20%5Cover%20%5Cpartial%20w%7D%24 ,而改思考对某一笔 data 的 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%5En(%5Ctheta)%20%5Cover%20%5Cpartial%20w%7D%24 就可以了
    • https://chart.googleapis.com/chart?cht=tx&chl=%24L(%5Ctheta)%20%3D%20%5Csum%5Climits_%7Bn%3D1%7D%5EN%20C%5En(%5Ctheta)%20%5Cto%20%7B%5Cpartial%20L(%5Ctheta)%20%5Cover%20%5Cpartial%20w%7D%20%3D%20%5Csum%5Climits_%7Bn%3D1%7D%5EN%20%7B%5Cpartial%20C%5En(%5Ctheta)%20%5Cover%20%5Cpartial%20w%7D%24
  • 那我们从一个简单的 Neural network 来看看,假设我们有一个 network 长下面这样

  • 那我们从某一个 neuron 来看看



    https://chart.googleapis.com/chart?cht=tx&chl=%24z%20%3D%20x_1w_1%20%2B%20x_2w_2%20%2B%20b%24

  • 那我们今天要算 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20w%7D%24 要怎麽算,依照 Chain Rule 我们可以拆成两项,也就是 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20z%20%5Cover%20%5Cpartial%20w%7D%20%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%7D%24
  • 那计算 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20z%20%5Cover%20%5Cpartial%20w%7D%24 其实是非常简单的,我们称为 Forward pass,那计算 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%7D%24 我们则称为 Backward pass,那为啥要叫 forward 跟 backward 我们等等就知道了

Forward pass

  • 先来看看怎麽计算 Forward pass,我们前面有说我们的 https://chart.googleapis.com/chart?cht=tx&chl=%24z%20%3D%20x_1w_1%20%2B%20x_2w_2%20%2B%20b%24 了,所以如果我们希望计算 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20z%20%5Cover%20%5Cpartial%20w_1%7D%24 ,其实就是 https://chart.googleapis.com/chart?cht=tx&chl=%24x_1%24https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20z%20%5Cover%20%5Cpartial%20w_2%7D%24 ,其实就是 https://chart.googleapis.com/chart?cht=tx&chl=%24x_2%24
  • 所以我们可以发现一个规律,当我们想找 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20z%20%5Cover%20%5Cpartial%20w%7D%24 ,事实上就是去看那个 w 前面接的参数,也就是这个神经元的输入
  • 因此如果我们希望找到所有的 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20z%20%5Cover%20%5Cpartial%20w%7D%24 ,就必须先就算正向的参数,也就是我们 input 参数进入之後,一路往下到输出的所有一层一层传递的参数,这也是为甚麽我们称其为 forward pass,因为就是我们一般求输出的正向运算
  • 那这边也是为甚麽我们说找 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20z%20%5Cover%20%5Cpartial%20w%7D%24 是非常简单的,因为根本就是输入参数

Backward pass

  • 那如果我们已经知道 Forward pass 就是顺向/正向运算,那 Backward pass 顾名思义应该就是反向运算了,但是要怎麽做呢?
  • 我们现在要算 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%7D%24 ,我们知道 z 好取得,但是 C 就是要继续往下看一路运算到最後结果,这是非常复杂的,那怎麽办呢?那我们试着再用 Chain rule 拆解看看这一项


    from: ML Lecture 7: Backpropagation

  • 我们先假设接在 Z 後的 activation function(我们之後再解释 QQ) 是 sigmoid function https://chart.googleapis.com/chart?cht=tx&chl=%24a%20%3D%20%5Csigma(z)%24 ,然後输出了一个结果 https://chart.googleapis.com/chart?cht=tx&chl=%24a%24 ,那我们先不管後面的部分,我们在多了一个变数 https://chart.googleapis.com/chart?cht=tx&chl=%24a%24 之後,就可以利用 Chain rule 再把式子拆分成 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%7D%20%3D%20%7B%5Cpartial%20a%20%5Cover%20%5Cpartial%20z%7D%20%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20a%7D%24
  • 那我们先来看 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20a%20%5Cover%20%5Cpartial%20z%7D%24 是什麽,我们已经知道 https://chart.googleapis.com/chart?cht=tx&chl=%24a%20%3D%20%5Csigma(z)%24 ,所以 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20a%20%5Cover%20%5Cpartial%20z%7D%24 其实就是 https://chart.googleapis.com/chart?cht=tx&chl=%24%5Csigma%5E%7B'%7D(z)%24 ,也就是 sigmoid function 的微分
  • https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20a%7D%24 应该长怎样呢? 应该长 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20a%7D%20%3D%20%7B%5Cpartial%20z%5E%7B'%7D%20%5Cover%20%5Cpartial%20a%7D%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%5E%7B'%7D%7D%20%2B%20%7B%5Cpartial%20z%5E%7B''%7D%20%5Cover%20%5Cpartial%20a%7D%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%5E%7B''%7D%7D%24

  • 那我们看上图可以发现 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20z%5E%7B'%7D%20%5Cover%20%5Cpartial%20a%7D%24https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20z%5E%7B''%7D%20%5Cover%20%5Cpartial%20a%7D%24 其实就是後面的 https://chart.googleapis.com/chart?cht=tx&chl=%24w_3%24https://chart.googleapis.com/chart?cht=tx&chl=%24w_4%24 ,那 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%5E%7B'%7D%7D%24https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%5E%7B''%7D%7D%24 呢?怎麽感觉又绕回来一圈了?
  • 我们先整理一下现在 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%7D%24 会长怎样? https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%7D%20%3D%20%5Csigma%5E%7B'%7D(z)%5Bw_3%20%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%5E%7B'%7D%7D%20%2B%20w_4%20%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%5E%7B''%7D%7D%5D%24 ,换句话说我们其实只差最後一个步骤了,也就是我们只差知道 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%5E%7B'%7D%7D%24https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%5E%7B''%7D%7D%24 整个问题就结束了,但是怎麽解?我们换个方向想
  • 如果我们从後面往前推,也就是我们把目标先放在答案那边,从 output layer 往前推

  • 我们可以得到 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%5E%7B'%7D%7D%20%3D%20%7B%5Cpartial%20y_1%20%5Cover%20%5Cpartial%20z%5E%7B'%7D%7D%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20y_1%7D%24https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%5E%7B''%7D%7D%20%3D%20%7B%5Cpartial%20y_2%20%5Cover%20%5Cpartial%20z%5E%7B''%7D%7D%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20y_2%7D%24 ,我们会发现因为 https://chart.googleapis.com/chart?cht=tx&chl=%24y_1%24https://chart.googleapis.com/chart?cht=tx&chl=%24y_2%24 都是已知了,因为我们正向运算一定会算出一个答案,我们的 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20y_1%7D%24https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20y_2%7D%24 就可以利用 Cost function 来决定(例如 MSE),然後 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20y_1%20%5Cover%20%5Cpartial%20z%5E%7B'%7D%7D%24https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20y_2%20%5Cover%20%5Cpartial%20z%5E%7B''%7D%7D%24 也可以运算了
  • 那如果现在不是在 output layer 呢?其实就是一直往下推一路到 output layer 就可以了,因为只有在 output layer ,我们才有办法把 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%5E%7B'%7D%7D%24 这种部份算出来
  • 所以概念上我们就是完全倒过来,从结果一路回推所有的 https://chart.googleapis.com/chart?cht=tx&chl=%24%7B%5Cpartial%20C%20%5Cover%20%5Cpartial%20z%7D%24

每日小结

  • Backpropagation 可以说是深度学习里面最重要的观念了,神经网路的构造复杂,本来就很难去计算和更新参数,因此普通的 Gradient Descent 会遇到很多计算上的困难, Backpropagation 则是利用 Chain Rule 的方式,将计算复杂度大大的下降,并利用一次 Forward pass 加一次 Backward pass 来达到快速更新参数计算参数的方式
  • 本日课程大量参考 李弘毅老师的开放式课程 ,这份教学非常非常好理解 Backpropagation,因此上面看不懂的部分都可以再去看看,笔者当初在学习的过程中,也深受此系列帮助
  • 到这里我们已经完成了基本的观念架设了,明天我们就可以开始介绍 PyTorch Framework 了~

<<:  鬼故事 - Not As Secure

>>:  Day 12 - PHP SDK: 建立信用卡、虚拟帐号订单

Python 练习

今天是我们最後一次的练习了,我们要来解APCS的题目,今天要解的题目是105年3月5的实作题第二题,...

17 - Traces - 观察应用程序的效能瓶颈 (1/6) - Elastic APM 基本介绍

Traces - 观察应用程序的效能瓶颈 系列文章 (1/6) - Elastic APM 基本介绍...

[火锅吃到饱-16] 斗牛士二锅 - 台中文心店

官网有分店资讯 之前在脸书社团就看过版友分享过桃园店的用餐体验,平日午餐328的价位,提供6种肉品吃...

Day25 :【TypeScript 学起来】Class 的继承、修饰符、abstract、static

今天继续笔记class,剩最後5天了! 若有错误,欢迎留言指教,感恩的心。 extends 继承 ...

Day 0x3 UVa10222 Decode the Mad man

Virtual Judge ZeroJudge 题意 输入一加密过字串,解密方式为键盘上向左两格,输...