翻譯 | 林椿眄
編輯 | Donna
本週,我們為您準備了一份資料科學家Ben Gorman撰寫的神經網路指導。這份指導包含了他具體的學習思路,包括所遇到的難點以及多種詳細的解決方法。
文章不短,但是值得深讀,請收藏!
人工神經網路當下非常流行。與任何流行的事物一樣,人工神經網路也收到了不少質疑。它究竟是賣弄玄虛,還是真正可以使無數人獲益的新技術呢?
為了讓大家入門神經網路,我從一個並不太瞭解的專業資料科學家的角度,和大家分享我的學習過程,希望對你們有所幫助。
需要注意的是,本文中所涉及的示例都是用R語言寫的程式碼。
讓我們從一個動機問題開始思考。這裡是一個灰度圖片的集合,每個2×2的畫素網格的畫素取值都是在0(白)到255(黑)之間。我們的目標是構建一個模型,用“階梯”的模式來識別圖片。
在這裡,我們來探討如何找到一個能夠合理擬合資料的模型感興趣。
方法一:預處理
對每張圖片,我們標記畫素X1,X2,X3,X4 , 並生成一個輸入向量X=[X1 X2 X3 X4],作為我們模型的輸入值。我們希望我們的模型能夠預測“True”(影像具有階梯模式)或為“False”(影像不具有階梯模式)。
方法二:單層感知器(模型迭代0次)
單層感知器是我們可以構建的一個簡單模型。當一個感知器使用線性權重組合的輸入時,可以得到一個預測值。如果預測的數值超過所選用的閾值,感知器則會判定為“True”,否則判定為“False”。更具體的說,
我們可以將它重新表示為如下形式:
這裡表示預測值。
圖形上,我們可以將感知器表示為一個由輸入到輸出的節點。
例如,我們假定構建如下的感知器:
這裡可以看到感知器是如何在我們的訓練影像上執行的。
這是合理的結果,肯定優於隨機猜測的效果。所有的階梯模式在其底部都有帶有深色陰影的畫素,能支援X3和X4採用更大的正係數。儘管如此,這個模型還是存在一些明顯的問題。
-
該模型輸出一個實數,它的值與自然的概念相關(值越大隱含著有更大的可能性說明影像表現為階梯模式),但是將這些值解釋為概率值是沒有依據的,特別當它們的取值範圍在[0,1]之外。
-
該模型無法捕捉到變數之間非線性的關係。
為了解這個問題,可以考慮以下的假設情況:
情況A:從一張影像開始,x = [100, 0, 0, 125],從0增至60.
情況B:從最後一張影像開始,x = [100, 0, 60, 125],從60增至120.
直觀上,相對於情況B來說,情況A的應該會有更大的增幅。然而,由於我們感知器模型只是一個線性等式,對於這兩種情況,X3增加了60,而只增加了0.12。
同時,我們的線性感知器還會有更多的問題,但是我們先來解決這兩個問題。
問題一:以Sigmoid為啟用函式的單層感知器(模型迭代1次):
我們可以通過將我們的感知器包在Sigmoid函式裡面(隨後選擇不同的權重值)來解決上述的問題1和2。回顧下Sigmoid函式是一條垂直方向上界定在0到1之間的S型曲線,因此經常被用來模擬二元事件發生的概率。
順著這個思路,我們用下面的圖片和方程式來更新我們的模型。
這就是Logistic迴歸。然而,將這個模型解釋為以Sigmoid為啟用函式的線性感知器也是很好的,因為這給了我們更多的空間去泛化。此外,由於我們將解釋為概率值,所以我們必須相應地更新我們的決策規則。
問題二:假定我們提出以下的擬合模型:
對比先前的部分,可以看出這個模型在相同的影像上是如何起作用的。
解決方法:
情況A:從一張影像開始,x = [100, 0, 0, 125],從0增至60.
情況B:從最後一張影像開始,x = [100, 0, 60, 125],從60增至120.
請注意,隨著的增加,Sigmoid函式是如何引起情況A的“觸發”現象(快速增加),但隨著z的持續增加,速度會減慢。這與我們的直覺是相一致的,即對於出現階梯的可能性,情況A應該反映出比情況B更大的增長。
不幸的是,這個模型仍然存在問題:
-
與每個變數都有單調的關係。如果我們想識別輕微的陰影階梯,那該怎麼辦?
-
該模型不考慮變數的互動問題。假設影像的底部是黑色的,如果左上角的畫素是白色,則右上角的畫素變暗會增加階梯出現的可能性。如果左上角的畫素是黑色的,則右上角的畫素變暗會降低階梯出現的可能性。換句話說,就是根據其他變數的值,增加X3應該可能增加或減少的值。目前我們的模型還無法實現這一點。
問題三:以Sigmoid為啟用函式的單層感知器(模型迭代2次):
我們可以通過在我們感知器模型上額外增加一個層來解決上述的兩個問題。我們將以上面的模型為基礎構建一系列基本模型,然後將每個基本模型的輸出作為輸入提供給另一個感知器。這個模型實際上就是一個 “香草型”的神經網路。讓我們通過一些例子看看它是如何工作。
例子1:識別階梯模式
-
構建一個模型,當左階梯模式被識別時觸發,
-
構建一個模型,當右階梯模式被識別時觸發,
-
增大每個基礎模型的得分,以便最後的S型函式只有在和都很大時才會被觸發。
或者
-
構建一個模型,當底部為暗色時才觸發,
-
構建一個模型,當左上角畫素為暗色且右上角畫素為亮色時才觸發,
-
構建一個模型,當左上角畫素為亮色且右上角畫素為暗色時才觸發,
-
增大基礎模型以便最後的sigmoid函式只有在和都很大,或者和都很大時才觸發(請注意和無法同時有很大的值)。
例子2:識別帶輕微陰影的階梯
-
構建一個模型,當底部為陰影,陰影x1和白色x2,陰影x2和白色x1時才被觸發,,和
-
構建一個模型,當底部為暗色,暗色x1和白色x2,暗色x2和白色x1時才被觸發, ,和
-
將模型組合起來以便在使用sigmoid函式壓縮之前, “暗色”的識別符號能夠基本上從 “陰影”識別符號中除去。
專業術語註釋
單層感知器具有單個的輸出層。因此,我們剛剛構建的模型將被稱為雙層感知器,因為模型的一個輸出層,是另一個輸出層的輸入。然而,我們可以將這些模型稱為神經網路,就這方面而言,網路有三層–輸入層,隱藏層和輸出層。
可替代的啟用函式
在我們的例子中,我們使用了一個sigmoid作為啟用函式。但是,我們可以使用其他的啟用函式。雙曲正切函式、 修正線性單元都是常用的選擇。啟用函式必須是非線性的,否則神經網路將等價於單層的感知器。
多目標分類
通過在最終輸出層中使用多個節點,我們可以輕鬆地將我們的模型擴充套件成多分類模型。這裡用到的想法是,每個輸出對應於我們想要預測的類別之一C,我們可以使用Softmax函式將空間中的一個向量對映到中的另一個向量,如此使得向量的元素之和為1,而不是通過sigmoid函式對映空間的一個輸出元素並將其壓縮在[0,1]之間輸出。換句話說,我們可以設計一個網路使得它的輸出向量是如此的形式:。
使用不止兩層的神經網路,即深度學習
你可能想知道,我們是否可以擴充套件我們的香草式神經網路,使得其輸出層被輸入到第四層(進而第五層,第六層等等)?
是這樣的,這就是通常所說的“深度學習”。實踐中,它非常高效。但是值得注意的是,任何一個隱藏層都可以通過一個單隱藏層的網路來模擬。實際上,根據通用逼近定理,可以使用具有單個隱藏層的神經網路來逼近任何連續的函式。
深層神經網路架構經常選擇偏向於單個隱層結構的原因就在於,他們更傾向於在擬合過程中更快速地收斂並得到最終的結果。
用模型去擬合帶標籤的訓練樣本 (反向傳播法)
在擬合階段,到目前為止,我們已經討論了神經網路如何能夠有效地工作,但是我們還沒有討論如何用神經網路去擬合帶標籤的訓練樣本。
一個等價的問題就是:給定一些帶標籤的訓練樣本,我們該如何選擇網路的最佳權重值?
對此,梯度下降法是常見的答案(儘管用最大似然估量法也可以做到)。
下面繼續我們的示例問題,梯度下降的過程會像這樣:
-
以一些帶標籤的訓練資料開始
-
選擇一個可微的損失函式並最小化,
-
選擇一個網路結構。具體地說就是確定網路的層數以及每層的節點數
-
隨機地初始化網路權重
-
用網路執行訓練資料來生成每個樣本的預測值。根據損失函式來度量總體的誤差值(這就是所謂的前向傳播過程)。
-
當每個權重發生小的變化,確定當前的損失值將改變多少。換句話說,計算L對於網路中每個權重的梯度值(這就是所謂的後向傳播過程)。
-
沿負梯度的方向走一小步。例如,,,那麼小幅度的減少會導致當前損失小幅度的降低。因此我們更新(這裡0.001就是我們所預定義的步長)。
-
以固定的次數重複進行這個過程(從步驟5開始),直至損失函式收斂為止。
這些是最基本的想法。實際中,這面臨了一系列的困難:
挑戰一: 計算複雜度
在擬合的過程中,我們需要計算的一個東西是L對於每個權重的梯度值。這是個棘手的問題,因為L依賴於輸出層中的每個節點,並且每個節點依賴於之前的層中的每個節點,以此類推。這就意味著計算是一個鏈式規則的噩夢(請記住,實際上許多神經網路都有數十層數千個節點)。
我歸納瞭解決這個噩夢的四個技巧。
處理這個問題的關鍵是要認識到,在應用鏈式規則的時候,將重用相同中間層的導數值。
如果你仔細追蹤這個的話,你就可以避免重新計算相同的東西幾千次。
另一個技巧就是使用特殊的啟用函式,其衍生物可以寫成他們值的函式。例如,=的導數。這是很方便的,因為在正向傳播過程中,當我們計算每個訓練樣本時,我們必須為某個向量x逐元素地計算。
在反向傳播過程中,我們可以在計算L相對於權重的梯度時重用這些值,從而節省時間和記憶體的佔用。
第三個技巧就是將訓練資料分成“小批量”,並逐一更新每個批次的權重。例如,如果將訓練資料劃分為{batch1,batch2,batch3},則訓練資料首先將
-
使用batch1更新權重值
-
使用batch2更新權重值
-
使用batch3更新權重值
這裡,L的梯度將在每次更新後重復地計算。
最後的一個值得注意的技巧就是使用GPU而不是CPU,因為GPU更適合並行地執行大量的計算。
挑戰二:梯度下降法可能會無法找到絕對最小值點
這不僅僅是一個神經網路的問題,因為它也是一個梯度下降問題。在梯度下降的過程中,權重可能會陷入區域性最小值。權重也可能超過最小值。
處理這個問題的一個技巧就是調整不同的步長。
另一個技巧就是增加網路中的節點數或網路層數(注意過擬合現象)。
此外,一些像使用動量的啟發式技巧也可能有效。
挑戰三: 如何泛化?
我們如何編寫一個通用的程式來擬合任何數量的節點和網路層的神經網路呢?
答案是, 你不用這樣做,你是用Tensorflow。但是,如果你真的想這麼做的話,最困難的部分就是計算損失函式的梯度。
這麼做的技巧就是意識到你可以把梯度表示為一個遞迴函式。5層的神經網路只是一個4層帶一些感知器的神經網路,而4層的神經網路只是一個3層帶一些感知器的神經網路。諸如此類。更正式的說,這稱為自動分化。
作者:Ben Gorman
原文連結: