Backward Propagation in nn.Module
本文接續 Torch NN Tutorial 4: Backward Propagation (part 1) ,與 Torch NN Tutorial 5: Backward Propagation (part 2) 講解 nn.Module
中, 與 backward propagation 有關的程式碼。
nn.Module
程式碼:https://github.com/torch/nn/blob/master/Module.lua
與 backward propagation 有關的,主要有以下三個運算 :
而這三個運算,分別對應到以下三個 function :
-
zeroGradParameters
-
backward
-
updateParameters
本文將詳細講解這三個 function 的程式碼內容。
註:
1.本文的 同前兩篇文(Torch NN Tutorial 4~5)中的 。
2.本文中的 為矩陣,而 , 為向量。
1.zeroGradParameters
此步驟是將 和 歸零。
在程式中, 和 的變數是 gradWeight
和 gradBias
。可用 zeroGradParameters
將它們歸零,程式碼如下:
1 2 3 4 5 6 7 8 |
|
在第五行中,可看到 gradParams[i]:zero()
,即是將所有的 gradParams
,包含 gradWeight
及 gradBias
歸零。
由於 nn.Module
本身沒有 gradWeight
和 gradBias
,如果要取得它們,就要透過 self:parameters()
來取得。
parameters
的程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 |
|
從第二行開始,可看到,如果繼承 nn.Module
的類別有實作 weight
,則回傳 weight
和 gradWeight
,以此類推。
至於歸零的作用,因為在建立 Module 的時候, gradWeight
和 gradBias
並沒有被設為什麼值,它有可能是任意數。舉個例子,建立一個 nn.Linear
,命名為 l1
, input size 為 2, output size 為 3,一開始什麼都沒做,就直接印出 gradWeight
和 gradBias
,程式如下:
1 2 3 |
|
得出結果如下,它們可能是任意數:
1 2 3 4 5 6 7 8 9 |
|
如果用 zeroGradParameters
將它們歸零,程式碼如下:
1 2 3 |
|
結果如下,可看到它們都歸零了:
1 2 3 4 5 6 7 8 9 |
|
2.backward
再來看到 backward
的部分, backward
個功能由兩個 function
來執行,分別是 updateGradInput
及 accGradParameters
。
1 2 3 4 5 6 |
|
為何要分這兩部分?從數學公式上來看,如果 input
是 , output
是 ,loss function 為 ,則:
accGradParameters
是負責計算以下兩項,也就是 gradWeight
和 gradBias
的值。
除了以上兩項以外,如果 input 前面還有其他 layer 的話,就需計算 ,並將此值往前傳遞。
updateGradInput
是負責計算 的值,也就是 gradInput
的值,如下:
在 nn.Module
中,這兩個 function 皆沒實作,需由繼承 nn.Module
的類別來實作。
1 2 3 4 5 6 |
|
nn.Linear
則實作了這兩個 function。
nn.Linear
程式碼:https://github.com/torch/nn/blob/master/Linear.lua
updateGradInput
先看 updateGradInput
的程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
此處可分為兩部分來看,在 Torch NN Tutorial 1 : NN.Module & NN.Linear 曾講到,當 input:dim() == 1
時,是一次輸入一筆資料。
計算 gradInput
公式如下:
公式中的 ,在程式中是 loss function 的 gradInput
,並從 updateGradInput
的參數 gradOutput
輸入。
假設 output size 為 3, input size 為 2,則在 forward propagation 時, 是由以下公式算出:
而 的結果如下,
因此, 的值為:
從以上結果得知,要先將 weight
轉置,再和 gradOutput
做 矩陣-向量 乘積。如同程式碼中所寫 self.gradInput:addmv(0, 1, self.weight:t(), gradOutput)
如果 和 的值分別如下:
則, 的值為:
執行 updateGradInput
,程式碼如下:
1 2 3 4 |
|
結果如下:
1 2 3 |
|
以上程式碼,輸入 x
只是為了滿足 input:dim() == 1
的條件, 而 x
的數值是不會影響結果的。
至於 input:dim() == 2
的情況,推導方式同上,在此不詳細推導。
再來看 accGradParameters
的程式碼:
accGradParameters
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
先看到 input:dim() == 1
的情形,計算 gradWeight
的公式如下:
公式中的 ,在程式中是 loss function 的 gradInput
,並從 updateGradInput
的參數 gradOutput
輸入。
假設 output size 為 3, input size 為 2,則 的結果如下,
因此, 的值為:
如果 的值同前例, 的值如下:
則, 的值為:
計算 gradBias
的公式如下:
而 這項的結果如下,
因此, 的值為:
因此, 的值,和 的值相同。
執行 accGradParameters
,程式碼如下:
1 2 3 4 5 |
|
結果如下:
1 2 3 4 5 6 7 8 9 |
|
至於 input:dim() == 2
的情況,推導方式同上,在此不詳細推導。
3.updateParameters
此函數在 nn.Module
中即有實作其內容,它所進行的運算相當簡單,就是更新 和 :
程式碼如下:
1 2 3 4 5 6 7 8 |
|
其中,公式中的 即為程式碼中的 learningRate
,而程式中的第五行,則是負責將 weight
和 bias
更新。 其中, weight
和 bias
由第二行的 parameters
函數所取得,回傳到 param
中,而 gradWeight
和 gradBias
也用同樣方式取得,回傳到 gradParams
中。
假設 , 的值分別如下:
更新 和 :
印出 l1
的 weight
和 bias
,執行 updateParameters
,比較執行前後的 weight
和 bias
差異,程式如下:
1 2 3 4 5 |
|
結果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Materials
本次教學的完整程式碼於此:
https://github.com/ckmarkoh/torch_nn_tutorials/blob/master/6_backward_propagation_part_3.ipynb