獨家 | 一文帶你上手卷積神經網路實戰(附數據集&學習資料)

深度學習是目前最熱門的人工智慧話題之一。它是部分基於生物學解釋的演算法合集,在計算機視覺、自然語言處理、語音識別等多個領域均展現了令人驚嘆的成果。

在過去的五年中,深度學習已經拓展到很多工業領域。

最近很多科技性突破都得歸功於深度學習,例如特斯拉無人駕駛汽車、Facebook照片標記系統、Siri和Cortana等虛擬助手、聊天機器人和物體識別照相機。在語言理解圖像分析的認知領域,深度學習已經達到人類水平。

下面一個例子很好的說明了深度學習演算法能做到什麼:自動識別和標記場景里的不同物體。

深度學習都已經成了媒體上老生常談的話題了。

我會在本文中跳過那些主流媒體的炒作內容並向你展現深度學習的實際應用案例。

我將告訴你如何搭建一個在圖片識別分類上達到90%準確度的深度神經網路。在深度網路尤其是卷積神經網路(CNN)出現之前,這個看似簡單的問題已經困擾計算機科學家很多年了。

本文分為四個部分:

1.呈現數據集和應用案例,解釋圖片分類的複雜性

2.詳細說明卷積神經網路。分析其內在機制,並闡述其在圖片分類方面相對普通神經網路的優越性。

3.基於AWS擁有強大GPU的EC2實例,搭建深度學習專門環境

4.訓練兩個深度學習模型:一個是從零開始在端對端管道中使用Keras和Tensorflow,另一個是使用大型數據集上的預訓練網路。

這些部分互相獨立。如果你對理論不感興趣,可以跳過第一部分和第二部分。

深度學習是個很有挑戰性的話題。作為一名機器學習實踐者,我花了很長時間去了解這個學科。我會在本文結尾分享以前看過的學習資料,這樣你們也可以自學並開始你們的深度學習之旅。

本文是一次整合我在神經網路領域所有知識的嘗試。閱讀時若發現不當之處,請及時指出。若有不明白之處和新想法,歡迎和我討論。

本文的代碼和訓練模型都在我的Github賬戶里(github.com/ahmedbesbes/

Understanding-deep-Convolutional-Neural-Networks-with-a-practical-use-case-in-Tensorflow-and-Keras),歡迎大家來查看和修改。

那就開始吧。

1.一個有趣的例子:如何區分貓和狗?

有很多圖片集專門用來基準測試深度學習模型。本文選擇的圖片集是「Kaggle貓狗大戰」(kaggle.com/c/dogs-vs-ca)。通過名字你也能猜到,這是一個貓狗標記圖片集。

像其他的Kaggle比賽一樣,我們會有兩個文件夾:

  • 訓練數據文件夾:包含了25,000張貓和狗的圖片。每張圖片都在其文件名中有標記。我們會用它來訓練和驗證我們的模型。
  • 測試數據文件夾:包含了12,500張圖片,根據數值ID來命名。對於數據集中的每一張照片,都要預測該圖片中動物是狗的概率(1表示是狗,0表示是貓)。實際操作中,它被用來在Kaggle的排行榜上給模型打分。

你可以看到,我們有很多圖片,解析度、拍攝角度和焦距各不相同。所有貓狗的形態、位置和顏色互相迥異,或坐著,或站著,或開心,或難過,或睡覺,或吠叫。

特徵可以是無窮無盡的。但人類可以不費力氣的在一堆不同的照片里識別場景里的寵物。然而這對於機器來說並不簡單。自動分類需要知道如何強有力地描述出貓和狗各自的特徵。需要知道能夠描述每隻動物的本質特徵。

深度神經網路在圖片分類上非常有效是因為它在分類任務中多層提取類別特徵的能力,並能抵抗失真和簡單幾何變形。

那深度神經網路是如何做到的?

2.全連接網路vs卷積神經網路

很多人一開始會選擇全連接網路來解決圖片分類問題。然而逐漸地他們發現這種網路並不是完成任

務的最好方法。

我們來分析下為何會這樣。

2.1一個全連接(FC)神經網路

全連接神經網路是一種相鄰層之間每個神經元都彼此連接的網路。它是標準的傳統神經網路架構。若想了解神經網路背後更多的原理,請參考Andrej Karpathy在斯坦福大學非常棒的講義(cs231n.github.io/neuralcs231n.github.io/neural)。

