多層感知機

目錄:1.多層感知機的基礎知識

            2.多層感知機的pytorch代碼實現與講解

多層感知機的基礎知識

1.基礎知識:多層感知機(MLP,Multilayer Perceptron)也叫人工神經網絡(ANN,Artificial Neural Network),除了輸入輸出層,它中間可以有多個隱層,最簡單的MLP只含一個隱層,即三層的結構,如下圖:

                                                     

從上圖可以看到,多層感知機層與層之間是全連接的。多層感知機最底層是輸入層,中間是隱藏層,最後是輸出層。 

具體說來,給定一個小批量樣本X\epsilon {R^{n\times d}},其批量大小爲n,輸入個數爲d。假設多層感知機只有一個隱藏層,其中隱藏單元個數爲h。記隱藏層的輸出(也稱爲隱藏層變量或隱藏變量)爲H,有H\epsilon {R^{n\times h}}。因爲隱藏層和輸出層均是全連接層,可以設隱藏層的權重參數和偏差參數分別爲W_{h}\epsilon {R^{d\times h}}和 b_{h}\epsilon {R^{1\times h}},輸出層的權重和偏差參數分別爲W_{o}\epsilon {R^{q\times h}}b_{o}\epsilon {R^{1\times q}}

我們先來看一種含單隱藏層的多層感知機的設計。其輸出O\epsilon {R^{n\times q}}的計算爲:

                                                                    H = XW_{h} \dotplus b _{h}

                                                                    O = HW_{o} \dotplus b _{o}

也就是將隱藏層的輸出直接作爲輸出層的輸入。如果將以上兩個式子聯立起來,可以得到

                                            O = W_{o}\left ( XW_{h} \dotplus b _{h} \right ) \dotplus b _{o} = XW_{o}W_{h} \dotplus W_{o}b_{h} \dotplus b_{o} 

從聯立後的式子可以看出,雖然神經網絡引入了隱藏層,卻依然等價於一個單層神經網絡:其中輸出層權重參數爲W_{o}W_{h},偏差參數爲W_{o}b_{h} \dotplus b_{o}。不難發現,即便再添加更多的隱藏層,以上設計依然只能與僅含輸出層的單層神經網絡等價。

 

上述問題的根源在於全連接層只是對數據做仿射變換(affine transformation),而多個仿射變換的疊加仍然是一個仿射變換。解決問題的一個方法是引入非線性變換,例如對隱藏變量使用按元素運算的非線性函數進行變換,然後再作爲下一個全連接層的輸入。這個非線性函數被稱爲激活函數(activation function)。

1):爲何使用激活函數?

     a:不使用激活函數,每一層輸出都是上層輸入的線性函數,無論神經網絡有多少層,輸出都是輸入的線性組合。

     b:使用激活函數,能夠給神經元引入非線性因素,使得神經網絡可以任意逼近任何非線性函數,這樣神經網絡就可以利用到更多的非線性模型中。

2):激活函數需要具備以下幾點性質:

   a:連續並可導(允許少數點上不可導)的非線性函數。可導的激活函數可以直接利用數值優化的方法來學習網絡參數。

    b:激活函數及其導函數要儘可能的簡單,有利於提高網絡計算效率。

    c:激活函數的導函數的值域要在一個合適的區間內,不能太大也不能太小,否則會影響訓練的效率和穩定性。 

3):常見的激活函數及其優缺點:

   a:Sigmoid函數表達式

                                                     f\left ( z \right ) = \frac{1}{1\dotplus e^{-z}}

    b:特點:它能夠把輸入的連續實值變換爲0和1之間的輸出,特別的,如果是非常大的負數,那麼輸出就是0;如果是非常大的正數,輸出就是1.

    c:優缺點:sigmoid函數曾經被使用的很多,不過近年來,用它的人越來越少了。主要是因爲它固有的一些 缺點。1:在深度神經網絡中梯度反向傳遞時導致梯度爆炸和梯度消失,其中梯度爆炸發生的概率非常小,而梯度消失發生的概率比較大。2:Sigmoid 的 output 不是0均值(即zero-centered)。3:其解析式中含有冪運算,計算機求解時相對來講比較耗時。

 

   a:tanh函數表達式

                                                         tanh\left ( x \right ) = \frac{(e^{x} - e^{-x}) }{(e^{x} \dotplus e^{-x}) }

   b:它解決了Sigmoid函數的不是zero-centered輸出問題,然而,梯度消失(gradient vanishing)的問題和冪運算的問題仍然存在。

 

    a:Relu函數解析式

                                                  ReLU = max\left ( 0, x \right )

     b:特點:ReLU函數其實就是一個取最大值函數,注意這並不是全區間可導的,但是我們可以取sub-gradient。

     c:優缺點:1.解決了gradient vanishing問題 (在正區間)。2.計算速度非常快,只需要判斷輸入是否大於0。3.收斂速度遠快於sigmoid和tanh。4.ReLU的輸出不是zero-centered。5.Dead ReLU Problem,指的是某些神經元可能永遠不會被激活,導致相應的參數永遠不能被更新。有兩個主要原因可能導致這種情況產生: (1) 非常不幸的參數初始化,這種情況比較少見 (2) learning rate太高導致在訓練過程中參數更新太大,不幸使網絡進入這種狀態。解決方法是可以採用Xavier初始化方法,以及避免將learning rate設置太大或使用adagrad等自動調節learning rate的算法。

4):關於激活函數的選擇?

 ReLu函數是一個通用的激活函數,目前在大多數情況下使用。但是,ReLU函數只能在隱藏層中使用。用於分類器時,sigmoid函數及其組合通常效果更好。由於梯度消失問題,有時要避免使用sigmoid和tanh函數。在神經網絡層數較多的時候,最好使用ReLu函數,ReLu函數比較簡單計算量少,而sigmoid和tanh函數計算量大很多。在選擇激活函數的時候可以先選用ReLu函數如果效果不理想可以嘗試其他激活函數。

 

多層感知機pytorch實現

import torch
from torch import nn
from torch.nn import init
import numpy as np
import sys
sys.path.append("/home/kesci/input")
import d2lzh1981 as d2l

#此代碼實現三層感知機

num_inputs, num_outputs, num_hiddens = 784, 10, 256   # 輸入層、隱藏層和輸出層節點個數

# 定義感知機的網絡結構    
net = nn.Sequential(
        d2l.FlattenLayer(),   # size:batch_size, 784
        nn.Linear(num_inputs, num_hiddens),  # size:784, 10  輸出:batch_size, 10
        nn.ReLU(),   # 激活函數 篩選有效特徵
        nn.Linear(num_hiddens, num_outputs),  # size:10, 256 輸出:batch_size, 256 
        )
    
for params in net.parameters():  # 參數初始化
    init.normal_(params, mean=0, std=0.01)

batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size,root='/home/kesci/input/FashionMNIST2065')
loss = torch.nn.CrossEntropyLoss()  # 損失函數

optimizer = torch.optim.SGD(net.parameters(), lr=0.5)

num_epochs = 5
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, None, None, optimizer)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章