1. 程式人生 > >Deep Learning-TensorFlow (8) CNN卷積神經網路_《TensorFlow實戰》及經典網路模型(上)

Deep Learning-TensorFlow (8) CNN卷積神經網路_《TensorFlow實戰》及經典網路模型(上)

環境:Win8.1 TensorFlow1.0.1

軟體:Anaconda3 (整合Python3及開發環境)

TensorFlow安裝:pip install tensorflow (CPU版) pip install tensorflow-gpu (GPU版)

轉載:

1. 《TensorFlow實戰》,黃文堅

1. 前言

在上一篇博文中,我們介紹了鄭澤宇(才雲科技)的《Tensorflow:實戰Google深度學習框架》的前四章內容,瞭解的 TensorFlow 框架下深度學習的基本構成。後六章的內容如下:

  • 第五章利用之前介紹的優化(啟用去線性、多隱藏層、指數衰減學習率、正則化、滑動平均模型)建立 MNIST 資料上的 DNN 網路,和實現過程中使用變數作用域和共享變數增加程式可讀性,以及 Model 的 Save 和 Restore ;
  • 第六章介紹影象識別問題及 ImageNet 的 ILSVRC 賽事,講述了 CNN 的網路結構組成——卷積層和池化層,建立了 LeNet-5 模型處理 MNIST 問題,以及如何利用已經訓練好的模型遷移到新問題上;
  • 第七章介紹 TensorFlow 對於資料輸入、資料預處理、多執行緒處理的 API;
  • 第八章第九章分別介紹了 RNN+LSTM 和 TensorBoard;
  • 第十章介紹了 TensorFlow 上的多 GPU 和分散式訓練。

總的來說,較為完整地介紹了使用 TensorFlow 建立深度學習模型需要具備的基礎知識。如果要進一步研究和開發,還需要對經典的網路模型進行探究,這部分內容是此書預設的。

目前在售的另一本 TensorFlow 書籍,由黃文堅所寫的《TensorFlow實戰》第6章講解了關於四大經典 CNN 網路:AlexNetVGGNetGoogle Inception Net 和 ResNet 的基本原理。本文主要節選自作者《TensorFlow實戰》第6章,關於這四大 CNN 網路實現方式可參考《TensorFlow實戰》,其中有這幾種網路的詳細實現步驟。

2. 簡介

四種經典的卷積神經網路,它們分別是:

Name Rank Top-5 Lays Institution
AlexNet ILSVRC 2012年冠軍 16.4% 8層 Toronto Hinton
VGGNet ILSVRC 2014年亞軍 7.3% 19層 Oxford (Visual Geometry Group) and Deepmind
Google Inception Net ILSVRC 2014年冠軍 6.7% 22層 Google
ResNet ILSVRC 2015年冠軍 3.57% 152層 Microsoft

這4個經典的網路都在各自的年代率先使用了很多先進的卷積神經網路結構,對卷積網路乃至深度學習有非常大的推動作用,也象徵了卷積神經網路在2012—2015這四年間的快速發展。如上表所示,ILSVRC 的 top-5 錯誤率在最近幾年取得重大突破,而主要的突破點都是在深度學習和卷積神經網路,成績的大幅提升幾乎都伴隨著卷積神經網路的層數加深。

而傳統機器學習演算法目前在 ILSVRC 上已經難以追上深度學習的步伐了,以至於逐漸被稱為淺層學習(Shallow Learning)。目前在 ImageNet 資料集上人眼能達到的錯誤率大概在5.1%,這還是經過了大量訓練的專家能達到的成績,一般人要區分1000種類型的圖片是比較困難的。而 ILSVRC 2015年冠軍——152層 ResNet 的成績達到錯誤率3.57%,已經超過了人眼,這說明卷積神經網路已經基本解決了 ImageNe t資料集上的圖片分類問題。