為了便於闡述,下面是一個三層隱藏層全連接神經網路。

使用全連接網路,圖片會首先轉成一維矢量,然後作為輸入量輸入網路。

例如,一張256x256的彩色照片,內容是一個(255, 255, 3)的物體,3是指顏色通道數目,轉成一個256 x 256 x 3 = 196608的矢量。我們做的是把圖片轉成了長矢量,矢量的每個元素都是像素值。

使用全連接網路分析一系列256x256的彩色照片,我們可以得到:

  • 一層尺寸為196608的輸入層,其中每個神經元都編碼了一個像素值
  • 一層尺寸為2的輸出層,每個神經元都顯示著輸出類別預估情況
  • 隱藏層和其中的隱藏神經元

全連接網路是很好的分類工具。在監督演算法領域,它可以學習複雜非線性圖案,總結能力很強,當然前提是架構穩定,沒有數據過度擬合。

對於處理圖片,全連接網路就不是最合適的工具了。

主要有兩點原因:

1. 我們來假設一個有1000個隱藏單元的隱藏層,考慮到輸入層尺寸,1000是一個合理值。在這種情況下,連接輸入層和第一隱藏層的參數數目達到196608 x 1000 = 196608000!不僅僅是數目太大的問題,由於神經網路一般需要不止一個隱藏層來確保穩固,所以網路不可能運作很好。說實在的,網路能夠擁有這樣的隱藏層和1000個隱藏單元,真的非常不錯了。但是我們來計算下存儲成本。一個參數是8位元組的浮動值,196698000個參數就是1572864000個位元組,大約1,572 GB。因此我們需要1,572 GB來存儲僅第一隱藏層的參數。除非你電腦的RAM非常大,不然這個方案很明顯不可拓展。

2. 使用全連接網路,我們會丟失圖片本有的空間結構信息。事實上,把圖片轉成長矢量之後,每個像素值的處理方式都很相似。無法找到像素之間的空間關聯。每個像素都扮演同樣的角色。我們丟失了相近像素間的關聯性和相似性,這是很嚴重的信息損失。這些信息我們都希望能夠編碼到模型中的。

為了克服這兩個局限,很多工作都投入到創造既能拓展,又適合處理圖片數據的複雜性的新型神經網路架構中。。

於是我們創造了了卷積神經網路(CNN)

2.2卷積神經網路

卷積神經網路是種特殊的神經架構,專門用來處理圖片數據。自1989年被LeCun et al引進後,卷積神經網路已經在手寫數字分類和面部識別等方面表現優秀。在過去的幾年中,好幾篇論文都表明了它在更有挑戰性的視覺分類中也有不俗表現。最有名的要屬Krizhevsky在2012年ImageNet的分類測試中破紀錄的表現,他的卷積神經網路模型AlexNet的錯誤率只有16.4%,而第二名的錯誤率是26.1%。

卷積神經網路不只是媒體炒作,多方面因素能解釋為何這麼多人會對它感興趣。

1.開放的大型訓練數據集,數以百萬計的標籤例子。最有名的資料庫之一就是ImageNet。

2.強大的GPU性能,使得大型模型訓練切實可行。

3.提升的模型規則化策略,如Dropout(youtube.com/watch?

AM8cnI)。

卷積神經網路在圖片分類中作用非常強大,專門用於解決之前所說的全連接網路面臨的兩大局限。

卷積神經網路有自己的架構和屬性。雖然和標準的全連接網路看起來不同,但是兩者的機制是一樣的。我們會談到隱藏層、weight(權重)、biase(偏置)、隱藏層神經元、損失函數、反向傳播演算法和隨機梯度下降。如果你對這些概念不是很懂,希望你可以看看Andrej Karpathy關於神經網路的講解。

卷積神經網路由五個基本部分組成,理解他們會讓你對整體機制有直觀的理解。

1.輸入層

2.卷積層

3.激活函數層

4.池化層

5.全連接層

了解每個部分之前,先看看卷積神經網路的架構。

正如你所見,圖片在網路中會經過多層處理,輸出神經元包含每類的預期值。

我們來詳細介紹每一層的原理。

  • 輸入層

