用PyTorch實現多層網絡:從感知機到多層神經網絡

神經網絡中有許多的名詞,比如MLP\ANN\CNN\RNN\DNN等,在文章開始之前先給出一個大致說明,免得像我一樣爲了區分多層感知機(MLP)與多層神經網絡的概念搜索半天資料。

首先,深度前饋網絡(deep feedforward network),也叫做前饋神經網絡(feedforward neural network)或者多層感知機(Multilayer Perceptron,MLP),多層感知機(MLP)又叫人工神經網絡(Artificial Neural Network,ANN),是典型的深度學習模型。其次,我覺得多層神經網絡是一個很廣泛的概念,所有那些具有較多隱藏層/中間層的神經網絡都可以成爲多層神經網絡,還有一個深度神經網絡(DNN)的概念,我覺得它就是多層神經網絡。最後,卷積神經網絡(CNN)和循環神經網絡(RNN)是兩種對簡單全連接神經網絡的傳播過程進行設計的特殊/專業神經網絡,這兩種神經網絡以後學習到時會介紹,這裏就不具體說明了。
所以,感知機模型如果中間有很多隱藏層的話,也就屬於多層神經網絡。

對於神經網絡的衆多名稱,‘花書’是這樣說明的,“這個領域已經更換了很多名字,它反映了不同的研究人員和不同觀點的影響。同時也因爲它被賦予了許多不同的名稱(其中大部分已經不在使用),最近才成爲衆所周知的深度學習”。

概念理解

感知機

感知機(perceptron)是二分類的線性分類模型,輸入爲實例的特徵向量,輸出爲實例的類別(取+1和-1)。感知機對應於輸入空間中將實例劃分爲兩類的分離超平面。感知機旨在求出該超平面,爲求得超平面導入了基於誤分類的損失函數,利用梯度下降法 對損失函數進行最優化(最優化)。
從神經網絡模型的角度看,感知機是最簡單的分類模型。

多層感知機

多層感知器(Multilayer Perceptron,縮寫MLP)是一種前向結構的人工神經網絡,映射一組輸入向量到一組輸出向量。MLP可以被看作是一個有向圖,由多個的節點層所組成,每一層都全連接到下一層。除了輸入節點,每個節點都是一個帶有非線性激活函數的神經元(或稱處理單元)。一種被稱爲反向傳播算法的監督學習方法(BP算法)常被用來訓練MLP。
MLP是一種非線性分類器,傳統的感知機模型是兩層的NN,是線性的,而MLP是三層及以上的NN,就可以實現非線性任務,比如三層的MLP可以實現異或(XOR)問題。
多層感知機的層與層之間是全連接的,即每一層的任意一個神經元均與其前一層的所有神經元有連接,這種連接其實代表了一種權重加和。

上面這樣對感知機與多層感知機的解釋很簡短明瞭,但是對很多初學者很不友好,所以我找到一篇文章從多層感知器到卷積網絡(一)來一起食用。文章作者白話的非常清楚,從神經網絡的原來講起,介紹簡單且廣泛,另外神經網絡中最基本的神經元與反向傳播在文中配圖介紹。

激活函數

從上面的介紹我們已經直到,神經元是神經網絡的基本單元,除了輸入節點,每個節點都是一個帶有非線性激活函數的神經元。那麼爲什麼需要激活函數,激活函數又是什麼?以下進行簡單說明。

不管是單層感知機還是多個感知器,只要不帶激活函數,都只能解決線性可分的問題,解決不了線性不可分問題。激活函數是用來加入非線性因素的,提高神經網絡對模型的表達能力,使得神經網絡可以更好地解決較爲複雜的問題。

激活函數(Activation Function),就是作用在人工神經網絡的神經元上函數,負責將inputs加權求和後的輸入映射到輸出端。

常見的激活函數有:函數圖形可見深度學習筆記六:常見激活函數總結
以下列出常見的四種。

  • Sigmoid(S型激活函數,將輸入映射到一個0到1之間的值)
  • tanh(雙曲正切函數,將輸入映射到一個-1到1之間的值)
  • ReLU(近似生物神經激活函數)
f(x)=max(0,x)
  • Softmax(在多分類中常用的激活函數,是基於邏輯迴歸的。)

pytorch實現

import torch
from torch.autograd import Variable

# 一定要繼承 nn.Module
class TwoLayerNet(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(TwoLayerNet, self).__init__()
        self.twolayernet = nn.Sequential(
            nn.Linear(input_size, hidden_size),
            nn.ReLU(),
            nn.Linear(hidden_size, output_size),
        )

    def forward(self, x):
        y_pred = self.twolayernet(x)
        return y_pred

# M是樣本數量,input_size是輸入層大小, hidden_size是隱含層大小,output_size是輸出層大小
M, input_size, hidden_size, output_size = 64, 1000, 100, 10

# 生成隨機數當作樣本
x = Variable(torch.randn(M, input_size))
y = Variable(torch.randn(M, output_size))

model = TwoLayerNet(input_size, hidden_size, output_size)

# 定義損失函數
loss_fn = nn.MSELoss(size_average=False)

learning_rate = 1e-4
EPOCH = 300

# 使用optim包來定義優化算法
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

for t in range(EPOCH):    
    y_pred= model(x)
    loss = loss_fn(y_pred, y)
    if (t+1) % 50 == 0:
        print(loss.data[0])
    
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

參考:
“花書”《深度學習》
系統學習深度學習(九)–激活函數總結
神經網絡激活函數的作用是什麼?
深度學習:神經網絡中的激活函數
https://github.com/LianHaiMiao/pytorch-lesson-zh/blob/master/basis/4、多層感知機.ipynb

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