--- tags: Knock Knock! Deep Learning --- Day 3 / Deep Learning 簡介 / 細解 Deep Learning(二) —— Training === 前面提到了訓練一個 Neural Network 包含 prediction 和 training 兩大步。這篇會深入介紹一下 training 這一步。 本篇數學偏難,但實際應用並不需要完全理解,所以不需擔心看不懂喔。這邊撐過去後面好玩多了! ## Training 在取得 prediction 之後,我們會計算這個預測值跟實際答案的誤差,並反向回饋給 network 裡的 parameters。後面這步也稱 **backpropagation**。訓練步驟大致如下: 1. 用 loss / error function 計算誤差程度 2. 把 loss 從 network 最後一層往前傳,每個 parameter 會計算自己對這個 loss 有多少「貢獻」,並且修正自己 ### Loss Function Loss function 決定這個 network 是怎麼衡量誤差的,因此會根據資料屬性不同選擇不同的 loss function。 我們通常用 $\hat{y}$ 代表 prediction,$y$ 代表 label。以下介紹兩種常見 loss function 和應用場合: || Mean Squared Error (MSE) | Cross-Entropy Loss | |------| -------- | -------- | |Function| $L = (y - \hat{y})^2$ | $L = -\sum^C_{i} y_i \log \hat{y}_i$ | |應用場合|Regression|Multiclass classification| 注意式子都是針對單一 data sample。 MSE 適用預測一個數值的 regression ,因此 $y$ 和 $\hat{y}$ 都是 scalar value(純量)。 Cross-Entropy 則適用預測種類的 multiclass classification,前篇有提到在做 multiclass classification 最後 output 會是 $C$ 個機率值($C$ 為種類數),所以這裡 $y$ 和 $\hat{y}$ 是大小為 $C$ 的 vector,$y_i$ 和 $\hat{y}_i$ 則是 vector 的第 $i$ 個值。而 cross-entropy loss 就是每個種類計算 $y_i \log(\hat{y}_i)$ 並加總。 這邊注意的是 $y$ 其實是 **one-hot vector**,也就是整個 vector 只有一個位置是 $1$ 其餘為 $0$,而 $1$ 就在正確種類的位置。所以說雖然在做加總,實際上只會有一個 $y_i = 1$,所以式子可以簡化為 $L = -\log(\hat{y}_c)$,$c$ 為正確種類的位置。是不是簡單很多? > 在 multiclass classification 有時候 $y$ 也可以是 scalar value,代表正確種類的位置。不管是數學式子還是寫 code 時用到的 loss function,都應該依照前後文判斷 $y$ 是 scalar 還是 vector。 > 對 Cross-Entropy 這個式子感到恐懼的我理解你,這是在 information theory 裡衡量兩個機率分佈有多不一樣的一個方法,deep learning 新手就使用就好,阿密陀佛。 ### Backpropagation 要來到重頭戲了。切記先複習一下 matrix differentiation(矩陣微分),以及 partial differentiation(偏微分)的概念。 這邊有很多數學,所以先來張圖比較好講解: ![two-layer network](https://i.imgur.com/i630Dbz.png) *—— Two hidden layer network for binary classification。[1]* 這邊我們用 $[\ell]$ 來表示第 $\ell$ 層,$(i)$ 來表示第 $i$ 筆資料。$\mathbf{W}$、$\mathbf{b}$、$\mathbf{a}$、$\mathbf{z}$ 都參照前篇介紹的表示法。 好,我們在右端計算了 loss $L$,現在要從右到左告知 network 裡的所有 parameters 他們做得有多差,請他們修正自己以減少下次的 loss。 那要怎麼知道需要往哪裡修正多少?這就跟 **Gradient Descent(梯度下降法)** 有關了。 #### Gradient Descent ![loss function visualization](https://i.imgur.com/9qyYjeQ.jpg) *—— Sample loss function visualization。[2]* 先來視覺化一下 loss function。圖中 $\theta$ 是一個 vector,$\theta_i$ 為第 $i$ 個 parameter,這個簡單的 model (跟前面圖的 model 不同)總共有兩個 parameter,而 $L(\mathbf{\theta})$ 是 loss 值。 目前我們 model 的 parameter 在紅點點那邊,造成的 loss 很高,可以說是表現很差。而綠點點是 model 能得到最好的表現,因為誤差最小。我們希望可以讓 parameter 的值往綠點點的方向移動。 這聽起來很簡單。但在現實世界裡,parameters 可不只兩個,維度一高圖形可就沒那麼簡單,要知道綠點的準確位置一點都不實際。但有個辦法:就往低處走吧?水往低處流,雖然不一定會走在捷徑上,總有一天也會到谷底。 也就是找出橘色的向量。仔細一看,他好像是⋯⋯紅點在曲面上的切線? 還記得怎麼在二維平面找出一條切線的斜率嗎?沒錯,取 derivative $\frac{d f(x)}{d x}$。那麼在高維空間找切線呢?那肯定就是取 gradient 了。 Gradient 可以說是多維度的 derivative,基本上就是幫 vector 裡的所有值取 partial derivative。以這張圖為例,對 parameters 取 gradient 為: $$ \nabla L(\theta) = \begin{bmatrix} \frac{\partial L(\theta)}{\partial \theta_1} \\ \frac{\partial L(\theta)}{\partial \theta_2} \end{bmatrix} $$ > Partial derivative (偏微分)很簡單啦,就是針對一個維度取微分。方法跟微分一樣,但把其他維度的值當成常數即可。 所謂 descent 就是下降,所以 **gradient descent 就是找出並沿著切線,一路盲目往低處走,以尋找最佳解**。 #### Finding Gradients for Model Parameters 介紹完 gradient descent,回到原本的 model,我們是要讓 parameters 知道自己要往哪個方向修正對吧。沒錯,就是計算 $L$ 對 $\mathbf{W}^{[1]}, \mathbf{W}^{[2]}, \mathbf{W}^{[3]}, \mathbf{b}^{[1]}, \mathbf{b}^{[2]}, \mathbf{b}^{[3]}$ 的 gradient。 因為是做分類問題,我們用 cross-entropy 當作 loss function: $$ L = -[(1 - y) \log (1 - \hat{y}) + y \log \hat{y}] $$ > 這裡因為是 binary classification,$y$ 是 scalar value 1 或 0。 所以有以下 6 組 gradient 要算: $$ \frac{\partial L}{\partial \mathbf{W}^{[\ell]}} \text{ for } \ell = 1, 2, 3 \\ \frac{\partial L}{\partial \mathbf{b}^{[\ell]}} \text{ for } \ell = 1, 2, 3 $$ 相信到這邊大家一定腦袋空白。好前面我都懂,但課本讀完讀題目怎麼像之前什麼都沒讀過?完全沒有頭緒。 總之,我們先從最後一層看起。我們會看到如果一層一層往前算,搭配微積分裡的 **Chain Rule**,計算方法會簡化許多。 > 先複習一下 chain rule。他是用來取 composite function $f(g(x))$ 的微分的: > > $$ > \frac{df(g(x))}{dx} = \frac{df(z)}{dx} = \frac{df(z)}{dz} \frac{dz}{dx} = \frac{df(z)}{dz} \frac{dg(x)}{dx} > $$ > > where $z = g(x)$。 ##### Gradients for the Last Layer ![network back](https://i.imgur.com/vkKBWm3.png) 我們先看一下最後一層,$\hat{y}$ 是怎麼計算出來的: $$ \hat{y} = \mathbf{a}^{[3]} = g(\mathbf{z}^{[3]}) = g(\mathbf{W}^{[3]}\mathbf{a}^{[2]} + \mathbf{b}^{[3]}) $$ 這邊因為是 binary classification,$g$ 為 sigmoid function。 這一層有兩組 parameters: $\mathbf{W}^{[3]}$ 和 $\mathbf{b}^{[3]}$。我們示範 $\mathbf{W}^{[3]}$ 就好。如果要硬幹他的 gradient 的話,結合前幾個式子,可以得到: $$ \frac{\partial L}{\partial \mathbf{W}^{[3]}} = -\frac{\partial}{\partial \mathbf{W}^{[3]}}[(1 - y) \log (1 - \hat{y}) + y \log \hat{y}] \\ = -\frac{\partial}{\partial \mathbf{W}^{[3]}}[(1 - y) \log (1 - g(\mathbf{W}^{[3]}\mathbf{a}^{[2]} + \mathbf{b}^{[3]})) + y \log g(\mathbf{W}^{[3]}\mathbf{a}^{[2]} + \mathbf{b}^{[3]})] $$ 喂等等先不要離開啊!我們沒有要嘗試化簡這個式子的意思。雖然現在上下有 $\mathbf{W}^{[3]}$ 可以開始手算,但實在太複雜,而且對 engineering 來說也很不實際。總不會寫一個 network 就要把這些式子爆開 code 進去吧? 這時候我們應用 chain rule,優雅的簡化成三步驟: $$ \frac{\partial L}{\partial \mathbf{z}^{[3]}} = -\frac{\partial}{\partial \mathbf{z}^{[3]}} [(1 - y) \log (1 - \hat{y}) + y \log \hat{y}] = \mathbf{a}^{[3]} - y \\ \frac{\partial \mathbf{z}^{[3]}}{\partial \mathbf{W}^{[3]}} = \mathbf{a}^{[2]T} \\ \Rightarrow \frac{\partial L}{\partial \mathbf{W}^{[3]}} = \frac{\partial L}{\partial \mathbf{z}^{[3]}}\frac{\partial \mathbf{z}^{[3]}}{\partial \mathbf{W}^{[3]}} = (\mathbf{a}^{[3]} - y)\mathbf{a}^{[2]T} $$ 不只數學計算簡單多了,在寫程式的時候,也可以把這些步驟分開來,並針對不同 loss 或 activation function 寫 gradient,分別計算後乘在一起就行。 > 詳細數學推導請見 [1] p.11-12,或自己練習。 > $\frac{\partial \mathbf{z}^{[3]}}{\partial \mathbf{W}^{[3]}} = \mathbf{a}^{[2]T}$ 是怎麼來的? > > 首先 $\mathbf{z}^{[3]} = \mathbf{W}^{[3]}\mathbf{a}^{[2]} + \mathbf{b}^{[3]}$,因為取偏微分所以 $\mathbf{b}^{[3]}$ 當常數微掉變 0,$\mathbf{W}^{[3]}\mathbf{a}^{[2]}$ 也可以想像成 $x \cdot c$ 對 $x$ 微分剩 $c$,所以剩 $\mathbf{a}^{[2]}$。 > > 那為什麼要取 transpose 呢?因為對 matrix $A$ 微分的結果必然是 $A$ 的形狀。$\mathbf{W}^{[3]}$ 的形狀是 $1 \times 2$,$\mathbf{a}^{[2]}$ 是 $2 \times 1$,所以要取 transpose 才符合 $\mathbf{W}^{[3]}$ 的形狀! > 蛤你又問為什麼知道 $\mathbf{W}^{[3]}$ 和 $\mathbf{a}^{[2]}$ 的形狀? > > 第二層有兩個 node 所以 $\mathbf{a}^{[2]}$ 是 $2 \times 1$,而第三層有幾個 node 就有幾個 bias,所以 $\mathbf{b}^{[3]}$ 是 $1 \times 1$。最後 $\mathbf{W}^{[3]}\mathbf{a}^{[2]} + \mathbf{b}^{[3]}$ 的結果取決於第三層有幾個 node 所以是 $1 \times 1$,所以 $\mathbf{W}^{[3]}\mathbf{a}^{[2]}$ 會是 $1 \times 1$,那 $\mathbf{W}$ 自然是 $1 \times 2$。 > > 更直觀的看法就是 $W^{[i]}$ 會是 $n_{i} \times n_{i-1}$,$n_i$ 代表第 $i$ 層有幾個 node。 > 好了小秘訣都說完了,不可以再抱怨太複雜因為很多資料連小秘訣都沒有。 ##### Gradients for Previous Layers ![network front](https://i.imgur.com/C6HQGaZ.png) 運用 chain rule,先把 forward propagation 的式子列出來,再由後往前找出對中間值的 gradient,就能依樣畫葫蘆找出其他 $\frac{\partial L}{\partial \mathbf{W}^{[\ell]}}$ 和 $\frac{\partial L}{\partial \mathbf{b}^{[\ell]}}$ 了。 也因為要先從後面的 layer 開始計算,並把結果往前送,這個過程才被稱為 **backpropagation**。 那就試著自己找出前面幾個 parameter 的 gradient 吧。還是不熟悉的可以參考 [1] p.11-12! 上面取 gradient 的部分應該是全系列最數學的地方,我也盡量提供一些訣竅幫助理解。如果反覆看幾次還是如在霧裡,那我跟你說沒關係,應用方面需要理解的數學不會這麼深! #### Parameter Update 好的,那還記得我們取 gradient 是尬麻嗎?是要找出往低處走的方向。找出來以後,我們要實際讓這些 parameters 邁出步伐,修正自己。 修正的方式很簡單: $$ \mathbf{\theta}^{[\ell]} = \mathbf{\theta}^{[\ell]} - \alpha \frac{\partial L}{\partial \mathbf{\theta}^{[\ell]}} $$ 這邊我們統稱 parameters 為 $\theta$,就是 $\mathbf{W}$ 和 $\mathbf{b}$ 啦。 我們知道剛剛讓人困擾終於搞懂的 $\frac{\partial L}{\partial \theta^{[\ell]}}$ 是我們要前進的方向,那 $\alpha$ 就是步伐大小了。我們稱之為 **learning rate**,也就是學習速率。減號是因為是要減小 $L$ 的值,所以是走 $L$ 的負方向。用此方式 update,parameters 就會往低處前進了。 那老師,為什麼不就走很大步就好呢?這樣不就學很快? 我們來看看這張圖: ![learning rate](https://i.imgur.com/PEVqT01.png) *—— Learning rate 影響學習成果。[4]* Learning rate 太低的話,training 會很慢;但太高的話,又容易走過頭。因此選擇適當的 learning rate 其實是一門藝術!後面也會講到怎麼依據學習情況自動調節 learning rate。 ## Checkpoint - MSE 和 cross-entropy loss 分別適用於哪些情況? - Gradient descent 的目的是什麼?為什麼會被用在 neural network 的訓練中? - 在 neural network 裡,我們具體要找出什麼的 gradient? - 利用 chain rule 計算 gradient 有什麼好處? - 為什麼 parameter 要由後往前 update(為什麼是 backpropagation)? - Learing rate 的大小會怎麼影響訓練? ## 參考資料 1. [👍 CS229 Lecture Notes - Deep Learning](http://cs229.stanford.edu/summer2020/cs229-notes-deep_learning.pdf) 2. [梯度下降法及反向传播小结](https://zhuanlan.zhihu.com/p/37065664) 3. [Khan Academy - Chain rule](https://www.khanacademy.org/math/ap-calculus-ab/ab-differentiation-2-new/ab-3-1a/a/chain-rule-review) 4. [Setting the learning rate of your neural network.](https://www.jeremyjordan.me/nn-learning-rate/) ## 延伸閱讀 1. [CS224n Readings - Review of differential calculus theory](http://web.stanford.edu/class/cs224n/readings/review-differential-calculus.pdf) 2. [CS231n Handouts - Derivatives, Backpropagation, and Vectorization](http://cs231n.stanford.edu/handouts/derivatives.pdf) 3. [CS224n Readings - Computing Neural Network Gradients](http://web.stanford.edu/class/cs224n/readings/gradient-notes.pdf)