這個是我之前搞LeNet卡了好一陣子的項目,由於網路上的資料也是很少,所以就把它寫出來(拖了一兩個月了…).這個在很多packages都是現成的功能,一般來說只需要知道原理就好了.但之前為了能夠徹底了解整個CNN的運作,就自己從頭到尾實作一次LeNet-5,也因此得詳細地把過程推導一次,這篇文就是紀錄推導的過程,有誤還請各位不吝指正,感謝.
這次假設核心的大小是5*5,如下圖
為了方便說明,我把輸入的陣列調整成9*9,如下圖
由於反向傳播會根據正向傳播的方式不同而有所變化,因此得先列出正向傳播的過程,才能講解相對應的反向傳播.
正向傳播
首先是輸入和卷積核執行卷積程序,其中b為bias,完成後的陣列為y,大小為5*5:
卷積輸出後,每個y陣列中的元素都會經過激活函數(activate function),這邊用tanh函數當例子,活化後的陣列為z,大小為5*5,如下圖:
z陣列就是我們這個神經元要傳到下個層的輸出了.以上就是正向傳播的程序.接下來講解反向傳播的程序.
反向傳播
為了方便說明,陣列E的每個元素都已經是誤差源頭對z陣列的每個元素的偏微分的結果(可參考鏈鎖律),為5*5的陣列(和z陣列同大小),如下圖:
卷積核權重誤差更新
誤差對卷積核權重之偏微分推導如下,以第一個元素w11為例:
推導出來後,核元素w11即可更新,如下公式,其中𝛾為學習速率:
相同的規則,核元素w12如下:
w55如下:
最後可歸納出一個公式來表達卷積核的權重更新:
卷積核bias誤差更新
類似於權重更新,推導如下:
由於bias是個純量,所以只有一個元素,因此就直接歸納其數學公式和誤差更新的數學公式,如下:
誤差回傳至輸入端
這個就比較複雜一點,因為對輸入端x陣列來說,並不是每個元素都和每個輸出有關聯,比如說x11只有在卷積y11的時候才有用到,在其他y陣列的元素上都沒參與到,因此誤差陣列也不一定每個元素都會回傳到x陣列的每個元素上,詳細推導如下:
因為在正向傳遞的過程中x11全程只有在生成y11時和w11作用過一次,最後只有E11回傳.
而x12在生成y11和y12都有參與到,因此E11和E12都有回傳.
而x55有參與到y陣列所有元素的生成,因此誤差陣列的所有元素都有回傳.
x99只有參與生成y55,因此最後只有E55回傳.
最後可以歸納出誤差對輸入端的偏微分公式
根據鏈鎖律,這個即可成為回傳上一層的誤差陣列.