動手實踐神經網路3: 用Excel實現多層全連接神經網路
前兩篇文章分享了單個神經元的訓練和調優,接下來我們進入多層(除了輸入和輸出層包含至少一個隱層)全連接神經網路。
這裡先不考慮使用Python或TensoFlow編程實現多層神經網路,而是使用Excel聯繫多層全連接神經網路的前向計算和誤差反向傳播,目標有兩點
1. 較之於程序代碼,Excel上手更容易,可以幫助初學者快速建立概念
2. 編程實現神經網路的過程中,最大的困難在於如何檢查實現結果是否正確。單純的Code Review顯然無法有效發現所有Bug,從軟體測試的角度,測試用例需要清晰的定義出程序的輸入和預期輸出。進一步,僅僅知道輸入和預期輸出還不夠,還需要運算中重要中間結果量,以便程序輸出結果與預期不符時,通過檢查不同階段的中間變數定位出問題的Root Cause。基於上述考慮,我想到了通過電子表格計算出神經網路前向和反向的每一步結果,一方面可以作為自己寫的神經網路程序的單元測試例;另一方面也在計算的過程中更加形象的理解神經網路。
本文提到的表格可以從筆者GitHub得到,下載地址如下
https://github.com/wangyaobupt/SimpleNeuralNetwork/tree/master/unitTestDoc
本文參考了斯坦福大學的BP演算法在線教程,參考文獻如下
[1]Backpropagation_Algorithm
網路結構定義
這裡我們考慮只包含一個輸入層、一個輸出層、一個隱含層的3層神經網路,每層兩個神經元,其結構如下圖所示
上述節點從輸入層開始編號,輸入層定義為第0層,隱層定義為第1層,輸出層定義為第2層。除了輸入層,每一層都包含與前一級的連接,每個連接都有權重值。激活函數選用signmoid函數。上述神經網路可以在Excel中用如下形式表示,其中每一層的參數介紹如下
- 「src節點j=0」與"dst節點i=0"的交叉點表示從上一層第0個節點到本層第0個節點的weight
- "dst節點i=0"與「bias節點」的交叉點表示本層第0個節點的bias取值
前向計算
假定輸入數據為(1,2),輸入層(第0層)不包含計算邏輯,所以第0層的激活值就是(1,2)
此後的兩層,神經網路每個單元激活值來自於前一層的輸入、自己的weight、自己的bias三者計算的結果。
以下圖的格式為例,「第1層激活值」與「節點0」的交點表示第一層節點0的輸出,計算公式為
1/(1+EXP(-1*($C$12*$C5+$C$13*$D5+$E5)))
標籤和Loss
將神經網路的訓練目標考慮為線性分隔問題,對於輸入數據(1,2),分為第二類。
分類結果用one-hot vector表示:第一類標籤定義為(1,0),第二類標籤定義為(0,1)
Loss值定義為神經網路輸出值與標籤的歐氏距離平方的一半,計算Loss的公式如上圖公式欄所示。神經網路的訓練目標定義為Loss值儘可能小誤差反向傳播第一步:計算逐點誤差
所謂逐點誤差,就是這個神經元節點對最終誤差的"貢獻"是多少,在斯坦福大學的一份在線教材中(Backpropagation Algorithm)[1],定義如下
for each node i in layer l, we would like to compute an "error term" that measures how much that node was "responsible" for any errors in our output.
基於教材中的描述,筆者嘗試翻譯整理如下
1. 對於輸出層節點,每個神經元的逐點誤差就是Loss函數對這個神經元激活函數輸入值的導數。寫成公式表示為
上述公式中y_i表示標籤中第i個維度的值,表示輸出層第i個節點的值,是輸出層第i個節點激活函數的輸入值。f(x)是激活函數,具體到我們的例子里,就是sigmoid函數,就是sigmoid函數的導函數,數學上給出
2. 對於隱層節點,每個神經元的逐點誤差
教材中給出的公式如下
上述公式可以用下圖形象化表示,圖中每個變數的上標都是層序號,下標表示在一層中的節點序號,黃色箭頭表示計算逐點誤差的方向
技術上述分析,電子表格中可以按照如下形式計算逐點誤差
誤差反向傳播第二步:計算誤差對每個變數的梯度
有了逐點誤差,梯度的計算就非常簡單,對於上述教材[1]中的數學公式,我這裡簡化描述如下
對於權重參數weight:每個節點的某個權重參數,梯度等於這個節點的逐點誤差 乘以 前一層另一個節點的激活值
對於偏置參數bias:這一層這個節點的逐點誤差
嚴格的數學公式由教材[1]給出
基於梯度調整權重並重新計算Loss當得到Loss函數對每個參數的梯度之後,就可以按照梯度下降方向結合學習率調整參數。舉例來說,對於某個參數,梯度為2,這意味著這個參數增加1,最終Loss就增加2,所以必須將這個參數向小的方向調。即
調整後的參數值 = 調整前的參數值 + (-1)*梯度*學習率
學習率假定為0.03,神經網路調整如下
調整後重新計算Loss,比第0次前向計算的Loss下降,這體現了BP演算法對神經網路參數的訓練效果。更多資料
這個系列整理自我的技術博客:王堯的技術博客。博客中的內容體系性不如在知乎整理的清楚,但會隨時記錄工作中的技術問題和發現,如有興趣歡迎圍觀。
推薦閱讀:
※先睹為快:神經網路頂會ICLR 2018論文接受結果速覽
※ML + System = ?
※神經網路告訴我,誰是世界上最「美」的人?
※論文解讀 | 基於神經網路的知識推理
※從下往上看--新皮層資料的讀後感 第一部分:皮層細胞
TAG:深度學習DeepLearning | 神經網路 |