在全連接網路中,輸入量是被描述為一列神經元的向量。不管我們是否處理圖片,我們都得調整數據來轉換成這樣。

而在卷積神經網路中,圖片被看作許多小方格或者神經元,每個神經元代表一個像素值。卷積神經網路能基本上讓圖片保真,而不必去壓縮成矢量。

下面的圖表展示了差異:

  • 卷積層

卷積層是卷積神經網路中最主要的部分。在解釋它的功能前,我們得先理解卷積神經網路和全連接網路在連接方面的差異。這一點非常重要。我來闡述下:

前文提到說全連接網路是真的「全部連接了」。意思是指每層隱藏層的每個神經元都和相鄰隱藏層的所有神經元相連接。當一個多維數據點從一個隱藏層流向另一個隱藏層,隱藏層的每個神經元激活狀態都是由上一層所有神經元的權重所決定的。

然而卷積神經網路情況大不相同。它不是全連接的。

也就是說,隱藏層的每個神經元並不是和上一個隱藏層所有的神經元都相連,而只是和上一個隱藏層某一小片相連。

下面是一個例子:

在該圖中,第一層隱藏層的第一個神經元和輸入層3x3像素區相連接。輸入層到隱藏層的這種映射叫做特徵映射(Feature map)。這個隱藏層神經元只依賴於3x3這一小片區域,也最終會通過學習來捕獲這片區域的特徵。

第一個隱藏層的神經元的數值代表了什麼呢?灰色區域對應一個權重矩陣,稱作卷積核(kernal),圖片中相同尺寸相同區域稱作局部感知域(receptive field),兩者間卷積的結果就是第一個隱藏層神經元的數值了。

背後的操作非常簡單,就是兩個矩陣之間的元素相乘,再相加形成一個輸出值。上述例子中,我們將9個相乘值相加就得到了第一個隱藏元的數值了。

該神經元從局部感知域學習到視覺圖形。你可以把它的值看作是代表圖片中某個特徵屬性的強度。

那麼其他隱藏層的神經元又是怎麼計算的呢?

為了計算第二隱藏層的神經元,卷積核會在輸入圖片上從坐到右移動一個單元(stride=1),用同樣的過濾器來做卷積。看下圖:

現在,我們可以想像卷積核移遍整個圖片,每一步都做卷積,並將輸出值存入特徵映射。

這就是卷積層的作用:給定一個過濾器,卷積層會掃描輸入層來闡述一個特徵映射。

但是卷積操作到底代表著什麼?如何理解最後形成的特徵映射?

我一開始說卷積層能捕捉到圖片里的視覺圖形。那麼我現在來證明下。

我會從數據集中下載一張貓的圖片,然後變換卷積核來做多次卷積,並將結果視覺化。

我會定義一個函數,將卷積核作為輸入量,對圖片進行卷積,然後繪製原始圖片和卷積後圖片。

卷積核是一個小型矩陣(上文中的灰色方塊)

我們先試試下面的過濾器:

這叫做方框濾波(box blur)。 當該過濾器應用到輸入圖片中某個像素值上,它會截取該像素和其周圍8個像素,並計算它們的平均像素值。數學上,這只是一個簡單的平均演算法。而視覺上,它能弱化圖片轉化的差異。

方框濾波被廣泛應用於噪音去除

我們來把方框濾波應用到一張貓的圖片上,看看效果如何。

如果你仔細查看卷積後的圖片,會發現它更加平滑,上面的白色像素點更少(噪音)。

現在來試試更進一步的方框濾波。

某些過濾器專門用來捕獲圖片的一些細節,像邊緣。

下面這個例子在計算圖片A中豎直方向變化的近似值。

白色部分更好的回應了過濾器,顯示了豎直邊緣的存在。請仔細看貓左耳的邊緣是怎麼被捕獲的。

很酷吧!下面的例子是同樣的操作,只是方向換成了水平方向。

請仔細看貓鬍鬚信息是怎麼被捕獲的。

前面這兩種過濾器是梯度算符。某種程度上,它們能夠展示某個方向上圖片的內在結構。

然而,當G_x和G_y用如下公式合併後:

會有更好的邊緣捕獲效果。

這叫做索貝爾運算元,是兩種簡單卷積的非線性組合。之後我們會看到卷積層能夠非線性整合多個特徵映射,從而實現這樣的邊緣檢測。

