若分類的對象是線性可分,我們可以使用感知器,若想以感知器處理線性不可分問題,基本上,也可以模仿支持向量機,透過核方法(Kernel method)的方式來處理。

但是,感知器就像個神經元,不如將一堆感知器組合為神經網路,就可以進行深度學習,達成複雜的任務,只不過在原理上,認識龐雜的數學推導過程雖是必要,但是,也容易令人忽視個別運算間可組合的本質。

分析、組合多個感知器

此時,我們試著自行分析、組合感知器如何?例如,若有一組身高、腰圍、體形的資料,其中體形標記了胖(-1)、適中(0)、瘦(1),現在想透過學習後的模型,從身高、腰圍資料來預測體形「是」「否」適中,也就是分為兩類,由於有過胖或過瘦的體形,所以,這會是個線性不可分的問題,無法使用一個感知器來達成任務。

如果我們將學習資料執行預處理,重新標記為胖(1)與不胖(0)(包含原資料的適中與瘦),這就成了線性可分問題,使用一個感知器P1就能學習;接著將學習資料做另一個預處理,重新標記為瘦(1)與不瘦(0)(包含原資料的適中與胖),同樣地,我們可以使用一個感知器P2來學習。

然而,發現什麼了嗎?胖(1)與不胖(0)、瘦(1)與不瘦(0)可以組成一個真值表,在P1、P2感知器都輸出為0(不胖與不瘦)的情況,就是適中體形,就程式上,只要使用OR邏輯,就可以達到目的,不過,我們可以再使用一個感知器P3,接受P1、P2的0、1輸出,自行學習出OR邏輯的行為。也就是說,感知器可以從隨機的權重與偏值開始,將真值表作為學習資料,感知器從中學習後,成為一個OR邏輯閘。

雖然單一感知器只能進行線性分類,然而組合多個感知器,就能完成非線性的任務,如這邊的簡單案例,透過自行組合感知器,我們就可以領略到:這其實就是每個感知器負責一個小任務,然後輸出再交給下一個感知器,進行下個小任務的處理。

方才談到了邏輯閘,其實,邏輯閘可以視為感知器的一個特例(只接受0與1,輸出0或1),雖然一個邏輯閘可以處理的邏輯有限,然而就電腦本身而言,不就是透過無數的邏輯閘組合後的成果(一個通用的圖靈機)。

激勵函數的空間轉換

對於一個感知器,它的輸出其實是透過W.X+b,W表示權重向量,X是變數值的向量,b是偏差值,W.X+b的值大於零輸出一,小於等於零輸出零。「值大於零輸出一,小於等於零輸出零」其實代表著單位階躍函數。

若將多個感知器組合為神經網路,階躍函數在其中就是一種激勵(activation)函數(或譯為活化函數)的角色,這是因為,它的輸出代表著對下層權重的激勵或活化程度,例如,0乘上權重還是0,就表示對權重沒有影響;在神經網路中,若無激勵函數,就無法解決非線性問題,單就數學推導上來看,也就是無論有多少個W.X+b組合,最後必然是W.X+b的形式,也就是最後結果仍是線性輸出。

「激勵」這名詞表達了對權重的影響程度,不過,並沒有表達出它在空間轉換上的效果。在討論單一感知器時,通常不會特別去留意到一件事,那就是,若將x與W.X+b值畫出來,會是個線性超平面,然而套用了「值大於零輸出一,小於等於零輸出零」,就會變成兩個不連續的超平面,也就是成為非線性,組合多個感知器時,就是進行多個非線性空間轉換的組合,轉後到最後一個空間的資料,投影至原資料空間,就是複雜的分類結果。

如果問題夠簡單,可以自行分析、構築數個感知器來組成神經網路,這時使用階躍函數並沒有問題,然而,若想自動從資料中學習,自動找出適當的權重組合,就不能使用階躍函數,因為學習過程必須透過梯度下降來尋找損失函數的最小值,而計算梯度需要透過微分,而階躍函數的微分是零,無法用於調整權重。

邏輯(logistic)函數是常用的激勵函數,函數圖形形狀類似S,被歸為Sigmoid函數或稱S函數,會讓重要資訊有較大輸出值(易接近一),不重要的資訊有較小輸出值(易接近零);另外一個常用的是線性整流函數(Rectified Linear Unit,ReLU),比較像是個開關,輸入若是小於零,就完全不影響下層權重,若輸出大於零,就完整地傳遞給下一層。

梯度的局部計算性

神經網路的學習過程中,資料會先正向傳播,也就是經過各個神經節點的權重運算後,得到最後的預測值,然後與訓練資料的實際值計算誤差(例如計算出交叉熵),從資料輸入得到誤差的函數就是損失函數,為了能調整權重,必須求得梯度,也就是損失函數求各權重變數偏微分後組成之向量,就程式實作來說並不難,然而運算上是耗時的。

在神經網路中,我們可以透過反向傳播,更有效率地求得梯度,只不過從神經網路的推導算式當中,去理解反向傳播,容易迷失而忽略了局部計算性的本質:一個巨大運算,可以分解為許多細小運算來看待。

例如,r=(2*x+3)*1.1,其實可以拆解為a=2*x、b=a+3、r=b*1.1,單看b=a+3就是一個小運算,a也許來自一個複雜運算的輸出,類似地,r=b*1.1的b也可以獨立看待,從x到整個運算過程,可以看成是個合成函式r(b(a(x)))。

如果對(2*x+3)*1.1直接求x的偏微分∂r/∂x,結果會是2.2,然而,從合成函式的觀點來看,∂r/∂x依連鎖律,我們可以利用構成合成函式的各函式微分相乘來表示,也就是∂r/∂b*∂b/∂a*∂a/∂x,也就是1.1*1*2,結果也是2.2,重點正在於∂r/∂b*∂b/∂a*∂a/∂x的順序,這表示微分值從b*1.1運算節點,反向傳播與a+3節點微分值相乘,接著,進一步反向傳播與2*x節點微分值相乘,就可以得到偏微分∂r/∂x。

神經網路結合了許多的權重、偏差、激勵函數、Softmax等運算,整個網路就是個巨大的合成函式,在實作神經網路時,可以將權重、偏差、激勵函數、Softmax等設計為獨立的運算節點,各節點只要在意自身的微分計算,各節點組合後,依順序將微分值相乘,就可以求得梯度,計算的速度會比對損失函數進行微分來得快速;以微分求梯度也不是沒有用處,因為可以用來驗證反向傳播求得的梯度。

運算之間具有可組合的本質

如果難以想像感知器如何組成神經網路,可以先想想邏輯閘,想辦法用感知器的原理,實現出AND、OR、NAND等邏輯閘;然後,再想想看,既然NAND都做出來了,不就什麼邏輯電路都組合得出來了嗎?由一堆感知器所組成的神經網路也是類似道理,只不過不限於零與一的輸出,透過多個激勵函數的組合,執行多次微小的空間變換,就可以達成複雜的需求。

相對於直接對損失函式微分,反向傳播是求梯度的另一種技巧,因為整個神經網路就是個巨大的合成函式,結合連鎖律,無論在計算或實作上,都可以獨立進行。

如果曾經對於神經網路的原理感到難以理解,或者迷失於公式推導,不妨從運算組合的本質來思考,個別運算與組合後各自代表了什麼,相信對於神經網路的運作與使用都能有更進一步的理解。

專欄作者

熱門新聞

Advertisement