神經網絡和深度學習之——前饋神經網絡

前面一章咱們詳細講解了神經網絡的組成,工做原理,信號在網絡中如何流動,以及如何求解每個輸入信號賦予的權重等計算過程;同時咱們還構建了一個邏輯迴歸網模型來解決鳶尾花分類問題,很明顯,這種網絡很「淺」,但它對於分類鳶尾花數據仍是很是有效的,並且不只僅是鳶尾花,對於有須要的其餘二分類問題,該模型也能表現得很好。因爲這種模型太「淺」了,咱們通常稱這種模型爲bp網絡,而不直接稱爲神經網絡,有些人甚至以爲這種網絡還不配叫作神經網絡。我無需去爭論這些芝麻小事,咱們要作的就是從這一章起,邁向深度神經網絡,瞭解什麼是深度神經網絡,它結構是什麼樣,它如何工做,以及綜合前面三章的內容,用Pytorch搭建一個三層網絡實現手寫數字分類。python

1. 深度前饋網絡

1.1 什麼是深度前饋網絡

深度神經網絡,簡單來理解就是含有多個隱藏層的網絡。一個深度神經網絡總會有一個輸入層,一個輸出層,還有中間多個隱藏層,隱藏層的維數決定了網絡的寬度。不管是輸入層、隱藏層仍是輸出層,每一層都是由多個感知器組成,因此深度神經網絡又稱多層感知機。算法

前饋(feedforward)也能夠稱爲前向,從信號流向來理解就是輸入信號進入網絡後,信號流動是單向的,即信號從前一層流向後一層,一直到輸出層,其中任意兩層之間的鏈接並無反饋(feedback),亦即信號沒有從後一層又返回到前一層。若是從輸入輸出關係來理解,則爲當輸入信號進入後,輸入層以後的每個層都將前一個層的輸出做爲輸入。以下圖所示的四層網絡,這個圖也能夠稱爲有向無環路圖。反之,當前饋神經網絡中層與層之間的信號有反向流動,或者自輸入時,咱們則稱這種網絡爲循環神經網絡,循環神經網絡在天然語言處理方面發揮着極大的做用。
編程



圖5.1.1網絡


在深度前饋網絡中,鏈式結構也就是層與層之間的鏈接方式,層數就表明網絡深度。若是咱們把每一層看做一個函數,那麼深度神經網絡就是許多不一樣非線性函數複合而成,這裏與以前典型的線性迴歸和邏輯迴歸明顯的區別開來。好比,第一層函數爲\(f^{(1)}\),第二層函數爲\(f^{(2)}\),第三層函數爲\(f^{(3)}\),那麼這個鏈式結構就能夠表示爲:\(f(x)=f^{(3)}(f^{(2)}(f^{(1)}(x)))\),經過屢次複合,實現輸入到輸出的複雜映射,鏈的全長也就表明模型深度。這種網絡結構比較好搭建,應用也十分普遍,好比在圖像識別領域占主導地位的卷積神經網絡就是深度前饋網絡的一種,學習這種網絡,是咱們通向循環神經網絡的奠定石。機器學習

1.2 深度學習

維基百科對深度學習的解釋是:深度學習(deep learning)是機器學習的分支,是一種試圖使用包含複雜結構或由多重非線性變換構成的多個處理層對數據進行高層抽象的算法。因爲深度神經網絡也是多層非線性變換的載體,因此也有人認爲深度學習就是深度神經網絡的代名詞。這裏請注意,咱們所說是深度神經網絡,而不是深度前饋網絡,前饋網絡僅僅是深度神經網絡的其中一種。函數

爲何深度學習是多層和非線性變換的結合呢,很顯然,咱們須要從兩個方面來理解。學習

一,咱們從以前的學習中能夠知道線性模型僅僅可以解決的是簡單的線性分類問題,對於異或邏輯的出現會直接讓線性模型出現沒法工做的狀況,因此非線性變換隨此出現。
二,對於上面說起的多層,其實咱們指的是多層隱藏層。相對於輸入層或輸出層的設計直觀性,隱藏層的設計便是科學又是藝術,一些經驗法則指出,隱藏層並非越多越好,神經網絡的研究人員已經爲隱藏層開發了許多設計最優法則,這有助於網絡的行爲能符合人們的指望。測試