還有很多先進的過濾器,更多信息請看維基百科上的說明(en.wikipedia.org/wiki/K(image_

processing))。

我們現在已經理解了卷積層在卷積神經網路中的作用了,就是產生一個卷積後的值來對應輸入量中的視覺元素。輸出值可能尺寸變小,因此你可以把它當作是關於某個特徵輸入量的縮小版。

卷積核決定了卷積是在尋找哪種特徵。它起到特徵檢測器的功能。我們可以想到很多過濾器來檢測

邊緣、半圓和角落等。

卷積層不止一個過濾器?

在經典的卷積神經網路架構中,每一層卷積層一般不止一個過濾器。有時,是10個,16個或32個,有時,甚至更多。這種情況下,我們在每一卷積層做的卷積次數等同於過濾器數目。思路就是製造不同的特徵映射,每個特徵映射定點陣圖片中某個特定特徵。我們有越多的過濾器,我們就能提取越多的本質細節。

記住,我們現在提取的這些簡單特徵之後會在網路中合併起來來檢測更複雜的圖案。

那我們該如何選擇過濾器權重了?

我們並不基於已有數據集主流知識來計算過濾器權重。

實際上,當訓練卷積神經網路時,我們並不會人工設置過濾器權重。這些值都是網路自動習得的。你還記得在經典全連接網路中權重是如何通過反向傳播演算法習得的么?是的,卷積神經網路也是同樣的原理。

不是我們來給每層設置大型權重矩陣,而是卷積神經網路習得過濾器權重。換言之,當我們從隨機值來調整權重來降低分類錯誤時,網路會找出正確的過濾器,適用於尋找我們感興趣的物體的特徵。這是個影響力巨大的思路,顛覆了整個過程。

我發覺卷積神經網路既富有感染力,又很神秘。下面是首次卷積神經網路習得的三個特徵映射,即有名的AlexNet。

注意從簡單邊緣提取特徵形成更奇怪的形狀有多複雜。

權重共享?

特徵映射是僅由一個過濾器來產生的。所有隱藏層神經元共享同樣的權重,因為是同一個過濾器在生成所有的神經元數值。這就是權重共享。這種屬性大量減少習得參數數目,從而提升卷積神經網路訓練速度。

除了為提升訓練速度,共享權重概念的提出也是出於一個事實,即同一個視覺圖案會在圖片的不同區域多次出現,因此在整個圖片中用同一個過濾器來檢測就很合理了。

  • 激活函數層

一旦特徵映射從卷積層提取後,下一步就是把它們移動到激活函數層。激活函數層一般是和卷積層綁定在一起,共同運作。

激活函數層會對特徵映射使用激活函數,使得所有的負值都是0.該操作的輸出被稱作修訂特徵映射。

激活函數有兩個主要優點:

  • 它們給網路引入了非線性。實際上,目前提到的運算都是線性的,像卷積、矩陣相乘和求和。如果我們沒有非線性,那麼最終我們會得到一個線性模型,不能完成分類任務。
  • 它們通過防止出現梯度消失來提升訓練進程。

下面是函數激活層如果影響圖片的視覺化展示。

  • 池化層

修訂特徵映射現在來到池化層了。池化是一個下採樣操作,能讓特徵映射降維。

最普通的池化操作是Max-pooling。它選取一個小窗口,一般是2x2 ,以stride(步幅)為2在修訂特徵映射上滑動,每一步都取最大值。

例如一個10x10的修訂特徵映射會轉變成一個5x5的輸出。

Max-pooling有很多優點:

  • 減小了特徵映射的尺寸,減少了訓練參數數目,從而控制過度擬合。
  • 獲取最重要特徵來壓縮特徵映射。
  • 對於輸入圖片的變形、失真和平移具有網路不變性,輸入小的失真不會改變池化的輸出,因為我們是取最大值。

Max-pooling還不是特別直觀。根據我的理解,我總結如下:

