Back Propagation 實作 in Python

Source: Deep Learning on Medium

Back Propagation 實作 in Python

作為開始經營部落格的第一篇文章,動機有兩個:

  1. 快畢業了,想要累積除了Github以外的文字作品
  2. 最近在用numpy手作DL的各種layer,想要用部落格來記錄學習歷程

首先 先上剛出爐的FC (Fully Connected) layer 的 class:

以前就斷斷續續的用numpy寫過MLP以及CNN,但總覺得都沒有一個系統,層跟層之間的接口寫得很差,model一改變就要整個打掉重練,我的理想是可以寫出像keras一樣的layer功能,不論CNN還是FC,都能有接口可以互相連接。目前施工進度只完成了FC,在實作BP的時候,縱使BP四大公式已經歷經幾十次的推導跟背得熟捻,還是遇到了一些問題,這篇部落格紀錄一下走過的錯誤,以及當下的盲點。

BP四大公式:

Source: http://neuralnetworksanddeeplearning.com/chap2.html

這邊先推該Source網頁,學習BP的過程就是靠著細啃那篇文章!! (我大概細讀了四五次,每次讀都會有新的領悟,學習一個困難的東西就是靠不斷地複習阿….不過到現在可能還是沒有全盤理解,以下BP內容有誤請多多指導!)

回歸主題:

在實作一個DL層的時候,會遇到的問題真的太多太多了….這篇會主要專注在當輸入為Batch的情形下時, 𝛿 的處理。

根據BP第二公式,處理淺層 𝛿的時候,會需要下一層的 𝛿值,沒有batch輸入的時候好處理,𝛿值就只有一組,但假設現在batch=16,每一層的𝛿值都會有16組,在我剛開始實作的時候,我把那16個𝛿值取了平均再傳給淺層利用,所以當時的程式碼看起來是這樣:

這是簡化了許多的程式碼,不過也比較好理解,第一行就是在實作BP的第二公式,第二行就是平均所有batch的部分,最後一行要回傳𝛿是為了繼續傳播計算更淺層的𝛿。

後來發現這樣train下去,是可以運作的,但總覺得收斂的速度奇慢,我也知道這樣處理其實不太合邏輯,所有BP推導過程都是基於單一sample,但我卻直接取了一個平均,而且根據BP第四公式,前一層的輸出也是batch,把平均過後的𝛿值套在不同的sample的輸出上也很不合理,總之不知道當時腦子怎麼了就這樣實作下去了,然後竟然還可以train的起來,不過相比我文章開頭的實作,performance大概少了30%左右。

當最後我把batch中的每一個𝛿都分開來作BP,更新weight的時候再根據batch的大小作weight gradient的算數平均,才變成現在的樣子,train的過程也順利了許多,在很前期的訓練就可以達到training data set的100%準確度。

※我使用的dataset是以前在一門課上的自製類似mnist的手寫數字,由於data少,難度比mnist高,有興趣可以到我的github下載 https://github.com/hankerkuo/LeCun_Networks_1989

所以這次的教訓:

在處理BP實作的時候,不同於明確的公式們,會遇到的是無盡的問題們!不只這次遇到的batch問題,之後要繼續實作的CNN,不論是1-D到N-D,應該還會遇到不少問題,到時候實作前,審慎觀察BP的傳播路徑,要更為嚴謹的處理每一行程式碼。

這次的分享就先到這(雖然很懶都沒有解釋code在幹嘛),往後如果有遇到值得提及的DL from Scratch問題,還會再上來和大家分享。