Python · 神經網路(四)· 網路

(這裡是最終成品的 GitHub 地址)

(這裡是本章用到的 GitHub 地址)

這一章我們會把神經網路這個框架完善,這一章結束後,一個能跑的、自由度相當高的神經網路就新鮮出爐了。Again,由於實現是比較重要的,所以我們先不管介面、只把功能弄出來。同時需要指出的是,我們會用到下一章才講到的損失函數層(CostLayer) Optimizers。這是因為如果應用 tensorflow 的話,這兩者的實現都只是封裝的活兒

為簡潔,我們使用 tensorflow 來作為我們的演算法核心,所以觀眾老爺們可能需要先知道 tensorflow 的一些基本知識。觀眾老爺們如果不想上官網的話可以去看我寫的這個「Tensorflow 應用式入門教程」 ( σ"ω")σ

現在我們已經有了一個整合了各個層和各層之間關聯的結構,接下來要做的就是利用這個結構得到我們想要的東西。為此我們可以通過一張圖來理解:

其中,結構內部的操作我們已經「分而治之」了,接下來要做就是根據結構外部的輸入、產生一個我們想要的輸出。這其實就是前向傳導演算法,我們定義一個函數來實現它:

定義完前傳演算法後,由於我們用的是 tensorflow,所以基本就已經把核心步驟做完了,剩下的基本只是封裝的活兒。為此,需要給出一直以來都沒有給出的、這個結構的初始化函數:

這裡為什麼要定義兩個類呢?

事實上,如果僅僅實現樸素的功能、是沒有必要分成兩個類的。但是不知觀眾老爺是否還記得、我在第零章裡面說過、我們的最終框架支持分形結構、也就是類似於這樣的結構:

在這裡,外面最大的黑框其實是一個 Layer,然後內部的藍色框可以看成是一個小神經網路,每個小的神經網路則又是由若干個 Layer 堆疊而成的

我們自然不希望藍色框代表的小神經網路擁有我們最終版的神經網路那麼多的功能(因為那樣會顯得很臃腫),所以我們可以抽出一些基本的神經網路的功能來組成一個「基本類」,這個基本類在我們的實現中就叫做 NNBase

相對應的,完整版的神經網路就叫做 NNDist,它會繼承 NNBase 並在其基礎上多出一些功能

說明一下之前沒出現過的變數:

  • NNTiming 是一個我自己寫的輔助計算函數耗時的小工具,在這裡有相關的介紹

  • self._optimizers 記錄的是結構用的 Optimizer,其定義下一章會講到

  • self._tfx,self._tfy,self._cost,self._y_pred 和 self._train_step 都是應用 tensorflow 過程中所需要記錄的變數,具體的用處會在用到的時候進行說明

接下來就可以來看訓練我們模型的函數了:

(如果觀眾老爺們對 tensorflow 不太熟悉的話、可能看的會有些不知所以然,此時戳進 tensorflow 的官網或者戳進我這篇文章 ( σ"ω")σ)

可能聰明的觀眾老爺們已經發現了:這個 fit 函數就是拿來訓練我們的模型的、其訓練的原理是最小化模型的損失(損失的定義下一章會講)。也就是說,如果我們想要根據訓練樣本 x,y 來訓練出一個神經網路的話,只需要:

nn = NNDist()nn.add(ReLU((x.shape[1], 24)))nn.add(CrossEntropy((y.shape[1],)))nn.fit(x, y, epoch=epoch)

就行了。這其實和現有的許多神經網路的框架長的差不多 ( σ"ω")σ

那麼模型已經弄好了,接下來怎麼評估這個模型呢?為此需要一個預測函數和一個評估函數:

該函數會根據輸入 x 輸出模型預估的類別向量。其中 self._get_prediction 的定義為:

至於評估函數則如下定義:

該函數會根據輸入的 x,y 列印出模型預估的準確率

以上,一個完整的神經網路結構就搭建完畢了,合共 116 行 Python 代碼,大概算是一個不錯的結果。稍微總結一下主要過程:

  1. 實現前傳演算法
  2. 根據前傳演算法獲得預測值和損失
  3. 最小化損失以訓練模型,根據預測值來評估模型

我們用到了但還沒講的損失函數層(CostLayer) Optimizers 會在下一章講,屆時神經網路的樸素實現就告一段落了

希望觀眾老爺們能夠喜歡~

(猛戳我進入下一章! ( σ"ω")σ )

(猛戳我進入附加章節 ( σ"ω")σ )


推薦閱讀:

強大的機器學習專屬R包——mlr包
Boosting

TAG:Python | 机器学习 | 神经网络 |