一、概述
上一集結束之後,學到了score function
,可以用SVM
或者Softmax
計算loss
,可以在loss
中增加regularization
來獲取更加合理的W
,並且最後可以用Analytic Gradient
(微積分)的方式計算loss function
相對於W
的gradient
來更新W
。如下圖。
這一集講了如何使用鏈式法則
來反向傳播gradients
,來更新W
和b
,這個gradients
反向傳播的過程叫做Backpropagation
。
Backpropagation
之後,進入了Neural Network
的介紹。
二、Backpropagation
Computational Graph
在計算
gradient
並進行backpropagate(bp)
的時候,藉助computational graphs(cg)
可以讓整個過程更加清晰(對於新手來說更是這樣)。在學習的起步階段,可以藉助它來理解bp
的原理。但是當神經網絡複雜了之後,再轉換成cg
看起來就很頭疼了。就像這樣。tensorboard
是cg
可視化的一個很強大的工具。一個
computational graph
是對整個神經網絡的直觀圖形表述。上圖中,每一個矩形代表着
input x
和W
;每一個圓代表着一個操作;箭頭指明瞭元素在這個神經網絡中的流向,從輸入開始,一直到最終的loss
輸出。其中,圓被稱爲一個門
gate
。數據每流經一個門,都會經過相應的數學變換。bp
如何實現上圖已經完成了
forward pass
的過程,輸入從左到右,經過+
,*
,得到結果f
。上圖中有三個輸入,
x,y,z
;一個+ gate q
;一個* gate f
;最後得到輸出f = 12
。紅色框中,是
+
這個操作相對於x
,y
的求導;藍色框中,是
*
這個操作相對於+
,z
的求導;bp
的過程,就是將運算順序倒過來,從cg
的最右端開始,利用鏈式法則(Chain Rule),依次將所有前面已經計算的到的導數,和當前元素的導數相乘,就是當前元素的gradient
。從最右端開始,
f
相對於自身的導數是1
。如下圖:繼續往左運算,遇到了
* gate
;這個門的算式就是f = qz
,藍色框中的算式。要求出
z
的gradient
,就是將之前已經計算出的gradient df / df = 1
,與z
本身的gradient
相乘,即(df / df) * (df / dz)
。先求
f
相對於z
的導數,df / dz = q
;由於
q = 3
,因此,z
的gradient df / dz = (df / df) * q = 3
。這個
3
意味着,z
的變化對於f
是正向的。如果z
增加任意H
個單位,那麼f
相應增加3H
個單位。計算結果如圖。
下面計算
q
的gradient df / dq
。藍色框中已經寫了,
df / dq = z
,並且z = -4
。因此,
df / dq = (df / df) * z = -4
。如圖。接下來計算
x
的gradient
。根據
Chain Rule
,x
的gradient df / dx = (df / dq) * (dq / dx)
。因此,
df / dx = -4 * 1 = -4
。如圖。點擊去看
Khan Academy
對於Chain Rule
的講解。以此類推,
y
的gradient
也就能計算出來了。下圖展示了
bp
的一個簡易流程。圖中,
x
,y
,f
,z
各是一個節點,稱之爲node
,每個node
在python中是一個class
。當x
和y
流經f
的時候,f
這個node
已經知道自身相對於x
的gradient
了,這個gradient
叫做local gradient
。在這個簡單的網絡作forward propagate
的時候,node f
就再已經保存了df / dx
的信息,比如,存放在變量self.local_gradient
中,便於之後back propagate
的時候取出來使用。而
bp
的整個過程,就是最右邊開始,把每個節點的local gradient
拿出來,與處於該節點右邊的所有節點的local gradient
相乘,就是該節點的最終gradient
。z
節點右邊沒有節點了,因此z
節點的local gradient
就是dz / dz = 1
,存在self.local_gradient
中。x
節點的gradient
就可以根據f.local_gradient * z.local_gradient
來得到。問題:如果一個節點被多個節點使用,這個節點的
gradient
如何計算?如下圖,如果一個節點被多個節點使用,這個節點的
gradient = local gradient + sum(all_previous_gradients)
左邊的節點作爲輸入被之後的兩個節點使用,那麼在
back propagate
的時候,右邊兩個節點的gradient
要加起來,再乘以左邊節點的local gradient
才能得到左邊節點最終的gardient
。下圖是
forward pass
和back propagate
的一個簡單python實現。在實踐中,在數學允許的情況下,多個
gate
可以被合併成一個gate
,那麼之前多個gate
的gradient
的計算,可以合併到這一個gate
中進行計算。如下面兩張圖。上圖中,所有的
gradient
都是一個一個依次計算的。但那是其中4
個gate
可以合併。上圖中,藍色框中的多個
gate
,可以組合成一個sigmoid gate
,那麼其中4
個單獨gate
的gradient
計算可以合併成一個sigmoid gate
的gradient
計算,其結果不變。樂高積木
上圖看的不是很清楚,大意就是,
Torch
的Git repo
中可以看到,這個框架就是一大堆神經網絡的layer
集合。所以,玩深度學習,玩神經網絡,就像是玩樂高積木一樣,把自己需要的積木塊(layer
)拿出來,拼接在一起,最後組成一個能完成任務的結構。同樣的情況在
Caffe
框架中也能看到。Gradients for vectorized code以及Vectorized operations
這一小節關於
Jcobian matrix
以及Vectorized operations
不是很懂,還需要再查資料體會一下。視頻中說到了
Jacobian matrix
會是一個維度很高的matrix,實踐中是不會去算出整個Jacobian matrix
的。Jacobian matrix
在max()
作爲activation function
的時候,又有一種特殊的結構,就是隻有左上到右下對角線上纔有值,可能是0,可能是非0,而其他值都是0。不是很明白爲什麼說
Vectorized operations
效率很高,同時提到這個Jacobian matrix
是爲了什麼…
三、神經網絡(Neural Network)
這裏討論的神經網絡和大腦的神經網絡有一些聯繫,就是計算機神經網絡借鑑了一些大腦神經元的工作原理。但是其複雜度是無法相提並論的,大腦神經元的複雜度遠高於計算機神經網絡。
更加複雜的神經網絡
所有之前涉及的內容,是一個最簡單的一層神經網絡
f = Wx
。如下圖。下面,就可以再進一步,增加複雜度,構造一個
2層神經網絡
。上圖中,
2層神經網絡
將max activation function
變成了一個hidden layer
。在這個hidden layer
之後,再和W2
作運算,得到一個Output
。上圖中,
hidden layer
有100
個神經元neuron
,這會使這個神經網絡比起之前簡單的版本要強大很多。比如說在下圖中:記得對之前簡單的
Linear Classification
進行訓練之後得到的這些模板,汽車和馬的模板會出現不同的朝向和顏色問題。因爲一層的神經網絡不能處理不同的顏色,不同的朝向。這個問題在增加hidden layer
和大量的神經元之後就能得到進一步的解決。每個神經元
neuron
的作用就是細分前面輸入的數據。比如說,一個神經元可以專門檢測紅色的,朝向前的汽車;一個神經元可以專門檢測黃色的,朝向右邊的汽車;以此類推。那麼這個神經網絡有具備了分類各種顏色和朝向汽車的能力。在
hidden layer
中的每個神經元,可以看作是一個簡單的Linear Classifier
。多個神經元組合在一起,就可以學習很複雜的模型。只需要通過擴展下圖中的公式,就能構造層數更多,更加複雜的神經網絡。
合理的數學編排,可以解決現實生活中很複雜的問題。
2層神經網絡的簡單Python實現
上圖是Andrew Trask對2層神經網絡的實現,其中用的是
logistic loss
,沒有使用SVM
或者Softmax
,但是原理是一樣的。編排神經網絡
經過編排的神經網絡看起來是這樣的,中間的
hidden layer
和最後的output layer
被稱作fully-connected layers
。問題:爲什麼要將神經網絡編排成這個樣子?
像這樣將神經網絡組織成層是爲了更高效率的計算(
Vectorized operation
),輸入只需要按照編排好的順序一層一層流過所有的層即可,不需要額外考慮任何的順序等因素。不同的neuron數量和regularization時lambda的值
hidden layer
中的neuron數量,差不多就像regularization function
中的lambda
的值一樣,被當作hyper parameter
來調整。一般來說,neuron的數量越多越好。neuron越多,這個神經網絡越強大。如下圖。
上圖中,neuron數量越多,分類的效果越好。
但是考慮到時間成本等因素(越多的neuron訓練時間相應就越長),找到一個平衡點上的neuron數量纔是最好的。
另外,可以看到
regularization
時的lambda
的值,也影響着最後的分類效果。如下圖。在當前情況下,
lambda
的值越小,分來效果也就越好。
四、總結
到這裏,已經知道如何進行反響傳播backpropagation
。
知道能將神經網絡編排成層。
這些層的編排,可以讓vectorized operation
很方便的進行。
知道了神經網絡並不是大腦中的神經網絡。
通常情況下,神經網絡越複雜,越強大。但是複雜的神經網絡意味着更長的訓練時間和更小心的規範化(regularization
)。