如果檢測到一個特徵,例如邊緣,以上面例子中2x2紅色方塊為例,我們並不在乎具體是哪些像素使得特徵顯示出來。相反,我們只提取最大值,並假設它代表了視覺特徵。這個方法看起來很大膽,因為很多空間信息都被捨棄了。但事實上,它相當有效,實踐操作中表現不錯。當然,你不用在意這個4x4圖片的例子。因為max-pooling在被應用到相對高解析度的圖片上時,主要空間信息仍然被保留了,只有不重要的細節被捨棄了。這也是為什麼max-pooling能夠防止過度擬合。它使得網路聚焦於圖片最相關的信息上面。

  • 全連接層

卷積神經網路也有一層全連接層,就是我們在經典全連接網路中看到的那種。它一般在網路的末尾,最後一層池化層已經扁平化為一個矢量,和輸出層全連接。而輸出層是預測矢量,尺寸和類別數目相同。

如果你對整個框架還有印象,即輸入->卷積->函數激活->Max pooling,那麼最後給輸出添加一個全連接層。你會得到一個完整的小型卷積神經網路,把基本部分都整合在一起。

大概是這樣的:

注意,這裡扁平化層就是之前的池化層矢量化的結果。

我們為何需要全連接層?

全連接層起著分類的作用,而前面那些層都是在提取特徵

全連接層收到卷積、修訂和池化的壓縮產物後,整合它們來實施分類。

除為了分類,添加一層全連接層也是一種學習這些特徵非線性組合的方法。從卷積層和池化層來的大部分特徵可能已經能夠完成分類,但是整合這些特徵後效果會更好。

把全連接層看作是添加到網路的一種附加提取。

總結

我們來總結下目前提到的層。

功能

輸入層

輸入圖片,保存空間結構信息

卷積層

從輸入提取特徵映射,對應一個特定圖案

函數激活層

將像素負值設置為0,給網路引入非線性

Max-pooling層

下採樣修訂特徵映射,降維和保留重要特徵,防止過度擬合。

全連接層

學習特徵非線性組合,實施分類

在一個經典全連接架構中,每種類型不會只有一種。實際上,如果你考慮有兩個連續的卷積-池化層的網路,就會知道第二個卷積是在獲得圖片的壓縮版,而圖片包含了某一個特徵的情況。因此,你可以把第二層卷積層當作原始輸入圖片的抽象壓縮版,依然保留著很多空間結構信息。

我們一般會設置2到3個全連接層,這樣在實施分類前就可以學習非線性特徵組合。

關於這點可以引用Andrej Karpathy的話:

最普通的卷積神經網路架構形式是包含好幾層卷積-函數激活層的,池化層緊隨其後,這種結構不斷重複直到圖片已經完全融合成小尺寸。在某個階段,轉化到全連接層也是很正常的事情。最後一層全連接層持有輸出,如類別值。換言之,最普通的卷積神經網路架構允許這樣的形式:

現在我們已經知曉了卷積神經網路的基本部分,就來看看一個經典網路吧。

  • LeNet5

下面是一個非常有名的卷積神經網路,叫LeNet5,由LeCun et al.在1998年設計。

我來解釋下這個網路架構。當然我希望你能先自己試著分析下。

  • 輸入層:一個32x32的灰度圖,一個顏色通道
  • 卷積層n°1:對圖片採用6個5x5過濾器,形成6個28x28的特徵映射,該層的激活函數不是ReLU。
  • 池化層:池化這6個28x28的特徵映射,形成6個14x14池化的特徵映射,尺寸變為1/4。
  • 卷積層n°2:對這6個14x14特徵映射採用16個不同的5x5過濾器,形成16個尺寸為 10x10的特徵映射。每個過濾器和6個輸入卷積,形成6個矩陣,並求和形成一個特徵映射,總共16個特徵映射。
  • 池化層:池化這16個 10x10特徵映射為16個5x5特徵映射。
  • 第一層全連接層:包含120個神經元,每個神經元都連接16個5x5特徵映射的所有像素。這一層有16x5x5x120=48000個學習權重。
  • 第二層全連接層:包含84個神經元,這一層和上一層全連接,有120x84=10080個學習權重。
  • 全連接層:鏈接輸出層,有84x10=840個學習權重。

更先進的卷積神經網路架構

你如果對更複雜更詳細的卷積神經網路架構感興趣,你可以看看這個博客(adeshpande3.github.io/a

You-Need-To-Know-About.html)。

下面是贏得2012 ImageNet比賽的卷積神經網路——AlexNet。

3.搭建深度學習專門環境