前面提到的計算機視覺比賽 ILSVRC 使用的資料都來自 ImageNet,如下圖所示。ImageNet 專案於2007年由斯坦福大學華人教授李飛飛創辦,目標是收集大量帶有標註資訊的圖片資料供計算機視覺模型訓練。ImageNet 擁有1500萬張標註過的高清圖片,總共擁有22000類,其中約有100萬張標註了圖片中主要物體的定位邊框。ImageNet 專案最早的靈感來自於人類通過視覺學習世界的方式,如果假定兒童的眼睛是生物照相機,他們平均每200ms就拍照一次(眼球轉動一次的平均時間),那麼3歲大時孩子就已經看過了上億張真實世界的照片,可以算得上是一個非常大的資料集。ImageNet 專案下載了網際網路上近10億張圖片,使用亞馬遜的土耳其機器人平臺實現眾包的標註過程,有來自世界上167個國家的近5萬名工作者幫忙一起篩選、標註。


每年度的 ILSVRC 比賽資料集中大概擁有120萬張圖片,以及1000類的標註,是 ImageNet 全部資料的一個子集。比賽一般採用 top-5 和 top-1 分類錯誤率作為模型效能的評測指標。

3. AlexNet

2012年,Hinton 的學生 Alex Krizhevsky 提出了深度卷積神經網路模型 AlexNet,它可以算是 LeNet 的一種更深更寬的版本。AlexNet 中包含了幾個比較新的技術點,也首次在 CNN 中成功應用了 ReLU、Dropout 和 LRN 等Trick。同時 AlexNet 也使用了 GPU 進行運算加速,作者開源了他們在 GPU上 訓練卷積神經網路的 CUDA 程式碼。

AlexNet 包含了6億3000萬個連線,6000萬個引數和65萬個神經元,擁有5個卷積層,其中3個卷積層後面連線了最大池化層,最後還有3個全連線層。AlexNet 以顯著的優勢贏得了競爭激烈的 ILSVRC 2012比賽,top-5 的錯誤率降低至了16.4%,相比第二名的成績26.2%錯誤率有了巨大的提升。AlexNet 可以說是神經網路在低谷期後的第一次發聲,確立了深度學習(深度卷積網路)在計算機視覺的統治地位,同時也推動了深度學習在語音識別、自然語言處理、強化學習等領域的拓展。

AlexNet 將 LeNet 的思想發揚光大,把 CNN 的基本原理應用到了很深很寬的網路中。AlexNet 主要使用到的新技術點如下:

  • 成功使用 ReLU 作為 CNN 的啟用函式,並驗證其效果在較深的網路超過了 Sigmoid,成功解決了 Sigmoid 在網路較深時的梯度彌散問題。雖然 ReLU 啟用函式在很久之前就被提出了,但是直到 AlexNet 的出現才將其發揚光大。
  • 訓練時使用 Dropout 隨機忽略一部分神經元,以避免模型過擬合。Dropout 雖有單獨的論文論述,但是 AlexNet 將其實用化,通過實踐證實了它的效果。在 AlexNet 中主要是最後幾個全連線層使用了 Dropout。
  • 在 CNN 中使用重疊的最大池化。此前 CNN 中普遍使用平均池化,AlexNet 全部使用最大池化,避免平均池化的模糊化效果。並且 AlexNet 中提出讓步長比池化核的尺寸小,這樣池化層的輸出之間會有重疊和覆蓋,提升了特徵的豐富性。
  • 提出了 LRN 層,對區域性神經元的活動建立競爭機制,使得其中響應比較大的值變得相對更大,並抑制其他反饋較小的神經元,增強了模型的泛化能力。
  • 使用 CUDA 加速深度卷積網路的訓練,利用 GPU 強大的平行計算能力,處理神經網路訓練時大量的矩陣運算。AlexNet 使用了兩塊 GTX 580 GPU 進行訓練,單個 GTX 580只有3GB視訊記憶體,這限制了可訓練的網路的最大規模。因此作者將 AlexNet 分佈在兩個 GPU 上,在每個 GPU 的視訊記憶體中儲存一半的神經元的引數。因為 GPU 之間通訊方便,可以互相訪問視訊記憶體,而不需要通過主機記憶體,所以同時使用多塊 GPU 也是非常高效的。同時,AlexNet 的設計讓 GPU 之間的通訊只在網路的某些層進行,控制了通訊的效能損耗。
  • 資料增強,隨機地從256´256的原始影象中擷取224´224大小的區域(以及水平翻轉的映象),相當於增加了(256-224)2´2=2048倍的資料量。如果沒有資料增強,僅靠原始的資料量,引數眾多的 CNN 會陷入過擬閤中,使用了資料增強後可以大大減輕過擬合,提升泛化能力。進行預測時,則是取圖片的四個角加中間共5個位置,並進行左右翻轉,一共獲得10張圖片,對他們進行預測並對10次結果求均值。同時,AlexNet 論文中提到了會對影象的 RGB 資料進行 PCA 處理,並對主成分做一個標準差為0.1的高斯擾動,增加一些噪聲,這個 Trick 可以讓錯誤率再下降1%。

