1.7 重談多層神經網路與BP演算法實現

本章內容只是介紹最簡單的演算法推演過程,並不涉及優化過程。程序放在了github上僅供參考example1.7.1.py

回想我們對於第1.6章內容的推演過程就會發現,演算法中梯度扮演了十分重要的作用。那麼現在需要學習的BP演算法也應該是基於梯度的,假設規定的誤差函數為:

mathcal{E}=|vec{d}-vec{y}|=sqrt{sum_{i}{(d_i-y_i)^2} }=sqrt{sum_{i}{e_i^2} }

記多層神經網路信息更新的方式為:

y^{[n]}=f(y^{[n-1]}cdot w^{[n]})

我們的目標是求得所有的w=w^{[1]},w^{[2]},ncdotsnw^{[N]},顯然我們應該建立的函數梯度該對所有w求偏導:

nabla_w mathcal{E}=frac{mathcal{E}}{w^{[1]}}n+ncdotsn+frac{mathcal{E}}{w^{[N]}}

在理論之上其實是計算技巧,顯然直接計算frac{mathcal{E}}{w^{[1]}}是比較困難的,為了減少這個困難我們從某一層開始看:

frac{mathcal{E}}{w^{[N]}}=nf({y^{[N-1]}}cdot w^{[N]})*(d-y^{[N]})^T cdot y^{[N]}n=nmathcal{M}^{[N]} y^{[N]}

對第下一層求導:

frac{mathcal{E}}{w^{[N-1]}}=nf({y^{[N-2]}}cdot w^{[N-1]}) * nw^{[N]}cdot [f({y^{[N-1]}}cdot w^{[N]}) *(d-y^{[N]})^T] cdot y^{[N-1]}n=nmathcal{M}^{[N-1]} y^{[N-1]}

顯然這個傳遞關係是顯而易見的:

mathcal{M}^{[N-1]}=f(x)*[w^{[N]} cdot mathcal{M}^{[N-1]}]

這裡有個運算符號:

*:vec{x}*vec{y}=[x_1y_1,cdots,x_ny_n]

上面的遞推過程是從最後一個到第一個反向遞推的,當然在一些書籍里將其稱之為反向傳播演算法,這是基於誤差傳播的方向而言的。可能圖形化的更好理解一些,但是對於演算法實現而言顯然用公式表示更加合適。

當然在進行「反向計算」的過程中首先需要做的,就是按照信號遞推公式

進行正向計算。而後在進行誤差的反向計算,寫成程序的函數:

def back_forward(self,dest):n self.e[self.layer-1]=dest-self.y[self.layer-1]n temp_delta=self.e[self.layer-1]*self.d_sigmoid_v[self.layer-1]n temp_delta=np.reshape(temp_delta,[-1,1])n self.dW[self.layer-2][:]=np.dot(np.reshape(self.y[self.layer-2],[-1,1]),np.transpose(temp_delta))n self.db[self.layer-2][:]=np.transpose(temp_delta)n #print(self.dW[self.layer-2])n for itrn in range(self.layer-2,0,-1):n sigma_temp_delta=np.dot(self.W[itrn],temp_delta)n temp_delta=sigma_temp_delta*np.reshape(self.d_sigmoid_v[itrn],[-1,1])n self.dW[itrn-1][:]=np.dot(np.reshape(self.y[itrn-1],[-1,1]),np.transpose(temp_delta))n self.db[itrn-1][:]=np.transpose(temp_delta)n

這裡為了與TensorFlow作對比,單獨的將偏置b提了出來,但是遞推公式並沒有發生明顯的變化。只是加入了一個關於b的偏導項

利用1.5章的抑或函數的測試數據:

那麼最終得到的圖形為:

類比於TensorFlow得到的圖形:

可以說這個迭代的程序思路是成功的。


推薦閱讀:

關於神經網路輸入標準化
用Python實現BP神經網路(附代碼)
什麼是 DQN (強化學習)
Learn R | 機器學習中的人工神經網路(四)
神經網路普遍性的直觀解釋

TAG:TensorFlow | 神经网络 | 深度学习DeepLearning |