1. 原理篇
我們用人話而不是大段的數學公式來講講全連接神經網絡是怎么一回事。
1.1 網絡結構
靈魂畫師用PPT畫個粗糙的網絡結構圖如下:
1.2 Simoid函數
Sigmoid函數的表達式是:
不難得出:
所以,Sigmoid函數的值域是(0, 1),導數為y * (1 - y)
1.3 鏈式求導
z = f(y)
y = g(x)
dz / dy = f'(y)
dy / dx = g'(x)
dz / dz = dz / dy * dy / dx = f'(y) * g'(x)
1.4 向前傳播
將當前節點的所有輸入執行當前節點的計算,作為當前節點的輸出節點的輸入。
1.5 反向傳播
將當前節點的輸出節點對當前節點的梯度損失,乘以當前節點對輸入節點的偏導數,作為當前節點的輸入節點的梯度損失。
1.6 拓撲排序
假設我們的神經網絡中有k個節點,任意一個節點都有可能有多個輸入,需要考慮節點執行的先后順序,原則就是當前節點的輸入節點全部執行之后,才可以執行當前節點。
2. 實現篇
本人用全宇宙最簡單的編程語言——Python實現了全連接神經網絡,便于學習和使用。簡單說明一下實現過程,更詳細的注釋請參考本人github上的代碼。
2.1 創建BaseNode抽象類
將BaseNode作為各種類型Node的父類。包括如下屬性:
- name -- 節點名稱
- value -- 節點數據
- inbound_nodes -- 輸入節點
- outbound_nodes -- 輸出節點
- gradients -- 對于輸入節點的梯度
2.2 創建InputNode類
用于存儲訓練、測試數據。其中indexes屬性用來存儲每個Batch中的數據下標。
2.3 創建LinearNode類
用于執行線性運算。
- Y = WX + Bias
- dY / dX = W
- dY / dW = X
- dY / dBias = 1
2.4 創建MseNode類
用于計算預測值與實際值的差異。
- MSE = (label - prediction) ^ 2 / n_label
- dMSE / dLabel = 2 * (label - prediction) / n_label
- dMSE / dPrediction = -2 * (label - prediction) / n_label
2.5 創建SigmoidNode類
用于計算Sigmoid值。
- Y = 1 / (1 + e^(-X))
- dY / dX = Y * (1 - Y)
2.6 創建WeightNode類
用于存儲、更新權重。
2.7 創建全連接神經網絡類
2.8 網絡結構
2.9 學習率
存儲學習率,并賦值給所有權重節點。
2.10 拓撲排序
實現拓撲排序,將節點按照更新順序排列。
2.11 前向傳播和反向傳播
2.12 建立全連接神經網絡
2.13 訓練模型
使用隨機梯度下降訓練模型。
2.14 移除無用節點
模型訓練結束后,將mse和label節點移除。
2.15 訓練模型
2.16 預測多個樣本
3 效果評估
3.1 main函數
使用著名的波士頓房價數據集,按照7:3的比例拆分為訓練集和測試集,訓練模型,并統計準確度。
3.2 效果展示
擬合優度0.803,運行時間6.9秒。
效果還算不錯~
3.3 工具函數
本人自定義了一些工具函數,可以在github上查看
1、run_time - 測試函數運行時間
2、load_boston_house_prices - 加載波士頓房價數據
3、train_test_split - 拆分訓練集、測試集
4、get_r2 - 計算擬合優度
總結
矩陣乘法
鏈式求導
拓撲排序
梯度下降