一小時神經網絡從入門到精通(放棄)


http://blog.itpub.net/31077337/viewspace-2156393/

 

 本文主要是學習BP神經網絡的一個總結,其本身也是機器學習中比較基礎、適合入門的模型。

  目前本人對於機器學習也還只是入門狀態,對於很多名詞仍然是一知半解(感覺機器學習中的很多術語本身也是模棱兩可的),對於很多公式也是不求甚解,因此這篇文章是嘗試用自己的語言和理解來復述所學習到的知識,如果有錯誤之處還望大牛們不吝斧正。

  霍金說過每多一個數學公式,就會少一半的讀者,因此這里也會盡量少用公式,要用也只用簡單易懂的公式。而且個人覺得神經網絡中的很多公式是可以感性地去認識的,能完全明白推導過程自然最好,但在不求甚解的狀態下能達到感性的認知也未必不是一個快速掌握的好方法。

  另外本文中用到了不少矩陣相關的知識,忘記了的同學可以看附錄中的整理。

  神經元與激勵函數

  神經元

  神經元是神經網絡的基本組成,如果把它畫出來,大概就長成下面這樣:

一小時神經網絡從入門到精通(放棄)

  圖中神經元左邊的x表示對神經元的多個輸入,w表示每個輸入對應的權重,神經元右邊的箭頭表示它僅有一個輸出。

  當然神經元也有很多種,下面介紹兩種比較基礎的。

  神經元1:感知器

  神經網絡技術起源於上世紀五、六十年代,當時叫感知機(perceptron),其中的單個神經元我們可以叫作感知器。感知器的特點具有濃厚的時代氣息:其輸入輸出都是二進制形式的(據說由於計算技術的落后,當時感知器傳輸函數是用線拉動變阻器改變電阻的方法機械實現的)。

一小時神經網絡從入門到精通(放棄)

  如上圖所示,感知器有多個二進制輸入(值只能是0或1)X1、X2..Xn,每個輸入有對應的權值W1、W2..Wn(圖中沒畫出來),將每個輸入值乘以對應的權值再求和( ∑XjWj ),然后與一個閾值(threshold) 比較,大於閾值則輸出1、小於閾值則輸出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(深度神經網絡)的內部網絡結構有什么區別?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM