Python · 神經網路(四*)· 網路
(這裡是最終成品的 GitHub 地址)
(這裡是本章用到的 GitHub 地址)
推薦先修章節:Python · 神經網路(三*)· 網路、Python · 神經網路(四)· 網路
與 tensorflow 版本類似,我們要先定義一個能把輸入變成輸出的函數(輸出函數)和一個用來訓練我們模型的函數(訓練函數)、然後定義一些函數評估我們的模型。由於不像 tensorflow 那樣把最終損失化為了一個數、所以我們的輸出函數(前向傳導演算法)相比之下形式很簡單:
def _get_activations(self, x): _activations = [self._layers[0].activate( x, self._weights[0], self._bias[0])] for i, layer in enumerate(self._layers[1:]): _activations.append(layer.activate( _activations[-1], self._weights[i + 1], self._bias[i + 1])) return _activations
需要指出的是,由於 BP 演算法是自己實現的、所以需要把激活值記錄下來以減少 BP 演算法中的計算量(因為許多激活函數【比如 Sigmoid】的導函數用函數值來算會比用輸入算塊一些)
訓練函數的話就比 tensorflow 版本要複雜了、因為要手動進行梯度下降:
def fit(self, x=None, y=None, lr=0.01, epoch=10): # Initialize self._add_cost_layer() self._init_optimizers(lr) layer_width = len(self._layers) # Train for counter in range(epoch): # 如有必要,更新優化器中的參數 self._w_optimizer.update(); self._b_optimizer.update() # 調用前向傳導演算法獲取各個激活值 _activations = self._get_activations(x) # 調用反向傳播演算法獲得各個局部梯度 _deltas = [self._layers[-1].bp_first(y, _activations[-1])] for i in range(-1, -len(_activations), -1): _deltas.append(self._layers[i - 1].bp( _activations[i - 1], self._weights[i], _deltas[-1] )) # 調用相應方法進行參數的更新 for i in range(layer_width - 2, 0, -1): self._opt(i, _activations[i - 1], _deltas[layer_width-i-1]) self._opt(0, x, _deltas[-1])
可以看到裡面用了大量 Optimizers 相關的東西,若有需要的話可以參見這篇文章;這裡我們只需知道 self._opt 這個函數能夠利用激活值和梯度幫我們更新相應的變數就行
可能會有觀眾老爺注意到我在定義 _deltas 這個存儲梯度的列表時調用的是 bp_first 函數,這是什麼意思呢?不知大家還記不記得、在 BP 演算法推導過程中、最後一層(亦即 CostLayer)的梯度計算和其餘層是不太一樣的,這裡這個 bp_first 即是 CostLayer 對應的 BP 演算法
模型搭好之後就能跑一跑並評估一下了。我寫了一個小的可視化函數並生成了一個螺旋線數據來進行測試和評估,效果大概如下:
模型結構是兩層 ReLU 各 24 個神經元,CostLayer 是 Softmax + Log Likelihood,Optimizers 選擇的是 Adam。迭代了 1000 次,耗時 1 秒左右。值得一提的是,用 tensorflow 來訓練的話要 3 秒左右(GPU 版本),觀眾老爺可以想想這是為什麼 ( σ"ω")σ (事實上,tensorflow 本身不適合用於訓練規模太小的模型、不僅限於這一種情況)以上,一個完整的純 Numpy 實現的神經網路結構就搭建完了,合共 150 行 Python 代碼,比 tensorflow 版本的要長一些
希望觀眾老爺們能夠喜歡~
推薦閱讀:
※如何評估神經網路演算法的計算量,從而來確定需要多少GPU的投入?
※在神經網路中,激活函數sigmoid和tanh除了閾值取值外有什麼不同嗎?
※你心中的deep learning(深度學習)領域世界十大名校是哪些?
※scikit learn 里沒有神經網路?
※神經網路中,bias有什麼用,為什麼要設置bias,當加權和大於某值時,激活才有意義?