4. VGGNet

VGGNet 是牛津大學計算機視覺組(Visual Geometry Group)Google DeepMind 公司的研究員一起研發的的深度卷積神經網路。

VGGNet 探索了卷積神經網路的深度與其效能之間的關係,通過反覆堆疊3´3的小型卷積核2´2的最大池化層,VGGNet成功地構築了16~19層深的卷積神經網路。VGGNet 相比之前 state-of-the-art 的網路結構,錯誤率大幅下降,並取得了 ILSVRC 2014 比賽分類專案的第2名和定位專案的第1名。同時 VGGNet 的拓展性很強,遷移到其他圖片資料上的泛化性非常好。VGGNet 的結構非常簡潔,整個網路都使用了同樣大小的卷積核尺寸(3´3)和最大池化尺寸(2´2)。

到目前為止,VGGNet 依然經常被用來提取影象特徵(!!!)。VGGNet訓練後的模型引數在其官方網站上開源了,可用來在 domain specific 的影象分類任務上進行再訓練(相當於提供了非常好的初始化權重),因此被用在了很多地方。

VGGNet 論文中全部使用了3´3的卷積核和2´2的池化核,通過不斷加深網路結構來提升效能。下圖所示為 VGGNet 各級別的網路結構圖,以及隨後的每一級別的引數量,從11層的網路一直到19層的網路都有詳盡的效能測試。雖然從A到E每一級網路逐漸變深,但是網路的引數量並沒有增長很多,這是因為引數量主要都消耗在最後3個全連線層。前面的卷積部分雖然很深,但是消耗的引數量不大,不過訓練比較耗時的部分依然是卷積,因其計算量比較大。這其中的D、E也就是我們常說的VGGNet-16VGGNet-19。C很有意思,相比B多了幾個1´1的卷積層,1´1卷積的意義主要在於線性變換,而輸入通道數和輸出通道數不變,沒有發生降維



VGGNet 擁有5段卷積,每一段內有2~3個卷積層,同時每段尾部會連線一個最大池化層用來縮小圖片尺寸。每段內的卷積核數量一樣,越靠後的段的卷積核數量越多:64 – 128 – 256 – 512 – 512。其中經常出現多個完全一樣的3´3的卷積層堆疊在一起的情況,這其實是非常有用的設計。如下圖所示,兩個3´3的卷積層串聯相當於1個5´5的卷積層,即一個畫素會跟周圍5´5的畫素產生關聯,可以說感受野大小為5´5。而3個3´3的卷積層串聯的效果則相當於1個7´7的卷積層。除此之外,3個串聯的3´3的卷積層,擁有比1個7´7的卷積層更少的引數量,只有後者的一半。最重要的是,3個3´3的卷積層擁有比1個7´7的卷積層更多的非線性變換(前者可以使用三次ReLU啟用函式,而後者只有一次),使得CNN對特徵的學習能力更強。


兩個串聯3´3的卷積層功能類似於一個5´5的卷積層

