Python · 神經網路(二*)· 層

========== 2017.4.23 更新 ==========

比較完整、有條理的說明、實現可以參見這裡

==========分割線的說 ==========

(這裡是最終成品的 GitHub 地址)

(這裡是本章用到的 GitHub 地址)

推薦先修章節:Python · 神經網路(二)· 層、數學 · 神經網路(二)· BP(反向傳播)

這是第一個帶星號的章節,想想還是挺激動的呢(不

我們現在知道了怎麼實現激活函數,但還沒有說如何實現 BP 演算法(反向傳播演算法)、也就是神經網路中的梯度下降演算法。雖然它可能讓許多人望而卻步、但其實需要的工具只有一個——求導的鏈式法則;然後如果把它分成一個個小單元來求解的話,可能就會發現也沒有想像中的那麼難。至少從實現的層面來講,它相當簡單:

當然,這四行代碼後面隱藏的邏輯有些繁複,我們會一一進行說明:

  • 普遍意義下的 BP 演算法對應著最後一行代碼,其中:
    • prev_delta 記錄著反向傳播回來的梯度
    • y 記錄著進行前向演算法時、該層輸入值的激活值,使用激活值作為反向傳播演算法的輸入的原因在講反向傳播演算法的最後有所提及——很多常用的激活函數的導函數使用函數值來定義會比使用自變數來定義要更好
    • self._derivative 是該層激活函數對應的導函數。需要注意的是,它接受的參數是激活值而不是輸入值
  • CostLayer 的 BP 演算法沒有包括在這裡面。具體細節會在今後帶星號的 CostLayer 相關章節中講,這裡說一個大概思路:它會利用它上一層 Layer(我們稱這層 Layer 為該 CostLayer 的爸爸)(……)的導函數來提前算好一個整合後的梯度,從而當它爸爸得到這個梯度時,可以直接把它往後傳而不用再求導

  • 正數第二、第三行對應著當這個 Layer 是 CostLayer 的爸爸時該怎麼做。正如上面提到的,它只需要直接把這個梯度往後傳就行、因為 CostLayer 已經利用它的導函數提前把梯度算好了

在實現完爸爸的 bp 演算法後,由於沒了 tensorflow 那些方便的函數,我們還需要稍微修改一下我們的激活函數:

至於為何要這樣處理,同樣會在帶星號的 CostLayer 相關章節中講到。這裡我們就只需要知道 CostLayer 需要單獨處理就行

我們就需要定義真正幹活的孩兒們(……)了。我們仍然以 sigmoid 為例:

可以看到,沒有了 tensorflow 的函數、所有東西都需要我們自己寫了。不過即使如此,Layer 的實現(在我看來)仍然是相當簡潔的

稍微總結一下:

  1. 除了前傳演算法之外,我們還要實現 BP 演算法。事實上,BP 演算法是神經網路的核心,在其上有著各種各樣的優化演算法
  2. 我們需要區別對待 CostLayer,這主要是因為 CostLayer 的 BP 演算法表現不同

下一章就要講在這種 Layer 分為主 Layer 和 SubLayer 兩種的情況下、我們應該如何去封裝它們的問題了,不知大家是否已經有思路和想法了呢 ( σω)σ

希望觀眾老爺們能夠喜歡~

(猛戳我進入下一章!( σω)σ )


推薦閱讀:

深度壓縮之蒸餾模型
「深度學習」和「多層神經網路」的區別?
關於深度神經網路壓縮(下)
數學 · 神經網路(四)· Normalize

TAG:Python | 机器学习 | 神经网络 |