深度學習的計算量很龐大。當你準備在你的筆記本電腦上搭建模型時就會發現這點。

然而,使用GPU就可以大幅度加快訓練。因為GPU在如矩陣乘積之類的並行任務中效率非常高。由於神經網路都是關於矩陣乘積,因此使用GPU會大大提升性能。

我的筆記本電腦上沒有強大的GPU,因此我選擇了Amazon Web Services (AWS)上的虛擬機p2.xlarge。p2.xlarge是Amazon EC2(亞馬遜彈性計算雲)實例的一部分,有Nvidia GPU,12GB的視頻存儲,61GB的RAM,4vCPU和2,496 CUDA核。性能非常強大,每小時花費0.9美元。

當然還有更強大的實例,但是對於目前要處理的任務,一個p2.xlarge絕對夠了。

我在Deep Learning AMI CUDA 8 Ubuntu Version上開始實例,更多信息可以參考這個(aws.amazon.com/marketpl)。基本上安裝一個Ubuntu 16.04伺服器,就包含了所有需要的深度學習框架,像Tensorflow, Theano, Caffe, Keras,也包含了聽說安裝異常難的GPU驅動。

AWS給你提供強大的實例和隨時可用的深度學習專門環境,這樣你就能快速開始你的項目了。這太棒了。

如果你對AWS不是很熟悉,可以看看下面兩個帖子。

  • blog.keras.io/running-j
  • hackernoon.com/keras-wi

它們能讓你:

  • 搭建EC2虛擬機,並連接上
  • 設置網路安全屬性來遠程使用jupyter notebook

4.使用Tensorfow和Keras來建造貓狗分類器

環境已經搭建好了。我們可以把目前學到的知識運用到實戰中了,那就是建造一個卷積神經網路來分類貓狗圖片。

我們會使用Tensorflow深度學習框架和Keras

Keras是高等級的神經網路應用程序編程介面(KPI),用Python編寫,能夠在TensorFlow、

CNTK和Theano上運行。它的設計初衷是讓快速實驗成為可能。能夠盡量不拖延把想法變成結果的執行力是做好研究的秘訣。

4.1從零開始建造卷積神經網路

第一部分,我們會搭建端對端管道來訓練卷積神經網路。我們會涉及到數據準備、數據集擴增、架構設計、訓練和驗證。我們會在訓練集和驗證集上實驗測試損失和準確度矩陣。這可以讓我們通過訓練估測模型改善情況。

準備數據

開始建造卷積神經網路前第一件事就是從Kaggle下載和解壓訓練集。

我們得組織下這些數據,從而keras能夠容易的處理它們。

我們會建一個data文件夾,裡面包含兩個子文件夾:

  • train
  • validation

這兩個子文件夾又各自包含兩個文件夾。

  • cats
  • dogs

最終我們有如下的文件夾結構:

這樣的文件夾結構可以讓我們的模型在不管是訓練還是驗證的時候都可以知道從哪個文件夾里提取圖片和標籤。

這有一個函數可以讓你來建文件樹。它有兩個參數:圖片總數n和驗證集比例r。

我的參數是:

  • n : 25000 (整個數據集)
  • r : 0.2

我們來下載Keras和它的dependencies。

圖片生成器和數據擴增

當我們訓練一個模型的時候,不會下載整個數據集放在存儲里。這樣效率非常低,特別是使用你自己的電腦來操作。

我們會使用ImageDataGenerator函數。它能讓你從訓練集和驗證集中無限批量的得到圖片。每一批圖片流過網路,做正向傳播和反向傳播,然後參數隨著驗證數據的測試而更新。接著下一批圖片會有同樣的操作。

在ImageDataGenerator object(目標)中我們會給每批圖片做隨機修改。這個過程叫做數據擴增(data augmentation)。它能生成更多的數據,從而我們的模型絕不會看到兩張一模一樣的照片。這能防止過度擬合,並讓模型總結能力更強。

我們會建兩個ImageDataGenerator object。

train_datagen是訓練集,val_datagen是驗證集。這兩個集會對圖片做變形調整。而train_datagen會做更多的調整。

從前面兩個object中,我們會創建兩個文件生成器:

  • train_generator
  • validation_generator

每個生成器都會從目錄生成批量張量圖片數據,實時數據擴增。並且數據會無限批量循環。