若是把隱藏層當作一個黑盒,那麼你所要關心的只是輸出,而不關注隱藏層內部如何對數據特徵進行提取,如何優化權重參數和隨機變量;若是把隱藏層拆開細究,隱藏層表明的則是數據特徵,上一個隱藏層把特徵向量通過一系列變換後輸入到下一個隱藏層,隱藏層的每個神經元都帶有特徵數據向前傳播。以下圖舉例說明,輸入一張人物頭像,三層隱藏層依次輸出的圖片信息可視化後,最後由計算機得出圖像特徵是人臉仍是動物。
優化



圖5.1.2spa


你能夠這樣理解,每一張圖片就表明一層隱藏層的輸出,這樣咱們便知道了隱藏層在對數據進行特徵提取方面發揮着重要做用。

2. 梯度降低的再次學習

到目前爲止,咱們瞭解的梯度降低算法是基於線性模型的殘差\(E(w)\),初始化權重\(w\)、可設定的常數學習率\(\eta\)的前提下,結合如下公式來不斷更新。
\[w_{n+1}=w_{n}-\eta \frac{\partial E(w)}{\partial w}\]
固然,還有種解法,若是殘差(代價函數)爲凸函數,那麼咱們只須要設殘差(代價函數)的導數爲0,即可以求得殘差最小值所對應的權重。
\[E(w)'=0\]
這種方法理論上是可行的,但若是遇到代價函數的導數很難求解的時候,問題就卡住了,相信你應該不會硬碰硬的去直接求解函數\(y=(e^x+x^2)^{\frac {1} {e^x+x}}\)的導數吧?。所以,回到上面的\(\frac{\partial E(w)}{\partial w}\),若是遇到導數沒法求解的時候,咱們是否能夠換個方式或者法則來計算呢?數學中,鏈式法是求解複合函數導數的一種重要方法,讓咱們來回顧一下。
假設\(E(f(w))\)\(y=f(w)\)\(w\)複合而成的函數,那麼對於求導數,咱們能夠有:
\[E(f(w))'=E'(f(w))f'(w)\]
對於求微分可寫成:
\[\frac{\partial E}{\partial w}=\frac{\partial E}{\partial y} \cdot \frac{\partial y}{\partial w}\]
而咱們面對的問題,和上面的鏈式法則定義一致。首先,別忘了殘差\(E\)的定義是真實值\(t{k}\)和輸出預測值\(O_{k}\)之差的平方,表示爲\(E=(t_{k}-O_{k})^2\)
殘差對權重的微分也可寫做
\[\frac{\partial E}{\partial w}=\frac{\partial (t-O)^2}{\partial w}\]
而預測值\(O_{k}\)又是權重\(w\)的函數,\(O_{k}=O_{k}(w)\)

運用鏈式法則,咱們把殘差對權重的微分寫成:
\[\frac{\partial E}{\partial w_{j,k}}=\frac{\partial E}{\partial O_{k}} \cdot \frac{\partial O_{k}}{\partial w}\]
其中\(\frac{\partial E}{\partial O}\)的微分是很容易計算的平方函數微分,因此上面的式子可爲:
\[\frac{\partial E}{\partial w_{j,k}}=-2(t_{k}-O_{k})\frac{\partial O_{k}}{\partial w_{j,k}}\]
進行到這裏,咱們可能須要引入深度前饋網絡來詳細考慮一下這個\(\frac{\partial O_{k}}{\partial w_{j,k}}\)的微分該如何表示。以下某網絡中任意一層,其中有四個節點,每一個節點爲S型感知器(即加入Sigmoid函數),咱們知道,不管這一層是輸入層、隱藏層仍是輸出層,這一層左邊的輸入來自外部輸入或來自上一層網絡的輸出,而層右邊的輸出可做爲下一層網絡的輸入,也可做爲最終的輸出。接着,咱們用\(w_{j,k}\)來表示上一層的第\(j\)個節點和如圖所示的這一層第\(k\)個節點的連接權重(其中\(j=1,2...n\)\(k=1,2...m\))。



圖5.1.3


當輸入進入該層,權重和輸入信號進行加權求和,同時經過Sigmoid函數輸出值:
\[O_{k}=Sigmoid({\sum_{k=1,j=1}^{4}} w_{j,k} \cdot x_{j})\]

這樣推導事後,咱們能夠獲得下面的式子:
\[\frac{\partial E}{\partial w_{j,k}}=-2(t_{k}-O_{k})\frac{\partial}{\partial w_{j,k}} Sigmoid(\sum w_{j,k} \cdot x_{j})\]
在求解Sigmoid函數的導數前咱們回顧一下\(Sigmoid\)函數表達式:
\[Sigmoid(x)=\frac{1}{1+e^{-x}}\]
\(Sigmoid\)\(x\)的微分:
\[\frac{\partial }{\partial x}Sigmoid(x)=Sigmoid(x)(1-Sigmoid(x))\]
咱們暫時沒必要把\(Sigmoid\)函數帶入計算,從這裏能夠看出原來Sigmoid函數的導數是如此簡單,並且易於使用。

在求解\(\frac{\partial}{\partial w_{j,k}} Sigmoid(\sum w_{j,k})\),再使用一次鏈式法則。

咱們得出一個很是炫酷的式子:




這確實是一個振奮人心的結果,眼尖的你可能一眼就看出表達式中每一項表明的意思。




不過我以爲把式子中的"2"去掉也許更簡潔,爲何?由於無論前面常數是-2,2,或者是20都不是影響殘差斜率的關鍵因素,咱們只須要記住本身須要什麼就能夠了,這樣殘差的斜率就被咱們簡化成最乾淨利落的樣子:
\[\frac{\partial E}{\partial w_{j,k}}=-(t_{k}-O_{k}) \cdot O_{k}\cdot (1-O_{k}) \cdot x_{j}\]

咱們能夠放心大膽的在線性感知器中使用權重更新公式了,只要咱們記住權重改變的方向與梯度方向相反,以及適度的設置其中的學習率以防止超調。
\[w_{n+1}=w_{n}-\eta \frac{\partial E}{\partial w_{j,k}}\]

不難看出,新的權重\(w_{n+1}\)是由剛剛獲得偏差斜率取反來調整舊的權重\(w_{n}\)而獲得的。若是斜率爲正,咱們但願減少權重,若是斜率爲負,咱們但願增長權重,所以,咱們要對斜率取反。學斜率\(\eta\)就是用於調節這些變化的強度,確保不會超調。如今終於能夠明白,咱們在上一章鳶尾花的分類中定義權重時一個重要的初始化步驟居然就是這樣來的。

self.wih += self.lr * numpy.dot((output_errors * final_outputs * (1.0 - final_outputs)),
                                        numpy.transpose(inputs))

這個權重更新表達式不只適用於隱藏層和輸出層之間的權重,並且適用於輸入層和隱藏層之間的權重。好比鳶尾花分類例子中使用的模型只有一層,相似上圖5.1.3,所以,代碼中final_outputs表明\(O_{k}\),而inputs則就是外部輸入\(x_{j}\);若模型爲多層網絡,那麼"\(O_{k}\)"表明某一層的輸出,\(x_{j}\)表明某一層的輸入。到此爲止,梯度降低算法總算了解透徹,若是還有其餘複雜的數學推導放一邊去吧,還有什麼不知足的呢,用上面的公式,以及結合python語言,咱們已經可以快速實現模型的指望結果。

3. 訓練一個模型

3.1 監督學習簡介

監督學習(Supervised learning),是一個機器學習中的方法,能夠由訓練集中學到或創建一個模式(函數/ learning model),並依此模式推測新的實例。 監督學習須要的訓練集是由輸入向量和與每個輸入向量相關聯的目標向量組成。神經網絡學習器使用目標向量來決定其已經學習的程度,而且經過目標向量指導權值的調整從而下降總體偏差。

雖然不一樣的模型在運算數量,運算的組合方式以及所使用的參數數量上千差萬別,但對於訓練,咱們始終能夠採用相同的通常結構:



圖5.1.4


這是一個訓練閉環,它的整個過程咱們實際上已經體驗過了,但這裏仍是不厭其煩的再講一講。

  1. 首先對模型參數進行初始化。一般採用對參數隨機賦值的方法,但對於比較簡單的模型,也能夠將各參數的初值均設爲0。
  2. 讀取訓練數據(包括每一個數據樣本及其指望輸出)。一般人們會在這些數據送入模型以前,隨機打亂樣本的次序。
  3. 在訓練數據上執行推斷模型。這樣,在當前模型參數配置下,每一個訓練樣本都會獲得一個輸出值。
  4. 計算殘差。殘差是一個可以刻畫模型在最後一步獲得的輸出與來自訓練集的指望輸出之間差距的歸納性指標。
  5. 調整模型參數。在給定的損失函數條件下,學習的目的在於經過大量訓練步驟改善各參數的值,從而將損失最小化。最多見的策略是使用梯度降低算法,也就是以上第二部份內容「再次學習梯度降低算法」所使用的方式。
  6. 上述閉環會依據所需的學習速率、所給定的模型及其輸入數據,經過大量循環不斷重複上述過程。

當訓練結束後,便進入驗證階段。在這一過程當中,咱們須要對一個一樣含有指望輸出信息的不一樣測試集數據依據模型進行預測,並評估模型在該數據集上的損失。該測試集中包含了何種樣本,模型是預先沒法獲悉的。經過評估,咱們能夠了解到所訓練的模型在訓練集以外的推廣能力。咱們經常將原始數據集一分爲二,將70%的樣本用於訓練,其他30%的樣本用於評估。

咱們在前面鳶尾花分類實踐中已經使用了一次監督學習的方法,後面在卷積神經網絡中咱們也會用到監督學習的方法。因此,瞭解它,正確使用它,咱們必須這樣作。

3.2 簡單說說無監督學習

在監督學習中,咱們的目標是學習從輸入到輸出的映射關係,其中訓練數據的輸出正確值已經由指導者提供,也就是說有正確的標籤值。然而,無監督學習中卻沒有正確的標籤值,只有輸入數據。咱們的目標是發現輸入數據中的規律,使網絡不斷地進行自我認知,自我鞏固,最後進行自我概括。

在有監督學習中,咱們把對樣本進行分類的過程稱之爲分類(Classification),而在無監督學習中,咱們將物體被劃分到不一樣集合的過程稱之爲聚類(Clustering)。聚類的目標是發現輸入數據的簇或分組。好比對於一個擁有老客戶數據的公司,客戶數據包括客戶的我的統計信息,以及之前與公司的交易,公司也許想知道其客戶的分佈,搞清楚什麼類型的客戶會頻繁出現。這種狀況下,聚類模型會將屬性類似的客戶分到相同的簇,一旦找出了這樣的分組,公司就可能作出一些決策,好比對不一樣分組的客戶提供特別的服務和產品等。

目前分類算法的效果仍是不錯的,在實際應用中使用普遍;但相對來說,聚類算法就一直存在發展障礙。確實,無監督學習自己的特色使其難以獲得如分類同樣近乎完美的結果,其中一個特色就是標籤的獲取經常須要極大的人工工做量,有時甚至很是困難,這無疑增長了無監督學習的難度,也稱爲無監督學習的發展瓶頸。不過,也有人提出經過半監督學習來解決這個難題,在半監督學習中,其訓練數據的一部分是有標籤,另外一部分沒有標籤,沒有標籤數據的數量遠大於有標籤數據的數量。半監督學習下隱藏着一個基本規律,那就是:數據的分佈不是徹底隨機的,經過一些有標籤數據的局部特徵,以及更多沒標籤數據的總體分佈,就能夠獲得能夠接受甚至是很是好的分類結果。

參考文獻:
一、《Python神經網絡編程》
二、《深度學習》
三、《計算智能導論》
四、《面向機器智能的Tensorflow實踐》
五、《機器學習導論》
六、https://www.zhihu.com/question/23194489

相關文章
相關標籤/搜索