numpy實現神經網路-反向傳播

HDU平頭哥發表於2020-10-03

參考連結:
https://www.jianshu.com/p/964345dddb70
https://www.cnblogs.com/jsfantasy/p/12177216.html
花了一天學習反向傳播,記錄一下,以便後面回顧。

  1. 反向傳播概念:前向傳遞輸入訊號直至輸出產生誤差,反向傳播誤差資訊更新權重矩陣。類似於反饋系統,通過輸出來影響網路各個層的權值和偏置。
  2. 數學約定:在這裡插入圖片描述
    按照圖示數學符號網路的對網路進行描述,以便進行公示推到。下圖展示了從輸出層反向傳播推匯出第一層的權值,偏置也是類似的,啟用函式採用sigmoid函式,函式的定義與求導如圖。
    sigmoid函式
    反向傳播四大公式單個神經元推到後,我們要進行總結,以便程式設計使用。下圖為總結的公式

BP1:
面向輸出層,C為損失函式,前面部分代表損失函式對輸出層輸出值的求導,後面部分代表輸出層輸入啟用函式的求導,兩者在進行對應元素相乘
BP2:
面向隱藏層,前面部分代表後一層的權值於後一層的後一層的誤差的矩陣乘法,後面部分代表該層輸入啟用函式的求導,兩者在進行對應元素相乘
BP3:
表示第L層偏置的導數等於第L層的誤差
BP4:
表示第L層權值的導數等於前一層輸出值與第L層的矩陣乘法
注意區分矩陣乘法與對應元素相乘的區別
仔細觀察,你會發現BP1與BP2相結合就能發揮出最大功效,可以計算出任意層的誤差,只要首先利用BP1公式計算出輸出層誤差,然後利用BP2層層傳遞,就無敵了,這也正是誤差反向傳播演算法的緣由吧。同時對於權重w以及偏置b我們就可以通過BP3和BP4公式來計算了。

梯度下降公式:
梯度下降公式

關鍵程式碼賞析(反向傳播部分):

 def backpropagation(self, X, y, learning_rate):
        # 反向傳播演算法實現
        output = self.feed_forward(X)# 向前計算,得到最終輸出值
        for i in reversed(range(len(self._layers))):  # 反向迴圈
            layer = self._layers[i]
            if layer == self._layers[-1]:  # 如果是輸出層
                layer.error = y - output # 這裡直接用真實值減去預測值,沒有求導
                #對應公式BP1
                layer.delta = layer.error * layer.apply_activation_derivative(output)
            else:  # 如果是隱藏層
                next_layer = self._layers[i + 1]
                layer.error = np.dot(next_layer.weights, next_layer.delta)
                #對應公式BP2
                layer.delta = layer.error * layer.apply_activation_derivative(layer.activation_output)

        # 迴圈更新權值
        for i in range(len(self._layers)):
            layer = self._layers[i]
            # o_i 為上一網路層的輸出
            o_i = np.atleast_2d(X if i == 0 else self._layers[i - 1].activation_output)
            # 梯度下降公式+BP4公式,delta 是公式中的負數,故這裡用加號
            layer.weights += layer.delta * o_i.T * learning_rate

相關文章