Python · 神經網路(二)· 層
(這裡是最終成品的 GitHub 地址)
(這裡是本章用到的 GitHub 地址)
這一章主要講核心結構 層(Layer)的實現
那麼思想我們都有了,關鍵就是怎麼把它翻譯成代碼。為使觀眾老爺們不會一步邁得太大,我們先不考慮和卷積神經網路(CNN)以及各種附加層(Dropout、Normalize 等)的兼容問題、而只考慮普通的神經網路。
我們上一章說了、我們關鍵要把所有層的爸爸定義好,所以我們要先考慮一個層的基本功能應該有哪些:
- 形狀。這個挺直觀,因為為了能夠和上一層與下一層水乳交融(喂),層與層之間的形狀要彼此契合(喂喂喂)
- 沒了。
確實如果只用實現最簡單的神經網路的話,定義一個形狀足矣。所以代碼也很清晰了:
class Layer(metaclass=ABCMeta):n def __init__(self, shape):n self.shape = shapen
接下來就可以直接實現 Duang 的部分了!鼓掌!!(喂
def activate(self, x, w, bias):n return self._activate(tf.matmul(x, w) + bias)n
這裡面涉及許多東西,我們一個個來看它們的數學內涵(至於數學內涵是什麼意思以及為什麼要這麼做請參見這篇文章):
- w:上一層與當前層之間的權重
- bias:當前層的偏置量
- tf.matmul:這裡面 tf 是 tensorflow 的縮寫(今後同理),matmul 是「矩陣乘法」的意思。也就是說,這個函數相當於做了個矩陣乘法並返回其結果
@abstractmethodndef _activate(self, x):n passn
和你想的一樣嗎?
注意我前面說過,爸爸是不幹活的,只有他生的孩兒才幹活;所以爸爸理應將這個 Duang 的部分交給他孩兒自己去 Duang
可以說到這為止,一個最簡單的爸爸就定義完了。我們最後讓他生一個兒子看看:
class Sigmoid(Layer):n def _activate(self, x, predict):n return tf.nn.sigmoid(x)n
tf.nn.sigmoid 是 tensorflow 自帶的 Sigmoid 激活函數。相當方便不是嗎科科科!
不過可能有比較厲害的觀眾老爺會發現:你這個東西不是沒定義梯度下降的過程嗎!沒錯,這正是 tensorflow 的厲害之處,它會幫你處理所有梯度下降相關的問題。
有些觀眾老爺可能會有所不滿……沒關係!!為了讓每個觀眾老爺都滿意,我自己寫了一套完整的梯度下降演算法,包括各種 Optimizers 像 Adams 啊 RMSProp 啊之類的都有!
不過那個就是比較深的內容了,大概會作為附加章節給出……畢竟是自己實現的,比 cpu 版的 tensorflow 要慢兩三倍,比 gpu 版的……咳咳咳……
以上,大概講述了如何最簡潔快速地定義 層(Layer)這個類;接下來我們會定義一個最簡單的 神經網路(NN)類、也就是上一章說的框架來封裝這個 Layer 類、並看看我們的初步結果如何
希望觀眾老爺們能喜歡~
(猛戳我進入下一章! ( σω)σ )
(猛戳我進入附加章節 ( σω)σ )
推薦閱讀:
※如何理解和區分近似誤差和估計誤差?
※「深度學習入行門檻太低了,不開心!」
※文本匹配:語義相關性
※如何評價牛津的Prof. Andrew Zisserman?