VGGNet 在訓練時有一個小技巧,先訓練級別A的簡單網路,再複用A網路的權重來初始化後面的幾個複雜模型,這樣訓練收斂的速度更快。在預測時,VGG 採用 Multi-Scale 的方法,將影象 scale 到一個尺寸 Q,並將圖片輸入卷積網路計算。然後在最後一個卷積層使用滑窗的方式進行分類預測,將不同視窗的分類結果平均,再將不同尺寸 Q的結果平均得到最後結果,這樣可提高圖片資料的利用率並提升預測準確率。同時在訓練中,VGGNet 還使用了 Multi-Scale 的方法做資料增強,將原始影象縮放到不同尺寸S,然後再隨機裁切224´224的圖片,這樣能增加很多資料量,對於防止模型過擬合有很不錯的效果。實踐中,作者令S在[256,512]這個區間內取值,使用 Multi-Scale 獲得多個版本的資料,並將多個版本的資料合在一起進行訓練。下圖為 VGGNet 使用 Multi-Scale 訓練時得到的結果,可以看到D和E都可以達到7.5%的錯誤率。最終提交到 ILSVRC 2014 的版本是僅使用 Single-Scale 的6個不同等級的網路與 Multi-Scale 的D網路的融合,達到了7.3%的錯誤率。不過比賽結束後作者發現只融合 Multi-Scale 的D和E可以達到更好的效果,錯誤率達到7.0%,再使用其他優化策略最終錯誤率可達到6.8%左右,非常接近同年的冠軍 Google Inceptin Net。


5. InceptionNet V1

Google Inception Net 首次出現在 ILSVRC 2014 的比賽中(和 VGGNet 同年),就以較大優勢取得了第一名。那屆比賽中的 Inception Net 通常被稱為 Inception V1,它最大的特點是控制了計算量和引數量的同時,獲得了非常好的分類效能—— top-5 錯誤率6.67%,只有 AlexNet 的一半不到。Inception V1 有22層深,比 AlexNet 的8層或者 VGGNet 的19層還要更深。但其計算量只有15億次浮點運算,同時只有500萬的引數量,僅為AlexNet引數量(6000萬)的1/12,卻可以達到遠勝於AlexNet的準確率,可以說是非常優秀並且非常實用的模型。

Inception V1 降低引數量的目的有兩點:

第一,引數越多模型越龐大,需要供模型學習的資料量就越大,而目前高質量的資料非常昂貴;

第二,引數越多,耗費的計算資源也會更大。

Inception V1 引數少但效果好的原因除了模型層數更深、表達能力更強外,還有兩點:

一是去除了最後的全連線層,用全域性平均池化層(即將圖片尺寸變為1´1)來取代它。全連線層幾乎佔據了 AlexNet 或 VGGNet 中90%的引數量,而且會引起過擬合,去除全連線層後模型訓練更快並且減輕了過擬合。用全域性平均池化層取代全連線層的做法借鑑了 Network In Network(以下簡稱 NIN )論文。


Network In Network

二是Inception V1中精心設計的 Inception Module 提高了引數的利用效率,其結構如下圖所示。這一部分也借鑑了 NIN 的思想,形象的解釋就是 Inception Module 本身如同大網路中的一個小網路,其結構可以反覆堆疊在一起形成大網路。不過 Inception V1 比 NIN 更進一步的是增加了分支網路,NIN 則主要是級聯的卷積層和MLPConv 層,如上圖。一般來說卷積層要提升表達能力,主要依靠增加輸出通道數,但副作用是計算量增大和過擬合。每一個輸出通道對應一個濾波器,同一個濾波器共享引數,只能提取一類特徵,因此一個輸出通道只能做一種特徵處理。而 NIN 中的 MLPConv 則擁有更強大的能力,允許在輸出通道之間組合資訊,因此效果明顯。可以說,MLPConv 基本等效於普通卷積層後再連線1´1的卷積和ReLU啟用函式,最後一層的每一個 Feature Map 做全域性平均池化得到 Softmax 的一個向量值。

Inception Module