模型架構

我會使用擁有三層卷積/池化層和兩層全連接層的卷積神經網路。三層卷積層分別使用32、32和64個3x3過濾器。

我對兩層全連接層使用dropout來防止過度擬合。

我使用隨機梯度下降優化器,學習速率為0.01,momentum係數為0.9。

因為我們是在做二進位分類,所以我使用了二進位交叉熵代價函數。

Keras提供了很方便的方法來展示模型總結。對於每一層,它都會展現輸出形狀和訓練參數數目。

這是擬合模型前的可用性測試:

我們來看看網路架構:

  • 視覺化呈現架構:

訓練模型

在訓練模型之前,我定義了兩個回調函數,訓練的時候會被回調。

  • 一個回調函數用於在損失函數不能改善驗證數據的時候及時停止訓練
  • 另一個回調函數用於儲存每個epoch(使用訓練集中的全部樣本訓練一次)驗證損失和準確度。這可以來實驗測試訓練誤差。

我還使用了keras-tqdm(github.com/bstriner/ker),它是和Keras完美整合的超棒進度條。

它可以讓你很輕鬆的監督你的模型訓練。

你需要做的事情很簡單,就是在keras_tqdm上下載TQDMNotebookCallback,然後把它當作第三個回調函數。

下面是簡單例子來呈現keras-tqdm的樣子。

關於訓練:

  • 我們會使用fit_generator方法。它是標準擬合方法的一種變化形式,把生成器作為輸入。
  • 我們會訓練模型50個epoch。每個epoch中,會有20000張獨特擴增照片以每批32張的方式流入網路,做正向傳播和反向傳播,用SGD來調整權重。使用多個epoch也是為了防止過度擬合。

計算量非常龐大:

  • 如果你是使用你自己的筆記本電腦,那麼每個epoch會花費15分鐘。
  • 如果你是像我一樣在使用p2.xlarge EC2實例,那麼每個epoch會花費大概2分鐘。

tqdm能夠讓你監督每個epoch驗證損失和準確度。這對檢查模型質量大有幫助。

分類結果

在驗證集上我們的準確率達到89.4%。訓練/驗證誤差和準確率顯示在下文。

考慮到我並沒有在設計網路架構上投入太多時間,所以這個結果已經非常棒了。

現在我們來保存模型以作後用。

在同一個表格上我們來試試訓練和驗證損失:

連續兩個epoch驗證損失都沒有提高,我們暫停了訓練。

現在我們在訓練集和驗證集上測試下準確度。

兩個矩陣持續增加直到達到一個水平狀態,模型最終過度擬合了(從epoch34開始)。

4.2下載預訓練模型

目前為止一切都挺好。我們設計了一個特定卷積神經網路,在驗證數據上表現不錯,準確率達89%。

然而有一個辦法可以得到更好的分數。在一個包含貓狗照片的大型數據集上,下載預訓練卷積神經網路的權重。這樣的網路會已經學習了和我們分類相關的有關特徵。

我會下載VGG16網路的權重。更準確的是,我會下載對應最後一層卷積層的網路權重。這個網路部分起著特徵探測的作用,我們會為了分類任務而添加全連接層。

和LeNet5相比,VGG16是一個非常大的網路。它有16層,擁有可訓練權重和將近1.4億參數。想學習更多關於VGG16,請參考這個pdf(arxiv.org/pdf/1409.1556)。

我們先下載在ImageNet訓練過的VGG16權重。這說明了我們對最後三層全連接層不是很感興趣。

我們把圖片放入網路來獲得特徵表示,再把特徵表示輸入神經網路分類工具中。

我們做這個是為了訓練集和驗證集。

當圖片經過網路的時候,是以正確的順序顯示的。因此,我們可以很容易的把標籤和它們關聯起來。

現在我們設計了一個小型全連接網路,把從VGG16提取出來的特徵都插入進去,來作為卷積神經網路的分類部分。

只15個epoch,準確率就達到了90.7%。效果很不錯。而且在我的筆記本電腦上,每個epoch只需要大概1分鐘。

很多深度學習開拓者們都提倡使用預訓練網路來完成分類任務。實際上這是在充分利用大型數據集上的大型網路訓練。

