第六章 深度学习(上)
在上一章,我們學習了深度神經網絡通常比淺層神經網絡更加難以訓練。我們有理由相信,若是可以訓練深度網絡,則能夠獲得比淺層網絡更加強大的能力,但是現實很殘酷。從上一章我們可以看到很多不利的消息,但是這些困難不能阻止我們使用深度神經網絡。本章,我們將給出可以用來訓練深度神經網絡的技術,并在實戰中應用它們。同樣我們也會從更加廣闊的視角來看神經網絡,簡要地回顧近期有關深度神經網絡在圖像識別、語音識別和其他應用中的研究進展。然后,還會給出一些關于未來神經網絡又或人工智能的簡短的推測性的看法。
這一章比較長。為了更好地讓你們學習,我們先粗看一下整體安排。本章的小結之間關聯并不太緊密,所以如果讀者熟悉基本的神經網絡的知識,那么可以任意跳到自己最感興趣的部分。
本章主要的部分是對最為流行神經網絡之一的深度卷積網絡的介紹。我們將細致地分析一個使用卷積網絡來解決 MNIST 數據集的手寫數字識別的例子(包含了代碼和講解):
MNIST 數據集樣例
我們將從淺層的神經網絡開始來解決上面的問題。通過多次的迭代,我們會構建越來越強大的網絡。在這個過程中,也將要探究若干強大技術:卷積、pooling、使用GPU來更好地訓練、訓練數據的算法性擴展(避免過匹配)、dropout 技術的使用(同樣為了防止過匹配現象)、網絡的 ensemble 使用 和 其他技術。最終的結果能夠接近人類的表現。在 10,000 幅 MNIST 測試圖像上 —— 模型從未在訓練中接觸的圖像 —— 該系統最終能夠將其中 9,967 幅正確分類。這兒我們看看錯分的 33 幅圖像。注意正確分類是右上的標記;系統產生的分類在右下:
深度神經網絡在 MNIST 實驗中的性能
可以發現,這里面的圖像對于正常人類來說都是非常困難區分的。例如,在第一行的第三幅圖。我看的話,看起來更像是 “9” 而非 “8”,而 “8” 卻是給出的真實的結果。我們的網絡同樣能夠確定這個是 “9”。這種類型的“錯誤” 最起碼是容易理解的,可能甚至值得我們贊許。最后用對最近使用深度(卷積)神經網絡在圖像識別上的研究進展作為關于圖像識別的討論的總結。
本章剩下的部分,我們將會從一個更加寬泛和宏觀的角度來討論深度學習。概述一些神經網絡的其他模型,例如 RNN 和 LSTM 網絡,以及這些網絡如何在語音識別、自然語言處理和其他領域中應用的。最后會試著推測一下,神經網絡和深度學習未來發展的方向,會從 intention-driven user interfaces 談道 深度學習在人工智能的角色。
這章內容建立在本書前面章節的基礎之上,使用了前面介紹的諸如 BP,正規化、softmax 函數,等等。然而,要想閱讀這一章,倒是不需要太過細致地掌握前面章節中內容的所有的細節。當然讀完第一章關于神經網絡的基礎是非常有幫助的。本章提到第二章到第五章的概念時,也會在文中給出鏈接供讀者去查看這些必需的概念。
需要注意的一點是,本章所沒有包含的那一部分。這一章并不是關于最新和最強大的神經網絡庫。我們也不是想訓練數十層的神經網絡來處理最前沿的問題。而是希望能夠讓讀者理解深度神經網絡背后核心的原理,并將這些原理用在一個 MNIST 問題的解決中,方便我們的理解。換句話說,本章目標不是將最前沿的神經網絡展示給你看。包括前面的章節,我們都是聚焦在基礎上,這樣讀者就能夠做好充分的準備來掌握眾多的不斷涌現的深度學習領域最新工作。
本章仍然在Beta版。期望讀者指出筆誤,bug,小錯和主要的誤解。如果你發現了可疑的地方,請直接聯系 mn@michaelnielsen.org。
卷積網絡簡介
在前面的章節中,我們教會了神經網絡能夠較好地識別手寫數字:
MNIST 手寫數字
我們在深度神經網絡中使用全連接的鄰接關系。網絡中的神經元與相鄰的層上的所有神經元均連接:
全連接深度神經網絡
特別地,對輸入圖像中的每個像素點,我們將其光強度作為對應輸入層神經元的輸入。對于 2828 像素的圖像,這意味著我們輸入神經元需要有 784(=28 28) 個。接著我們訓練網絡的權重和偏差,使得最后網絡可以正確識別輸入圖像: '0', '1', '2', ..., '8', 或者 '9'。
我們前面使用的網絡效果已經不錯了:我們使用來自MNIST handwritten digit data set訓練數據和測試數據獲得了超過 98% 準確度的分類結果。但是,仔細看看,使用全連接層來分類圖像其實是很奇怪的。因為,這樣的網絡結構并沒有考慮圖像本身的空間結構。例如,對輸入像素,網絡將離得很遠和很近的像素都同等看待。這樣的空間結構概念必須從訓練數據中推斷出來。但是如果我們不從一個簡單的網絡開始,而使用一個針對空間結構的網絡,效果會怎么樣?本節,我們會介紹卷積神經網絡。這些網絡使用一種特定的結構,主要適配于圖像的分類。使用這種結構讓卷積網絡訓練速度有所提升。這樣也能夠幫助我們訓練深層的、多層的適用圖像分類的網絡。現在深度卷及網絡或者類似的變體在圖像識別中用得最為頻繁。
卷積神經網絡的誕生要回到 1970 年代。但是建立起現代卷積網絡的開創性論文出現在 1998 年,"Gradient-based learning applied to document recognition" 這篇由 Yann LeCun, Léon Bottou, Yoshua Bengio, 和 Patrick Haffner 合作的論文。LeCun 已經給出了關于卷積網絡模型所受到的生物學上的啟發:“諸如卷積網絡受到(生物)神經學的啟發還是很微小的。這也是我們稱此為卷積網絡而不是卷積神經網絡的原因,其中的節點我們也叫做單元(unit)而不是神經元(neuron)。”盡管有此說明,卷積網絡也使用了大量我們之前講述的神經網絡中的想法:如 BP、梯度下降、正規化、非線性激活函數等等。所以我們會遵循通常的實踐,將卷積網絡看成是神經網絡的一種類型。后面卷積網絡和卷積神經網絡會交換使用。當然 (人工)神經元和單元 也是換著使用的。
卷積神經網絡擁有三個基本特性:局部感知區、共享權重和pooling。下面詳細討論這三個概念。
局部感知區:在全連接層中,輸入被看做是豎直方向的神經元列。在卷積網絡中,可以將輸入看做是 28 * 28 的神經元的正方形,其中每個神經元對應于輸入圖像的像素。
Paste_Image.png
正如往常那樣,我們將輸入像素連接到隱藏層上。但是我們不會將每個輸入像素連接到每個隱藏元上。而是僅僅在輸入圖像上做一個局部小規模的連接。
更加準確地說,在第一隱藏層的每個神經元將會被連接到輸入神經元的小區域上,例如,一個 5 * 5 的局域,對應于 25 個輸入像素。所以,對一個特定的隱藏元,我們可能會有如下的連接:
Paste_Image.png
在輸入圖像中的那個區域被稱為隱藏元的局部感知區。這是在輸入像素上的一個小窗口。每個連接學習一個權重。隱藏元同樣會學習一個整體的偏差。你可以將這種特定的隱藏元看做是在學習分析其對應的局部感知區。
接著我們將窗口在整個輸入圖像上進行滑動。對每個局部感知區,在第一隱藏層,存在一個不同的隱藏元。為形象地解釋這個過程,我們給出一個例子:
Paste_Image.png
以此下去,可以構建出整個第一隱藏層。注意,如果我們有一個 28 28 的圖像作為輸入,然后局部感知區為 5 5,那么最后在隱藏層就有 24 * 24 個神經元。這是因為我們只能移動局部感知區 23 次(或者向下移動 23 次),直到抵達最右側(或者最底部)。
我已經展示了移動一次局部感知區的效果。實際上,有時候會有不同的步長。例如,我們可以每次移動局部感知區 2 個像素。稱步長為 2。本章幾乎所有例子都使用 1 的步長,但最好要知道這個值是可以進行調整的。
正如我們在前面章節所講的,如果我們對不同步長感興趣,就可以使用驗證數據,在不同步長上實驗不同的效果,最終選擇最優的步長。可以參考這里 了解神經網絡中超參數的選擇。同樣的方法也可以用來選擇局部感知區的大小上。一般來說,更大的局部感知區在輸入圖像明顯大于 28 * 28 的 MNIST 圖像時更有用。
共享權重和偏差:我已經提到每個隱藏元有一個偏差和一個連接在其局部感知區的 5 5 的矩陣。而沒有提及的則是,我們將會使用同樣的權重和偏差對所有 2424 個隱藏元。換言之,對 j,k 隱藏元,輸出是
$$\sigma(b + \sum_{l=0}^{4}\sum_{m=0}^{4} w_{l,m}a_{j+l, k+m})$$
Paste_Image.png
這里,$$\sigma$$ 是神經元的激活函數——可能是 sigmoid 函數。$$b$$是共享的偏差。$$w_{l,m}$$ 是 5 * 5 的共享權重矩陣。最后,使用 $$a_{x,y}$$ 表示在 $$x,y$$ 處的輸入激活值。
這意味著所有第一隱藏層的神經元檢測除了同樣的特征,只是在輸入圖像不同的位置而已。我們來看看為何這樣是合理的,假設權重和偏差可以讓神經元能夠獲取特定的局部感知區的豎直線。這個能力同樣可以用在圖像中其他的地方。所以,應用同樣的特征檢測器在圖像中的每個地方。用更為抽象一點的術語就是,卷積網絡可以適應圖像的轉化不變性:移動一點點貓的圖像,仍然保證得到的是貓的圖像。
實際上,對 MNIST 數字分類問題,圖像處于正中央,大小也是規范化了的。所以 MNIST 不大會有在其他圖像中發現的變化不變性。諸如邊和角這樣的特征可能在大部分輸入空間上都有用。
因此,我們有時候將輸入層到隱藏層的映射稱為 特征映射。我們稱定義了這個映射的權重為 共享權重。而相應的偏差就叫做共享偏差 了。共享權重和偏差常常被稱為 核(Kernel)或者 過濾器(filter)。在文獻中,人們使用這些術語會存在一些差異,所以我這里不會在細化;而是會討論一些具體的例子。
目前描述的網絡結構可以檢測出一種單一的局部特征。為了進行圖像識別,我們需要更多的特征映射。所以,完整的卷積層包含一些不同的特征映射:
Paste_Image.png
在上面的例子中,存在 3 個特征映射。每個特征映射使用一個 5 * 5 的共享權重和一個共享偏差定義。結果就得到了一個可以檢測三個不同的特征的網絡,每個特征是在全圖范圍內得到的。
我這里為了讓圖很簡單就展示了 3 個特征映射。然而,在實際情況中,卷積網絡可能使用很多很多特征映射。早期的卷積網絡,如 LeNet-5,使用了 6 個特征映射,每個關聯于 5 * 5 的局部感知區,來識別 MNIST 數字。所以,上面展示的例子很接近 LeNet-5。本章后面的例子中我們會使用擁有 20 和 40 個特征映射的卷積層。讓我們看看這些例子學到的特征吧:
來自我們最終版的卷積網絡的特征映射,參見這里
Paste_Image.png
這 20 幅圖對應 20 個不同的特征映射(過濾器或者核)。每個映射表示為 5 5 的塊圖,對應于局部感知區中的 5 5 的權重。稍白的塊表示略小的權重,這樣特征映射更少地對相應的輸入像素產生反應。更黑的塊表示略大的權重,這樣特征映射更多地對相應的輸入像素產生反應。粗略地說,上面的圖像展示了卷積層對應的特征類型。
所以我們從這些特征映射中能夠得到什么結論呢?很顯然,這里有一種并非是隨機的空間結構:很多特征有明顯的亮暗子區域。這表明,我們的網絡真的在學習與空間結構相關的知識。不過,看明白這些特征檢測器究竟在學習什么是很困難的。可以肯定的是,我們并沒有在學習(打個比方)Gabor 過濾器,這種用在很多傳統的圖像識別方法中的技術。實際上,現在有很多的努力都花費在更好地理解卷積網絡學到的東西上。如果你對此感興趣,我推薦你看看 Matthew Zeiler 和 Rob Fergus 在 2013 年的這篇文章:Visualizing and Understanding Convolutional Networks。
共享權重和偏差的重要優勢是他們大幅降低了參數的數量。對每個特征映射,我們需要 25 = 5 5 個共享變量和一個共享偏差。所以每個特征映射需要 26 個參數。如果我們有 20 個特征映射,那么對一個卷積層總共要學習 2026 = 520 個參數。假設我們第一層用一個全連接層,共 784 = 28 28 個輸入神經元,和一個相對少量 30 個隱藏元,跟前面的例子中保持一致。那就共有 78430 個權重和 30 個偏差,總共就是 23, 550 個參數。換言之,全連接層會有超過卷積層 40 倍的參數量。
當然我們不能真的就對參數的個數進行直接對比,因為這兩個模型是本質不同的。但是,直覺地看,看起來卷積層的變化不變性的使用相比于全連接模型達到同樣的性能會降低需要學習的參數的個數。這樣將會得到更快的訓練的模型,最終能夠幫助我們構建使用卷積層的深度網絡。
巧合的是,卷積網絡的命名來自方程(125)的操作,那個操作就叫做卷積。更準確地說,人們有時候會把那個公式寫成 $$a^1 = \sigma(b + wa^0)$$,其中 $$a^1$$ 表示從一個特征映射中輸出的激活值,$$$$ 表示卷積操作。我們不會再后面使用任何更難的卷積操作,所以不必擔心這個關聯。不過至少應該了解這個詞的來源。
Pooling 層:在卷積網絡中,還包含了一個叫做 pooling 的層。Pooling 層通常會立即用在卷積層后。而 pooling 層所做的實際上就是簡化從卷積層得到的輸出。
pooling 層使用卷積層的每個特征映射作為輸出,并得到一個壓縮了的特征映射。例如,pooling 層的每個單元可能會對上一層中的一個(如 22 大小) 的區域進行總結。用具體例子,一個通常使用的 pooling 操作是 *max-pooling*。在 max-pooling 中,pooling 單元就會輸出 22 區域中最大的那個激活值,如下圖所示:
Paste_Image.png
注意,因為我們的卷積層輸出是 2424 神經元,pooling 之后就是 12 12 個神經元。
正如下面所述,卷積層通常包含超過一個特征映射。然后我們分別應用 max-pooling 到每個特征映射上。所以如果有三個特征映射,組合的卷積和max-pooling 層就是這樣子:
Paste_Image.png
我們可以見 max-pooling 看成是網絡確認一個給定特征是否在圖像區域中任何地方都存在的方法。接著會丟棄準確位置信息。這個直覺就是一旦特征被發現了,其準確的位置就相對于其他特征來說不那么重要了。最大的好處就是,這樣會產生更少量的pooling后的特征,降低了在后面網絡層的參數的數量。
max-pooling 不是 pooling 的唯一技術。另一個常用的方法是 L2 pooling。這里使用 2*2 區域內神經元的激活值的平方和的平方根。盡管細節不同,直覺上仍然和 max-pooling 相似:L2 pooling 是一種壓縮來自卷積層的信息的方法。實際應用中,兩種方法都廣泛使用。有時候人們還會嘗試別的 pooling 操作。如果你真的想優化性能,可能需要使用驗證數據來比較不同的 pooling 技術,選擇那些表現最好的。但是我們這里不會去詳細討論優化的細節。
整合所有這些方法:我們可以將這些方法整合起來形成一個完整的卷積神經網絡。類似于我們剛剛看過的那些架構,不過會增加一個有 10 個輸出神經元的層,對應于不同的 10 個數字:
Paste_Image.png
這個網絡以 28 28 輸入神經元作為第一層,來編碼 MNIST 圖像的像素強度。接著跟隨一個使用 5 5 的局部感知區和 3 個特征映射的卷積層。結構是一個 324 24 的隱藏特征神經元層。下一步就是加入一個 max-pooling 層,應用在 22 區域上,共有 3 個特征映射。最終就是一個 312 * 12 的隱藏特征神經元層。
最終層的連接是一個全連接方式。該層連接來自 max-pooling 層輸出到這所有 10 個神經元上。注意這和我們之前介紹的一樣。盡管圖中只用了一根帶箭頭的線表示。這很容易想象補全。
這個卷積結構完全不同于我們之前使用的架構。不過整體的圖結構類似:擁有多個簡單輸入段元的網絡,網絡的行為完全由權重及偏差確定。整體的目標也一致:使用訓練數據來訓練網絡權重和偏差,這樣讓網絡能夠很好地對輸入數字圖像進行分類。
特別地,和本書前面章節中一樣,我們會使用隨機梯度下降和 BP 來進行訓練。這個流程和我們前面介紹的都是一致的。然后,我們這里需要對 BP 進行一些修改。因為前面章節的 BP 推導都是在全連接的層下進行的。幸運的是,這里的修改是很直接的。如果你想理解這些細節,我希望你能夠仔細研究一下下面的問題。需要注意的是該問題會花費一些時間,除非你對之前的推導已經非常熟悉了。
問題
- 卷積網絡中的 Backpropagation:在全連接網絡中的 BP 核心公式是 (BP1)-(BP4) (link)。那么在卷積網絡中,這些公式將如何修改呢?
文/Not_GOD(簡書作者)
原文鏈接:http://www.jianshu.com/p/3716fa796677
總結
以上是生活随笔為你收集整理的第六章 深度学习(上)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第五章 深度神经网络为何很难训练
- 下一篇: 第六章 深度学习(上中)