http://blog.itpub.net/31077337/viewspace-2156393/web
本文主要是學習BP神經網絡的一個總結,其自己也是機器學習中比較基礎、適合入門的模型。算法
目前本人對於機器學習也還只是入門狀態,對於不少名詞仍然是隻知其一;不知其二(感受機器學習中的不少術語自己也是模棱兩可的),對於不少公式也是不求甚解,所以這篇文章是嘗試用本身的語言和理解來複述所學習到的知識,若是有錯誤之處還望大牛們不吝斧正。網絡
霍金說過每多一個數學公式,就會少一半的讀者,所以這裏也會盡可能少用公式,要用也只用簡單易懂的公式。並且我的以爲神經網絡中的不少公式是能夠感性地去認識的,能徹底明白推導過程天然最好,但在不求甚解的狀態下能達到感性的認知也未必不是一個快速掌握的好方法。機器學習
另外本文中用到了很多矩陣相關的知識,忘記了的同窗能夠看附錄中的整理。函數
神經元與激勵函數工具
神經元學習
神經元是神經網絡的基本組成,若是把它畫出來,大概就長成下面這樣:測試
圖中神經元左邊的x表示對神經元的多個輸入,w表示每一個輸入對應的權重,神經元右邊的箭頭表示它僅有一個輸出。spa
固然神經元也有不少種,下面介紹兩種比較基礎的。.net
神經元1:感知器
神經網絡技術起源於上世紀5、六十年代,當時叫感知機(perceptron),其中的單個神經元咱們能夠叫做感知器。感知器的特色具備濃厚的時代氣息:其輸入輸出都是二進制形式的(聽說因爲計算技術的落後,當時感知器傳輸函數是用線拉動變阻器改變電阻的方法機械實現的)。
如上圖所示,感知器有多個二進制輸入(值只能是0或1)X一、X2..Xn,每一個輸入有對應的權值W一、W2..Wn(圖中沒畫出來),將每一個輸入值乘以對應的權值再求和( ∑XjWj ),而後與一個閾值(threshold) 比較,大於閾值則輸出一、小於閾值則輸出0。 寫成公式的話以下:
若是把公式寫成矩陣形式,再用b來表示負數的閾值(即b=-threshold),那就獲得了以下公式:
舉個栗子
例如你所在的城市將有一個你的偶像的演唱會,你正決定是否觀看,你可能會經過如下三個方面來權衡你的決定:
天氣好嗎?
你的好基友是否願意陪你去?
是否這個活動距離公共交通很近?(你本身沒車)
咱們將這三個因素用對應的二進制變量x1,x2和x3表示。好比,當天氣還不錯時,咱們有x1=1,天氣很差時x1=0;類似的,若是好基友願意去,x2=1,不然x2=0;對於公共交通x3同理賦值。
而後根據你的意願,好比讓天氣權重 w1=6,其餘條件權重分別爲w2=2,w3=2。權重w1值越大表示天氣影響最大,比起好基友加入或者交通距離的影響都大。最後,假設你選擇5作爲感知器閾值(即b爲-5),按照這種選擇,這個感知器就能實現這個決策模型:當天氣好時候輸出1,天氣很差時候輸出0,不管你的好基友是否願意去,或者交通是否比較近。
神經元2:Sigmoid神經元
先來認識一個函數:Sigmoid函數,這個單詞在某些工具上直譯是「乙狀結腸」、也還真有某些資料把Sigmoid神經元叫做乙狀結腸神經元的。 其實它是一個經常使用的「S」型函數,能夠把變量映射到(0,1)區間內,其公式以下:
它的函數圖像是以下圖如示的「S」型:
那麼Sigmoid神經元是什麼呢?與感知器有什麼區別?
首先,在Sigmoid神經元中,輸入的值再也不是二進制,而是0到1之間的任意值。即Xi取值是0到1之間的任意實數。
其次,而Sigmoid神經元的輸出也再也不是0或1,而是 σ(wx+b)。 注意"wx+b"是簡寫(矩陣)形式,請對照上面的感知器的公式。
所以咱們能夠得出Sigmoid神經元的公式:
能夠發現當z=w?x+b是一個大的正數時,那麼σ(z)≈1,而當z=w?x+b是一個很小的負數(「絕對值很大的負數」比較好理解)時,σ(z)≈0。處於這兩種狀況時,Sigmoid神經元的輸出跟感知器是很接近的。只有當w?x+b在一個適度的值,sigmoid神經元和感知器誤差才較大。
激勵函數
神經元的輸入和輸出之間具備函數關係,這個函數就稱爲激勵函數。因此上面提到的Sigmoid函數就是激勵函數的一種,感知器的那個函數也能夠稱爲閾值(或階躍)激勵函數。
激勵函數也叫點火規則,這使它與人腦的工做聯繫起來。當一個神經元的輸入足夠大時,就會點火,也就是從它的軸突(輸出鏈接)發送電信號。一樣,在人工神經網絡中,只要輸入超過必定標準時纔會產生輸出,這就是點火規則的思想。
神經網絡的結構
神經網絡簡單地說就是將多個神經元鏈接起來、組成一個網絡。 本文介紹的是最簡單、歷史悠久的一種:「多層感知機」(但咱們講的這個它裏面的神經元並非感知器、而是Sigmoid神經元,名詞混亂+1),或稱之爲「多層向前神經網絡(Multilayer Feed-Forward Neural Network)」,它的特色是有多層(廢話),且神經元之間是全鏈接的,即後一層的神經元會鏈接到前一層的每一個神經元(這裏定義下從輸入層到輸出層爲從「後」向「前」)。
一個多層感知機的示意圖以下,網絡的最左邊一層被稱爲輸入層,其中的神經元被稱爲輸入神經元。最右邊及輸出層包含輸出神經元,在這個例子中,只有一個單一的輸出神經元,但通常狀況下輸出層也會有多個神經元。中間層被稱爲隱含層,由於裏面的神經元既不是輸入也不是輸出。
訓練神經網絡的意義
如今神經元有了,神經網絡的結構也有了,如今回到核心的問題上來:咱們拿神經網絡幹什麼? 要怎樣使它作到?
訓練的目標
按照常識、用人話來講,神經網絡的做用就是咱們預先給它大量的數據(包含輸入和輸出)來進行訓練,訓練完成後,咱們但願它對於未來的真實環境的輸入也能給出一個令咱們滿意的輸出。
損失函數/代價函數(Loss函數)
那麼怎樣用數學的方式來表示一個輸出有多麼令咱們滿意呢? 這裏咱們引入損失函數(或稱代價函數、Loss函數)的概念。
現假設有n組包含了輸入和真實結果(或稱指望結果、指望輸出)的樣本數據,對於每組輸入,咱們的神經網絡輸出的結果記爲fi,真實結果(指望結果)記爲yi。
使用數學工具中的MAE(Mean Absolute Error,平均絕對偏差),能夠很是直觀地表達出輸出結果和真實結果的誤差,所以咱們能夠用MAE來寫出一個下面這樣的Loss函數,Loss值越大、說明神經網絡的輸出結果越遠離咱們的指望。
也能夠用MSE(Mean Squared Error,均方偏差)做爲損失函數,MSE能更好地評價數據的變化程度,簡單地說由於平方了一下、誤差是會被放大的。
將Sigmoid神經元的表達式f(x)=σ(wx+b)代入上面的損失函數中,能夠發現x(輸入)是固定的,yi(指望結果)也是固定的,讓咱們感性地想象一下:實際上影響Loss的只有w和b,而最重要的任務也就是尋找w和b使得Loss最小。
再具象一點,其實對神經網絡進行訓練的目的就是爲每一個神經元找到最適合它的w和b的值,從而使得整個神經網絡的輸出最接近咱們的指望(說「最」其實有點違反廣告法,神經網絡最終達到的很難說是問題的最優解)。
注:下面將真正用到的損失函數
在實際中,爲了方便求導,通常使用以下的Loss函數:
梯度降低
根據上面的結論,能夠把損失(Loss)記做C,而C又只與w和b有關,那麼能夠當作C是一個關於w和b的函數,以下圖所示。注意因爲神經網絡中其實有大量的「w」和「b」(回憶一下、每一個神經元都有多個權重和一個閾值),所以這裏也須要感性的認知。
若是把圖畫出來,它多是下面這樣的:
咱們的目標是找到w和b使C最小,固然上面這張圖很容易看出來合適的w和b在哪,但當面對更復雜的狀況時、好比下圖這樣的,應該如何快速地找到C最小的點呢?
這裏咱們引入梯度降低算法,原理很簡單:把上圖看做是一個丘陵地帶,想象咱們有一個球放在某個位置,讓它「天然地向低處滾」,滾得越低,C就越小,咱們就越高興。
那麼怎樣使得它往低處滾呢? (注意這裏要搬出全文中第一個比較燒腦的概念了) 微分法則告訴咱們,當w移動Δw、b移動Δb時,有:
因爲C表示的是損失,咱們想讓球往低處滾,固然是但願C不斷變小,那ΔC應該恆爲負,那麼Δw、Δb應該如何取值呢? 梯度降低法是這麼設計的:
能夠看出如此取值可使ΔC恆爲負,其中的η稱爲學習率。
那麼如今問題變成了?C/?w、?C/?b,即 C對w 和 C對b 的偏導,這兩個鬼東西要怎麼求?
反向傳播
反向傳播(back propagation)是在這種場景下快速求解?C/?w、?C/?b的算法,用了這個算法的多層感知機--也就是這篇文章講的神經網絡--也就叫做BP神經網絡(名詞混亂+1)。
這一章包含了比較複雜的公式推導過程,我的認爲不瞭解其細節也沒有關係、能夠跳過這一章(只看「正向傳播」一節就行),只要知道有個經典的反向傳播算法能夠快速求解?C/?w、?C/?b,從而算出Δw和Δb,使得ΔC恆爲負、即便得Loss愈來愈小便可。
正向傳播
正向傳播也能夠叫做前饋(因此又有個前饋神經網絡的詞...),正向傳播就是指給神經網絡的輸入,而後一層一層向前計算輸出,最終獲得一個輸出,這就是正向傳播了。
推導前的基本定義
w、a、b的定義
咱們使用 wljk 表示從 (l?1)th 層的 kth 個神經元到 (l)th 層的 jth 個神經元的連接上的權重。例如,下圖給出了第二隱藏層的第四個神經元到第三隱藏層的第二個神經元的連接上的權重:
咱們使用 blj 表示在 lth 層 jth 個神經元的誤差,使用 alj 表示 lth 層 jth 個神經元的激活值。下面的圖清楚地解釋了這樣表示的含義:
基於上面的定義,能夠寫出關於單個神經元激活值alj的公式,其中sum(l-1)表示(l?1)th 層的神經元數量:
上面w的表示方法或許很奇怪,但咱們把它寫成矩陣形式或許就能發現它的妙處了。用wl矩陣來表示第(l)th 層的w的值,用j做爲行,k行爲列,那麼上面的神經網絡中的w3就能夠寫成:
那麼也能夠用al矩陣來表示第(l)th 層的a的值,用j做爲行,但只有一列,那麼al實際上是一個列向量。那麼上面的a2能夠寫成下面很是形象的列向量形式:
同理,b3能夠也能夠寫成一個列向量:
那麼由上面的單個神經元激活值alj的公式,能夠得出al矩陣的公式:
單個神經元的帶權輸入zlj
從上面的公式中能夠提取出一箇中間量zlj:
固然也能夠簡寫成矩陣形式:
zlj其實就是第 l 層第 j 個神經元的激活函數帶權輸入。
單組數據的損失
前面介紹了損失函數,那麼對於某一組輸入,其損失(大寫的「L」表示輸出層)能夠寫做以下公式(這裏比上面的Loss公式少了個n,由於這裏只考慮一組輸入,而上面的Loss設定是考慮n組數據)。
這個公式一樣能夠寫成矩陣的形式,這裏用到了矩陣的模(能夠看附錄),模的平方即爲向量各元素的平方和。
單個神經元的偏差δlj測試
定義 l 層的第 jth 個神經元上的偏差 δlj 爲:
而後能夠再推演兩步:
推導
輸出層的偏差矩陣
由上面的單個神經元偏差公式,能夠得出輸出層偏差矩陣公式(注意這裏使用大寫的「L」表示輸出層,圓圈表示的Hadamard乘積能夠看附錄):
而因爲咱們採用的損失函數很是容易求出C對aL的導,因此公式能夠進一步簡化成:
某一層的偏差矩陣
首先推導下單個神經元偏差δlj與下一層(l+1層)的關係:
上面推導中比較難理解的多是累加k的由來,這是由於第lth層第jth個神經元會影響到第(l+1)th層的全部神經元,因此在反向計算偏導時須要考慮第(l+1)th層的全部神經元。
而後能夠得出第lth層的偏差矩陣(向量)δl的公式:
此次變換出現了矩陣轉置,可能也比較難以理解其由來。仔細觀察上面wkj會發現其中的j與k的順序與w的原始定義中的順序發生了對調,這能夠理解成轉置的緣由。本身拿一個示例演算一下也能發現從單個神經元偏差到某層神經元的偏差矩陣變換時的規律。
偏差與權重w的關係
在獲得了單個神經元的偏差以後,再來看看偏差與w的關係:
和上節的推演同樣,若寫成矩陣,則是以下形式:
偏差與誤差b的關係
與上面w的推導過程一致,容易獲得偏差與b的關係:
這個的矩陣形式就很簡單了:
總結
經過上面慘無人道的推導,能夠發如今通過一次正向傳播以後,能夠經過輸出層的偏差、快速求解出C對每一個w和b的偏導,即?C/?w、?C/?b,再對每一個w和b加上Δw、Δb,從而使得「球往下滾」,C、即Loss愈來愈小,神經網絡在朝着咱們指望的方向進行調整。
BP神經網絡的訓練流程
基於上面的知識,咱們如今能夠總結出訓練一個神經網絡的全流程:
初始化神經網絡,對每一個神經元的w和b賦予隨機值;
輸入訓練樣本集合,對於每一個樣本,將輸入給到神經網絡的輸入層,進行一次正向傳播獲得輸出層各個神經元的輸出值;
求出輸出層的偏差,再經過反向傳播算法,向後求出每一層(的每一個神經元)的偏差;
經過偏差能夠得出每一個神經元的?C/?w、?C/?b,再乘上負的學習率(-η),就獲得了Δw、Δb,將每一個神經元的w和b更新爲 w+Δw、b+Δb;
完成訓練以後,通常狀況下咱們都能獲得一個損失比較小的神經網絡。
附錄
矩陣
矩陣加法、減法
要求兩個矩陣大小(行數、列數)相同,而後相同位置的元素相加/相減。
矩陣乘法
這個應該都還記得,即左邊矩陣的一行乘上右邊矩陣的一列,所以矩陣相乘要求左邊矩陣的列數等於右邊矩陣的行數。
轉置
把矩陣A的行和列互相交換所產生的矩陣稱爲A的轉置矩陣(即第m行第n列元素轉爲第n行第m列元素),用符號T表示:
向量
只有一行的矩陣稱爲行向量,只有一列的矩陣稱爲列向量。行向量例如:
列向量例如:
PS:向量只是一種特殊的矩陣,矩陣乘法和轉置都是能夠用在向量上的。
Hadamard乘積:?
假設S和T是兩個一樣維度的向量,使用S?T來表示按元素的乘積。因此 S?T 的元素就是(S?T)j=SjTj。
向量的模(長度或大小)
在線性代數中,向量的大小用向量兩邊加雙豎線表示,向量的大小就是向量各份量平方和的平方根。若有向量S:
則其模爲:
參考資料
知乎:CNN(卷積神經網絡)、RNN(循環神經網絡)、DNN(深度神經網絡)的內部網絡結構有什麼區別?