多層感知機(multilayer perceptron,簡稱MLP)是最基礎的深度學習模型。
多層感知機在單層神經網路的基礎上引入了一到多個隱藏層(hidden layer)。隱藏層位於輸入層和輸出層之間。隱藏層中的神經元和輸入層中各個輸入完全連線,輸出層中的神經元和隱藏層中的各個神經元也完全連線。因此,多層感知機中的隱藏層和輸出層都是全連線層。
仿射變換
在描述隱藏層的計算之前,我們看看多層感知機輸出層是怎麼計算的。輸出層的輸入是隱藏層的輸出,通常我們將隱藏層的輸出稱為隱藏層變數或隱藏變數。
給定一個小批量樣本,其批量大小為n,輸入個數為x,輸出個數為y。假設多層感知機只有一個隱藏層,其中隱藏單元個數為h,隱藏變數\(\boldsymbol{H} \in \mathbb{R}^{n \times h}\)。假設輸出層的權重和偏差引數分別為\(\boldsymbol{W}_o \in \mathbb{R}^{h \times y}, \boldsymbol{b}_o \in \mathbb{R}^{1 \times y}\),多層感知機輸出
\[\boldsymbol{O} = \boldsymbol{H} \boldsymbol{W}_o + \boldsymbol{b}_o\]
實際上,多層感知機的輸出\(\boldsymbol{O}\)是對上一層的輸出\(\boldsymbol{H}\)的仿射變換(affine
transformation)。它包括一次通過乘以權重引數的線性變換和一次通過加上偏差引數的平移。
那麼,如果隱藏層也只對輸入做仿射變換會怎麼樣呢?設單個樣本的特徵為\(\boldsymbol{x} \in \mathbb{R}^{1 \times x}\),隱藏層的權重引數和偏差引數分別為\(\boldsymbol{W}_h \in \mathbb{R}^{x \times h}, \boldsymbol{b}_h \in \mathbb{R}^{1 \times h}\)。假設
\[\boldsymbol{h} = \boldsymbol{x} \boldsymbol{W}_h +\boldsymbol{b}_h\]\[\boldsymbol{o} = \boldsymbol{h} \boldsymbol{W}_o + \boldsymbol{b}_o\]
聯立兩式可得\(\boldsymbol{o} = \boldsymbol{x} \boldsymbol{W}_h \boldsymbol{W}_o + \boldsymbol{b}_h \boldsymbol{W}_o + \boldsymbol{b}_o\):它等價於單層神經網路的輸出\(\boldsymbol{o} = \boldsymbol{x} \boldsymbol{W}^\prime + \boldsymbol{b}^\prime\),其中\(\boldsymbol{W}^\prime = \boldsymbol{W}_h \boldsymbol{W}_o, \boldsymbol{b}^\prime = \boldsymbol{b}_h \boldsymbol{W}_o + \boldsymbol{b}_o\)。因此,僅使用仿射變換的隱藏層使多層感知機與前面介紹的單層神經網路沒什麼區別。
啟用函式
由上面的例子可以看出,我們必須在隱藏層中使用其他變換,例如新增非線性變換,這樣才能使多層感知機變得有意義。我們將這些非線性變換稱為啟用函式(activation function)。啟用函式能對任意形狀的輸入按元素操作且不改變輸入的形狀。
ReLU函式
ReLU(rectified linear unit)函式提供了一個很簡單的非線性變換。給定元素x,該函式的輸出是\(\text{relu}(x) = \max(x, 0)\),ReLU函式只保留正數元素,並將負數元素清零。
Sigmoid函式
Sigmoid函式可以將元素的值變換到0和1之間:\(\text{sigmoid}(x) = \frac{1}{1 + \exp(-x)}\),我們會在後面“迴圈神經網路”一章中介紹如何利用sigmoid函式值域在0到1之間這一特性來控制資訊在神經網路中的流動。
Tanh函式
Tanh(雙曲正切)函式可以將元素的值變換到-1和1之間:\(\text{tanh}(x) = \frac{1 - \exp(-2x)}{1 + \exp(-2x)}\)。當元素值接近0時,tanh函式接近線性變換。值得一提的是,它的形狀和sigmoid函式很像,且當元素在實數域上均勻分佈時,tanh函式值的均值為0。
from mxnet import ndarray as nd
X = nd.array([[[0,1], [-2,3], [4,-5]], [[6,-7], [8,-9], [10,-11]]])
print X.relu(), X.sigmoid(), X.tanh()
多層感知機
現在,可以給出多層感知機的向量計算表示式了。
\[\begin{split}\boldsymbol{H} = \phi(\boldsymbol{X} \boldsymbol{W}_h + \boldsymbol{b}_h),\\ \boldsymbol{O} = \boldsymbol{H} \boldsymbol{W}_o + \boldsymbol{b}_o,\end{split}\]
在分類問題中,我們可以對輸出O做Softmax運算,並使用Softmax迴歸中的交叉熵損失函式。 在迴歸問題中,我們將輸出層的輸出個數設為1,並將輸出O直接提供給線性迴歸中使用的平方損失函式。
我們可以新增更多的隱藏層來構造更深的模型。需要指出的是,多層感知機的層數和各隱藏層中隱藏單元個數都是超引數。
隨機初始化模型引數
在神經網路中,我們需要隨機初始化模型引數。
MXNet的預設隨機初始化,我們使用net.initialize(init.Normal(sigma=0.01))令模型net的權重引數採用正態分佈的隨機初始化方式。如果不指定初始化方法,例如net.initialize(),我們將使用MXNet的預設隨機初始化方法。在預設條件下的初始化時,權重引數每個元素隨機取樣於-0.07到0.07之間的均勻分佈,偏差引數全部元素清零。
Xavier隨機初始化
還有一種比較常用的隨機初始化方法叫做Xavier隨機初始化,假設某全連線層的輸入個數為:math:a,輸出個數為b,Xavier隨機初始化將該層權重引數的每個元素隨機取樣於均勻分佈
\[\left(-\sqrt{\frac{6}{a+b}}, \sqrt{\frac{6}{a+b}}\right).\]
它的設計主要考慮到,模型引數初始化後,每層輸出的方差不該被該層輸入個數所影響,且每層梯度的方差不該被該層輸出個數所影響。這兩點與我們之後將要介紹的正向傳播和反向傳播有關。