Author:louwill
From:深度學習筆記
深度學習作為當前機器學習一個最熱門的發展方向,仍然保持著傳統機器學習方法的理念與特徵,從監督學習的角度看,深度學習與機器學習並無本質上的差異。隱藏層使得感知機能夠發展為擬合萬物的神經網絡模型,而反向傳播算法則是整個神經網絡訓練的核心要義。要學習深度學習,恐怕不得不先溫習一下機器學習,搞清楚二者之間的關係。簡單來說,機器學習就是從歷史數據中探索和訓練出數據的普遍規律,將其歸納為相應的數學模型,並對未知的數據進行預測的過程。至於在這個過程中我們碰到的各種各樣的問題,比如數據質量、模型評價標準、訓練優化方法、過擬合等一系列關乎機器學習模型生死的問題,在這裡不做具體展開,大家可以去補習相關的機器學習知識。在機器學習中,有很多相當成熟的模型和算法。其中有一種很厲害的模型,那就是人工神經網絡。這種模型從早期的感知機發展而來,對任何函數都有較好的擬合性,但自上個世紀90年代一直到2012年深度學習集中爆發前夕,神經網絡受制於計算資源的限制和較差的可解釋性,一直處於發展的低谷階段。之後大數據興起,計算資源也迅速跟上,加之2012年ImageNet競賽冠軍採用的AlexNet卷積神經網絡一舉將圖像分類的Top5錯誤率降至16.4%,震驚了當時的學界和業界。從此之後,原本處於研究邊緣狀態的神經網絡又迅速火熱了起來,深度學習也逐漸佔據了計算機視覺的主導地位。注意:這裡有必要解釋一下模型和算法的概念,通常我們所說的像支持向量機(Support Vector Machine,以下簡稱SVM)之類的所謂機器學習十大算法其實不應該稱之為算法,更應該稱之為模型。機器學習算法應該是在給定模型和訓練策略的情況下採取的優化算法,比如梯度下降、牛頓法等。當然,一般情況下將機器學習中的模型和算法概念混在一起並沒有十分不妥之處,畢竟模型中本身就包含著計算規則的意思。講了這麼多,無非就是想讓大家知道,以神經網絡為核心的深度學習是機器學習的一個領域分支,所以深度學習在其本質上也必須遵循機器學習的基本要義和法則。在傳統的機器學習中,我們需要訓練的是結構化的數值數據,比如預測銷售量、預測某人是否按時還款,等等。但在深度學習中,其訓練輸入就不再是常規的數值數據了,它可能是一張圖片、一段語言、一段對話語音或一段視頻。深度學習要做的就是輸入一張狗的圖片到神經網絡裡,它的輸出是狗或者dog這樣的標籤,輸入一段語音,它輸出的是比如「你好」這樣的文本。綜上所述可以看出,機器學習(深度學習)的核心任務就是找(訓練)一個模型,它能夠將輸入轉化為正確的輸出。深度學習看起來就像是一個黑箱機制,輸入各種非結構化的數據之後出來預測結果,比如輸入一段語音,輸出為「Hello, World!」這樣的文本;輸入一張狗的圖像,輸出為「狗」這樣的標籤;輸入一副棋盤和當前的局勢,輸出為下一步的走棋方式;輸入「你好!」這樣一句中文,輸出為「Hi!」這樣一句英文,等等。我們很難對輸入與輸出之間的模型轉化過程給出一個合理的解釋。在實際工作中,調用像 TensorFlow 這樣優秀的深度學習框架能夠幫助我們快速搭建起一個深度學習項目,但在學習深度學習的時候,不建議大家一開始就上手各種深度學習框架,希望大家能和我們一道,在把基本原理搞清楚之後利用Python自己手動去編寫模型和實現算法細節。為了學習深度學習和各種結構的神經網絡,我們需要從頭開始。感知機作為神經網絡和支持向量機的理論基礎,一定要清楚其中的模型細節。簡單來說,感知機就是一個旨在建立一個線性超平面對線性可分的數據集進行分類的線性模型。其基本結構如圖1所示。圖1從左到右為感知機模型的計算執行方向,模型接受了三個輸入,將輸入與權值參數進行加權求和並經過Sigmoid函數進行激活,將激活結果作為輸出。這便是感知機執行前向計算的基本過程。這樣就行了嗎?當然不行。剛剛我們只解釋了模型,對策略和算法並未解釋。當我們執行完前向計算得到輸出之後,模型需要根據你的輸出和實際的輸出按照損失函數計算當前損失,計算損失函數關於權值和偏置的梯度,然後根據梯度下降法更新權值和偏置,經過不斷的迭代調整權值和偏置使得損失最小,這便是完整的單層感知機的訓練過程。圖2所示是輸入為圖像的感知機計算過程。前面講的是單層感知機,單層感知機包含兩層神經元,即輸入與輸出神經元,可以非常容易地實現邏輯與、邏輯或和邏輯非等線性可分情形,但是單層感知機的學習能力是非常有限的,對於像異或問題這樣的線性不可分情形,單層感知機就搞不定了(所謂線性不可分,即對於輸入訓練數據,不存在一個線性超平面能夠將其進行線性分類)。其學習過程會出現一定程度的振蕩,權值參數難以穩定下來,最終不能求得合適的解,異或問題如圖3 c圖所示。對於線性不可分的情況,在感知機基礎上一般有兩個解決方向,一個是著名的SVM,旨在通過核函數映射來處理非線性的情況,而另一種就是神經網絡模型。這裡的神經網絡模型也叫作多層感知機(Muti-Layer Perception,以下簡稱MLP),與單層的感知機在結構上的區別主要在於MLP多了若干隱藏層,這使得神經網絡能夠處理非線性問題。可以看到,相較於兩層神經元的單層感知機,多層感知機中間多了一個隱藏層。何為隱藏層?就是在神經網絡的訓練過程中我們只能觀察到輸入和輸出層的數據,對於中間的隱藏層的數據變化我們是看不見的,因而在深度神經網絡(Deep Neural Networks,以下簡稱DNN)中,對於中間看不見又難以對其效果進行合理解釋的隱藏層稱之為「黑箱子」。含隱藏層的神經網絡是如何訓練的呢?與感知機一樣,神經網絡的訓練依然包含前向計算和反向傳播兩個主要過程。當然,單層感知機沒有反向傳播這個概念,而是直接建立損失函數對權值和偏置參數進行梯度優化。前向計算簡單來說,就是權值偏置與輸入的線性加權和激活操作,在隱藏層上有個嵌套的過程。這裡我們重點講反向傳播算法(Error Back Propagation,也叫誤差逆傳播),作為神經網絡的訓練算法,反向傳播算法可謂是目前最成功的神經網絡學習算法。我們通常說的BP神經網絡就是指應用反向傳播算法進行訓練的神經網絡模型。那麼,反向傳播算法的工作機制究竟是怎樣的呢?這裡需要大家複習一下在大學課本階段學習的微積分知識。下面以一個兩層(即單隱層)網絡為例,也就是圖5中的網絡結構,給大家詳細推導一下反向傳播的基本過程。假設輸入層為x,輸入層與隱藏層之間的權值和偏置分別為w1和b1,線性加權計算結果為z1=w1x+b1,採用sigmoid激活函數,激活輸出為a1=σ(z1)。而隱藏層到輸出層的權值和偏置分別為w2和b2,線性加權計算結果為z2=w2x+b2,激活輸出為a2=σ(z2)。所以這個兩層網絡的前向計算過程為x-z1-a1-z2-a2。可以看出,反向傳播的直觀理解就是將前向計算過程反過來,但必須是梯度計算的方向反過來,假設我們這裡採用如下的交叉熵損失函數。 反向傳播是基於梯度下降策略的,主要是以目標參數的負梯度方向對參數進行更新,所以基於損失函數對前向計算過程中各個變量進行梯度計算就非常必要了。將前向計算過程反過來,那基於損失函數的梯度計算順序就是da2-dz2-dw2-db2-da1-dw1-db1。我們從輸出a2開始進行反向推導,輸出層激活輸出為a2,那首先計算損失函數L(y,a)關於a2的微分da2,影響a2輸出的是誰呢?由前向傳播可知a2是由z2經激活函數激活計算而來的,所以計算損失函數關於z2的導數dz2必須經由a2進行複合函數求導,即微積分上常說的鏈式求導法則。然後繼續往前推,影響z2的又是哪些變量呢?由前向計算可知影響的有w2、a1和b2,繼續按照鏈式求導法則進行求導即可。最終以交叉熵損失函數為代表的兩層神經網絡的反向傳播向量化求導計算公式如下所示。注意:鏈式求導法則對複合函數進行求導的一種計算方法,複合函數的導數將是構成複合這有限個函數在相應點的導數的乘積,就像鏈子一樣一環套一環,故稱鏈式法則。在有了梯度計算結果之後,我們便可根據權值更新公式對權值和偏置參數進行更新了,具體計算公式如下,其中為學習率,是個超參數,需要我們在訓練時手動指定,當然也可以對其進行調參以取得最優超參數。 以上便是BP神經網絡模型和算法的基本工作流程,如圖5所示。總結起來就是前向計算得到輸出,反向傳播調整參數,最後以得到損失最小時的參數為最優學習參數。經過近十幾年的發展,神經網絡的結構已經從普通的全連接網絡發展到卷積神經網絡、循環神經網絡、自編碼器、生成式對抗網絡和圖神經網絡等各種各樣的結構,但BP算法一直是神經網絡一個經典和高效的尋優工具。通過本節內容來看,訓練一個BP神經網絡並非難事,我們有足夠優秀的深度學習計算框架,讀者通過幾行代碼就可以搭建起一個全連接網絡。但是,為了掌握神經網絡的基本思維範式和鍛鍊實際的編碼能力,希望讀者朋友們能夠利用Python在不調用任何算法包的情況下根據算法原理手動實現一遍神經網絡模型。往期精彩:
【原創首發】機器學習公式推導與代碼實現30講.pdf
【原創首發】深度學習語義分割理論與實戰指南.pdf
喜歡您就點個在看!