Keras能讓你輕鬆下載預訓練網路,像VGG16, GoogleNet和ResNet。更多信息,請看這個(keras.io/applications/)。

座右銘:別逞能。別浪費時間去做無用功。使用預訓練網路吧!

我們還能做什麼?

如果你對改善特定卷積神經網路很感興趣:

  • 給數據集引入更多的數據擴增
  • 使用網路超參數:卷積層數目、過濾器數目、過濾器尺寸。用驗證數據集來測試每種組合。
  • 更換或改進優化器
  • 試試不同的成本函數
  • 使用更多的全連接層
  • 引入更大膽的dropout

如果你對使用預訓練網路來得到更好結果很感興趣:

  • 使用不同的網路架構
  • 使用更多的全連接層和更多的隱藏元

如果你想挖掘卷積神經網路學到了什麼:

  • 視覺化特徵映射。我還沒有試過。不過有一篇很有趣的論文在討論這方面(arxiv.org/pdf/1311.2901)。
  • 如果你想使用訓練模型:
  • 推出產品,並使用到新的貓狗圖片上。這個方法很好的測驗了模型總結能力好不好。

總結

這篇文章概述了卷積神經網路背後的理論機制,詳細解釋了每個基本部分。

這也是一個上手指南,指導如何在AWS上搭建深度學習專門環境,如何從零開始建造端對端模型和基於預訓練的增強模型。

使用python來做深度學習研究非常有趣。Keras讓預處理數據和建層變得更加容易。記住一點,如果有天你想搭建特定神經網路的某些部分,就得換成別的框架。

我希望本文能夠讓你直觀了解卷積神經網路機制,並激發你的興趣來繼續學習。

卷積神經網路真的非常強大。任何從事計算機的人士都堅信它的強大和高效。

它的應用領域不斷在擴大。現在自然語言處理行業人士也在轉向卷積神經網路。下面是他們的一些應用:

  • 使用卷積神經網路實施文本分類:chara.cs.illinois.edu/s
  • 自動圖片描述(圖片+文本):cs.stanford.edu/people/
  • 字元層面的文本分類:papers.nips.cc/paper/57

參考:

在之前學習神經網路和卷積神經網路的時候,我參考過下列鏈接:

1.neuralnetworksanddeeplearning.com

neuralnetworksanddeeplearning.com):

包含目前為止關於神經網路和深度學習最好的筆記內容。我強烈推薦該網站給那些想學習神經網路的人。

2.CS231n Convolutional Neural Networks for Visual Recognition

cs231n.github.io/convol):

Andrej Karpathy在斯坦福大學的講義,很注重數學。

3.A Beginner Guide to Understanding Neural Networks

cs231n.github.io/convol):

一篇包含三個部分用來解釋卷積神經網路的文章,從基本的直觀感受說到架構細節。讀起來非常有趣,獲益頗豐。

  • 第一部分

adeshpande3.github.io/as-Guide-To-Understanding-Convolutional-Neural-Networks/)

  • 第二部分

adeshpande3.github.io/as-Guide-To-Understanding-Convolutional-Neural-Networks-Part-2/)

  • 第三部分

adeshpande3.github.io/a

4.Running jupyter notebooks on GPU on AWS

blog.keras.io/running-j

5.Building powerful image classification models using very little data

blog.keras.io/building-.

html)

6.CatdogNet - Keras Convnet Starter

kaggle.com/jeffd23/catd

7.A quick introduction to Neural Networks

(ujjwalkarn.me/2016/08/0)

8.An Intuitive Explanation of Convolutional Neural Networks

(ujjwalkarn.me/2016/08/1)

9. Visualizing parts of Convolutional Neural Networks using Keras and Cats

(hackernoon.com/visualiz)

原文地址:

ahmedbesbes.com/underst

原文標題:Understanding deep Convolutional Neural Networks with a practical use-case in Tensorflow and Keras

作者:Ahmed Besbes

翻譯:蘇金六

校對:韓海疇 編輯:文婧


推薦閱讀:

筆記 | 如何選擇一個靠譜的物聯網平台
如何成為大數據產品經理
大數據計數原理1+0=1這你都不會算(五)No.55
大數據計數原理1+0=1這你都不會算(八)No.60
下一次工業革命來了,你知道他是誰么?

TAG:大數據 | 卷積神經網路CNN |