我們再來看 Inception Module 的基本結構,其中有4個分支:第一個分支對輸入進行1´1的卷積,這其實也是 NIN 中提出的一個重要結構。1´1的卷積是一個非常優秀的結構,它可以跨通道組織資訊,提高網路的表達能力,同時可以對輸出通道升維和降維。可以看到 Inception Module 的4個分支都用到了1´1卷積,來進行低成本(計算量比3´3小很多)的跨通道的特徵變換。第二個分支先使用了1´1卷積,然後連線3´3卷積,相當於進行了兩次特徵變換。第三個分支類似,先是1´1的卷積,然後連線5´5卷積。最後一個分支則是3´3最大池化後直接使用1´1卷積。我們可以發現,有的分支只使用1´1卷積,有的分支使用了其他尺寸的卷積時也會再使用1´1卷積,這是因為1´1卷積的價效比很高,用很小的計算量就能增加一層特徵變換和非線性化。Inception Module 的4個分支在最後通過一個聚合操作合併(在輸出通道數這個維度上聚合,在 TensorFlow 中使用tf.concat(3, [], []) 函式可以實現矩陣合併)Inception Module 中包含了3種不同尺寸的卷積和1個最大池化,增加了網路對不同尺度的適應性,這一部分和 Multi-Scale 的思想類似。早期計算機視覺的研究中,受靈長類神經視覺系統的啟發,Serre 使用不同尺寸的 Gabor 濾波器處理不同尺寸的圖片,Inception V1 借鑑了這種思想。Inception V1 的論文中指出,Inception Module 可以讓網路的深度和寬度高效率地擴充,提升準確率且不致於過擬合。

人腦神經元的連線是稀疏的,因此研究者認為大型神經網路的合理的連線方式應該也是稀疏的。稀疏結構是非常適合神經網路的一種結構,尤其是對非常大型、非常深的神經網路,可以減輕過擬合併降低計算量,例如卷積神經網路就是稀疏的連線。Inception Net 的主要目標就是找到最優的稀疏結構單元(即 Inception Module ),論文中提到其稀疏結構基於 Hebbian 原理,這裡簡單解釋一下 Hebbian 原理:

神經反射活動的持續與重複會導致神經元連線穩定性的持久提升,當兩個神經元細胞A和B距離很近,並且A參與了對B重複、持續的興奮,那麼某些代謝變化會導致A將作為能使B興奮的細胞。

總結一下即“一起發射的神經元會連在一起”(Cells that fire together, wire together),學習過程中的刺激會使神經元間的突觸強度增加。受 Hebbian 原理啟發,另一篇文章 Provable Bounds for Learning Some Deep Representations 提出,如果資料集的概率分佈可以被一個很大很稀疏的神經網路所表達,那麼構築這個網路的最佳方法是逐層構築網路:將上一層高度相關(correlated)的節點聚類,並將聚類出來的每一個小簇(cluster)連線到一起。這個相關性高的節點應該被連線在一起的結論,即是從神經網路的角度對 Hebbian 原理有效性的證明。

在 Inception Module 中,通常1´1卷積的比例(輸出通道數佔比)最高,3´3卷積和5´5卷積稍低。而在整個網路中,會有多個堆疊的 Inception Module,我們希望靠後的Inception Module 可以捕捉更高階的抽象特徵,因此靠後的 Inception Module 的卷積的空間集中度應該逐漸降低,這樣可以捕獲更大面積的特徵。因此,越靠後的Inception Module中,3´3和5´5這兩個大面積的卷積核的佔比(輸出通道數)應該更多。

Inception Net 有22層深,除了最後一層的輸出,其中間節點的分類效果也很好。因此在 Inception Net 中,還使用到了輔助分類節點(auxiliary classifiers),即將中間某一層的輸出用作分類,並按一個較小的權重(0.3)加到最終分類結果中。這樣相當於做了模型融合,同時給網路增加了反向傳播的梯度訊號,也提供了額外的正則化,對於整個Inception Net 的訓練很有裨益。

當年的 Inception V1 還是跑在 TensorFlow 的前輩 DistBelief 上的,並且只執行在 CPU 上。當時使用了非同步的 SGD 訓練,學習速率每迭代8個 epoch 降低4%。同時, Inception V1 也使用了 Multi-Scale、Multi-Crop 等資料增強方法,並在不同的取樣資料上訓練了7個模型進行融合,得到了最後的 ILSVRC 2014 的比賽成績—— top-5 錯誤率6.67%