2017年已到最後一個月的尾巴,那聖誕節還會遠嗎?不知道各位對于聖誕節有什麼安排或一些美好的回憶,我記得最清楚的還是每年聖誕節前一晚那些包裝好的蘋果,寓意平平安安。那談到聖誕節,不可或缺的主角——“聖誕老人”會出現在各地的大街小巷、各種畫冊上,本文将帶領讀者使用Keras完成“聖誕老人”圖像的分類,算是聖誕節前的預熱活動吧。
在介紹正式内容前,讀者可以先看這篇内容:
如何利用谷歌圖檔獲得訓練資料
在本教程的第一部分,将介紹本文使用的資料集;其次使用Python和Keras訓練一個卷積神經網絡模型,該模型能夠檢測一個圖像中是否存在聖誕老人,
所選的網絡結構類似于LeNet網絡;最後,在一系列的圖像上評估本文搭建的模型,然後讨論一下本文方法的局限性以及如何拓展等。
“ 聖誕老人 ”和“ 非聖誕老人 ”資料集
為了訓練搭建的模型,本文需要兩類圖像集:
- 圖像含聖誕老人(“聖誕老人”);
- 圖像不包含聖誕老人(“不是聖誕老人”)
上周我們用谷歌圖檔迅速擷取訓練圖像資料集,資料集中包含461張有聖誕老人的圖像中,如圖1(左)所示;此外從UKBench資料集中随機擷取461張不包含聖誕老人,如圖1(右)所示。
基于卷積神經網絡和Keras 搭建的 第一個圖像分類器
如圖2所示,該圖是一個典型的Lenet網絡結構,最初被用來數字手寫體的分類,現将其擴充到其他類型的圖像。
本教程主要是介紹如何将深度學習應用于圖像分類中,是以不會對Keras和Python語句介紹得非常詳細,感興趣的讀者可以看下Deep Learning for Computer Vison with Python這本書。
首先先定義網絡架構。建立一個新檔案并命名為lenetpy,并插入以下代碼:
第2-8行是需要導入的Python包,其中conv2d表示執行卷積,maxpooling2d表示執行最大池化,Activation表示特定的激活函數類型,Flatten層用來将輸入“壓平”,用于卷積層到全連接配接層的過渡,Dense表示全連接配接層。
真正建立Lenet網絡結構是代碼的第10-12行,每當定義了一個新的卷積神經網絡結構時,我喜歡:
- 把它放在自己的類中(為了命名空間及便于組織)
- 建立一個靜立建造函數,來完成整個模型的建立
建立的模型時需要大量的參數:
- weight:輸入圖像的寬度
- height:輸入圖像的高度
- depth:輸入圖像的通道數(1表示單通道圖像灰階,3表示标準的RGB圖像)
- claclasses:想要組織的層類别總數
第1第4行定義我們的模型,第15行初始化inputshape,第18-19行正常更新inputshape
現在我們已經初始化我們的模型,可以開始添加其它層,代碼如下:
第21-25行建立第一個CONV->RELU->POOL層,卷積層使用20個大小5x5的濾波器,之後緊跟RELU激活函數,最後使用視窗大小為2x2的最大池化操作;
之後定義第二個CONV->RELU->POOL層:
這次卷積層使用50個濾波器,濾波器個數的增加加深整個網絡體系結構。
最終的代碼塊是将資料“壓平”以連接配接全連接配接層:
第33行能将maxpooling2d層的輸出壓扁成一個單向量;
第34行顯示全連接配接層包含500個節點,然後緊跟一個ReLU激活函數;
第38行定義另一個全連接配接層,該層的節點數等于分類的類别數,Dense
層送入softmax分類器輸出每類的機率值;
第42行傳回模型的調用函數;
使用 Keras 訓練 卷積神經網絡圖像分類器
打開一個新的檔案并命名為train_networkpy,并插入以下代碼打開
第2 - 18行導入程式需要的資料包;
下面開始解析指令行參數:
這裡有兩個需要指令行參數,--dataset和--model,以及accuracy/loss圖的路徑選擇。其中--dataset表示模型的訓練集,--model表示訓練分類器後儲存的模型,如果--plot未指定,則預設為plot.PNG。
接下來,設定一些訓練變量、初始化清單并設定圖像路徑:
第32-34行定義模型的訓練次數、初始學習率以及批量大小;
第38和39行初始化資料和标簽清單,這些清單對應存儲圖像以及類别标簽;
第42-44行擷取輸入圖像路徑并将圖像随機打亂;
現在對圖像進行預處理:
該循環簡單的将每個圖像的尺寸重新調整為28×28大小(為LeNet所需要的空間尺寸)
能夠提取标簽是由于我們的資料目錄結構如下所示:
是以,imagePath的一個例子為:
從ImagePath提取标簽,結果為:
下一步,将資料集分為訓練資料集和測試資料集:
第61行進一步預處理輸入資料,按比例将資料點[ 0, 255 ]縮放到[ 0, 1 ]範圍内;
然後第66-67行将75%資料作為訓練集,25%資料作為測試集;第70-71行對标簽進行獨熱編碼;随後,通過以下操作增加資料量:
第74-76行建立一個圖像發生器,對資料集圖像進行随機旋轉、移動、翻轉、剪切等,通過這種操作允許我們能用一個較小的資料集實作好的結果。
繼續深入學習Keras訓練圖像分類器:
第80-83行使用Adam優化器,由于本文是一個二分類問題,可以使用二進制交叉熵損失函數(binary cross-entropy)。但如果執行的分類任務多于兩類,損失函數更換為類别交叉熵(categorical_crossentropy)
第87-89行調用model.fit_generator開始訓練網絡,第93行儲存模型參數,最後畫出圖像分類器的性能結果:
為了訓練網絡模型,需要打開一個終端執行以下指令:
可以看到,當網絡訓練了25個回合後,模型的測試精度為97.40%,損失函數也很低,如下圖所示:
評估卷積神經網絡圖像分類器
打開一個新的檔案并命名為test_networkpy,然後開始進行評估:
第2-7行導入需要的資料包,另外注意導入的load_model是訓練過程中儲存的模型。
下一步,解析指令行參數:
需要兩個指令行參數:--model和輸入--image,然後加載圖像預處理:
預處理與前面幾乎一模一樣,這裡不做過多的解釋,隻是第25行通過np.expand_dims對資料額外添加了一個次元,如果忘記添加次元,它将導緻調用model.predict時出現錯誤。現在加載圖像分類器模型并進行預測:
第29行加載模型,第32行做出預測。最後畫出頭像以及預測标簽:
第35行建立标簽,第36行選擇對應的機率值,第37行将标簽文本顯示在圖像的左上角,第40-42行調整圖像大小為标準的寬度以確定它适應電腦螢幕,最後,第45行顯示輸出圖像,第46行表示當一個鍵被按下結束顯示。
以下是包含聖誕老人圖像的實驗結果:
以下是不包含聖誕老人圖像的實驗結果:
本文 圖像分類模型的局限性
本文圖像分類器有一些局限性:
第一個是輸入圖像尺寸28×28很小。一些示例圖像(圖像中聖誕老人本身已經很小)調整尺寸為28×28後大大降低聖誕老人的尺寸。
最優的卷積神經網絡正常接受輸入圖像大小一般為200-300像素,是以一些較大尺寸的圖像将幫助我們建立一個更強大的圖像分類器。然而,使用更大的分辨率的圖像會加深網絡模型的深度和複雜度,這将意味着需要收集更多的訓練資料,以及昂貴的計算訓練過程。
是以,如果各位讀者想提高本文模型的精度話,有以下四點建議:
- 收集更多的訓練資料(超過5000幅“聖誕老人”圖像);
- 利用高分辨率的圖像在訓練。 64×64、128×128像素的圖像可能效果會更理想;
- 在訓練過程中使用一個更深層次的網絡體系結構;
- 閱讀Deep Learning for Computer Vision with Python,裡面有更多關于自定義資料集等内容的細節;
總結
- 本文教你學會利用Keras和Pyhton訓練LeNet模型,并用來完成是否含有聖誕老人形象的圖像分類,最終目标可以是建立一個應用程式類似于Not Hotdog;
- “聖誕老人”圖像資料集(460幅)是按照之前的教程——通過谷歌圖檔采集深度學習的圖像獲得,而“沒有聖誕老人”的圖像資料集是由從UKBench資料集中挑選得到;
- 在一系列的測試圖像上評估本文搭建的網絡模型,在每一種情況下,本文模型都能對輸入圖像分類正确。
作者資訊 Adrain Rosebrock,企業家、博士,專注于圖像搜尋引擎。
Linkedin: https://www.linkedin.com/in/adrian-rosebrock-59b8732a/
本文由北郵@愛可可-愛生活老師推薦,阿裡雲雲栖社群組織翻譯。
文章原标題《Image classification with Keras and deep learning》,作者:Adrain Rosebrock,譯者:海棠,審閱:董邵男。
文章為簡譯,更為詳細的内容,請檢視 原文