別磨嘰,學完這篇你也是圖像識別專家了
圖像識別是當今深度學習的主流應用,而Keras是入門最容易、使用最便捷的深度學習框架,所以搞圖像識別,你也得強調速度,不能磨嘰。本文讓你在最短時間內突破五個流行網路結構,迅速達到圖像識別技術前沿。
作者Adrian Rosebrock
譯者郭紅廣
編輯鴿子
幾個月前,我寫了一篇關於如何使用已經訓練好的卷積(預訓練)神經網路模型(特別是VGG16)對圖像進行分類的教程,這些已訓練好的模型是用Python和Keras深度學習庫對ImageNet數據集進行訓練得到的。
這些已集成到(先前是和Keras分開的)Keras中的預訓練模型能夠識別1000種類別對象(例如我們在日常生活中見到的小狗、小貓等),準確率非常高。
先前預訓練的ImageNet模型和Keras庫是分開的,需要我們克隆一個單獨github repo,然後加到項目里。使用單獨的github repo來維護就行了。
https://github.com/fchollet/keras/blob/master/keras/applications/vgg16.py
具體來說,是先寫一個Python腳本,能載入使用這些網路模型,後端使用TensorFlow或Theano,然後預測你的測試集。
Keras上的VGGNet、ResNet、Inception與Xception
在本教程前半部分,我們簡單說說Keras庫中包含的VGG、ResNet、Inception和Xception模型架構。
然後,使用Keras來寫一個Python腳本,可以從磁碟載入這些預訓練的網路模型,然後預測測試集。
最後,在幾個示例圖像上查看這些分類的結果。
Keras上最好的深度學習圖像分類器
下面五個卷積神經網路模型已經在Keras庫中,開箱即用:
我們從ImageNet數據集的概述開始,之後簡要討論每個模型架構。
ImageNet是個什麼東東
ImageNet是一個手動標註好類別的圖片資料庫(為了機器視覺研究),目前已有22,000個類別。
然而,當我們在深度學習和卷積神經網路的背景下聽到「ImageNet」一詞時,我們可能會提到ImageNet視覺識別比賽,稱為ILSVRC。
這個圖片分類比賽是訓練一個模型,能夠將輸入圖片正確分類到1000個類別中的某個類別。訓練集120萬,驗證集5萬,測試集10萬。
這1,000個圖片類別是我們在日常生活中遇到的,例如狗,貓,各種家居物品,車輛類型等等。ILSVRC比賽中圖片類別的完整列表如下:
http://image-net.org/challenges/LSVRC/2014/browse-synsets
在圖像分類方面,ImageNet比賽準確率已經作為計算機視覺分類演算法的基準。自2012年以來,卷積神經網路和深度學習技術主導了這一比賽的排行榜。
在過去幾年的ImageNet比賽中,Keras有幾個表現最好的CNN(卷積神經網路)模型。這些模型通過遷移學習技術(特徵提取,微調(fine-tuning)),對ImaegNet以外的數據集有很強的泛化能力。
VGG16 與 VGG19
在2014年,VGG模型架構由Simonyan和Zisserman提出,在「極深的大規模圖像識別卷積網路」(Very Deep Convolutional Networks for Large Scale Image Recognition)這篇論文中有介紹。
論文地址:https://arxiv.org/abs/1409.1556
VGG模型結構簡單有效,前幾層僅使用3×3卷積核來增加網路深度,通過max pooling(最大池化)依次減少每層的神經元數量,最後三層分別是2個有4096個神經元的全連接層和一個softmax層。
「16」和「19」表示網路中的需要更新需要weight(要學習的參數)的網路層數(下面的圖2中的列D和E),包括卷積層,全連接層,softmax層:
極深的大規模圖像識別卷積網路論文的圖表1, Simonyan & Zisserman (2014)
在2014年,16層和19層的網路被認為已經很深了,但和現在的ResNet架構比起來已不算什麼了,ResNet可以在ImageNet上做到50-200層的深度,而對於CIFAR-10了來說可以做到1000+的深度。
Simonyan和Zisserman發現訓練VGG16和VGG19有些難點(尤其是深層網路的收斂問題)。因此為了能更容易進行訓練,他們減少了需要更新weight的層數(圖2中A列和C列)來訓練較小的模型。
較小的網路收斂後,用較小網路學到的weight初始化更深網路的weight,這就是預訓練。這樣做看起沒有問題,不過預訓練模型在能被使用之前,需要長時間訓練。
在大多數情況下,我們可以不用預訓練模型初始化,而是更傾向於採用Xaiver/Glorot初始化或MSRA初始化。讀All you need is a good init這篇論文可以更深了解weight初始化和深層神經網路收斂的重要性。
MSRA初始化:https://arxiv.org/abs/1502.01852
All you need is a good init:https://arxiv.org/abs/1511.06422
不幸的是,VGG有兩個很大的缺點:
網路架構weight數量相當大,很消耗磁碟空間。
訓練非常慢
由於其全連接節點的數量較多,再加上網路比較深,VGG16有533MB+,VGG19有574MB。這使得部署VGG比較耗時。我們仍然在很多深度學習的圖像分類問題中使用VGG,然而,較小的網路架構通常更為理想(例如SqueezeNet、GoogLeNet等)。
ResNet(殘差網路)
與傳統的順序網路架構(如AlexNet、OverFeat和VGG)不同,其加入了y=x層(恆等映射層),可以讓網路在深度增加情況下卻不退化。下圖展示了一個構建塊(build block),輸入經過兩個weight層,最後和輸入相加,形成一個微架構模塊。ResNet最終由許多微架構模塊組成。
在2015年的「Deep Residual Learning for Image Recognition」論文中,He等人首先提出ResNet,ResNet架構已經成為一項有意義的模型,其可以通過使用殘差模塊和常規SGD(需要合理的初始化weight)來訓練非常深的網路:
論文地址:https://arxiv.org/abs/1512.03385
其在2016年後發表的文章「Identity Mappings in Deep Residual Networks」中表明,通過使用identity mapping(恆等映射)來更新殘差模塊,可以獲得很高的準確性。
論文地址:https://arxiv.org/abs/1603.05027
(左)初始殘差模型(右)升級後的殘差模型
需要注意的是,Keras庫中的ResNet50(50個weight層)的實現是基於2015年前的論文。
即使是RESNET比VGG16和VGG19更深,模型的大小實際上是相當小的,用global average pooling(全局平均水平池)代替全連接層能降低模型的大小到102MB。
Inception V3
「Inception」微架構由Szegedy等人在2014年論文"Going Deeper with Convolutions"中首次提出。
論文地址:https://arxiv.org/abs/1409.4842
GoogLeNet中所用的原始Inception模型
Inception模塊的目的是充當「多級特徵提取器」,使用1×1、3×3和5×5的卷積核,最後把這些卷積輸出連接起來,當做下一層的輸入。
這種架構先前叫GoogLeNet,現在簡單地被稱為Inception vN,其中N指的是由Google定的版本號。Keras庫中的Inception V3架構實現基於Szegedy等人後來寫的論文"Rethinking the Inception Architecture for Computer Vision",其中提出了對Inception模塊的更新,進一步提高了ImageNet分類效果。Inception V3的weight數量小於VGG和ResNet,大小為96MB。
論文地址:https://arxiv.org/abs/1512.00567
Xception
Xception架構
Xception是由Fran?ois Chollet本人(Keras維護者)提出的。Xception是Inception架構的擴展,它用深度可分離的卷積代替了標準的Inception模塊。
原始論文「Xception: Deep Learning with Depthwise Separable Convolutions」在這裡:
論文地址:https://arxiv.org/abs/1610.02357
Xception的weight數量最少,只有91MB。
至於說SqueezeNet?
SqueezeNet的「火」模型
SqueezeNet架構通過使用squeeze卷積層和擴展層(1x1和3X3卷積核混合而成)組成的fire moule獲得了AlexNet級精度,且模型大小僅4.9MB。
雖然SqueezeNet模型非常小,但其訓練需要技巧。在我即將出版的書「深度學習計算機視覺與Python」中,詳細說明了怎麼在ImageNet數據集上從頭開始訓練SqueezeNet。
用Python和上述Keras庫來給圖像分類
讓我們學習如何使用Keras庫中預訓練的卷積神經網路模型進行圖像分類吧。
新建一個文件,命名為classify_image.py,並輸入如下代碼:
第2-13行的作用是導入所需Python包,其中大多數包都屬於Keras庫。
具體來說,第2-6行分別導入ResNet50,Inception V3,Xception,VGG16和VGG19。
需要注意,Xception網路只能用TensorFlow後端(如果使用Theano後端,該類會拋出錯誤)。
第7行,使用imagenet_utils模塊,其有一些函數可以很方便的進行輸入圖像預處理和解碼輸出分類。
除此之外,還導入的其他輔助函數,其次是NumPy進行數值處理,cv2進行圖像編輯。
接下來,解析命令行參數:
我們只需要一個命令行參數--image,這是要分類的輸入圖像的路徑。
還可以接受一個可選的命令行參數--model,指定想要使用的預訓練模型,默認使用vgg16。
通過命令行參數得到指定預訓練模型的名字,我們需要定義一個Python字典,將模型名稱(字元串)映射到其真實的Keras類。
第25-31行定義了MODELS字典,它將模型名稱字元串映射到相應的類。
如果在MODELS中找不到--model名稱,將拋出AssertionError(第34-36行)。
卷積神經網路將圖像作為輸入,然後返回與類標籤相對應的一組概率作為輸出。
經典的CNN輸入圖像的尺寸,是224×224、227×227、256×256和299×299,但也可以是其他尺寸。
VGG16,VGG19和ResNet均接受224×224輸入圖像,而Inception V3和Xception需要299×299像素輸入,如下面的代碼塊所示:
將inputShape初始化為224×224像素。我們還使用函數preprocess_input執行平均減法。
然而,如果使用Inception或Xception,我們需要把inputShape設為299×299像素,接著preprocess_input使用separate pre-processing function,圖片可以進行不同類型的縮放。
下一步是從磁碟載入預訓練的模型weight(權重)並實例化模型:
第58行,從--model命令行參數得到model的名字,通過MODELS詞典映射到相應的類。
第59行,然後使用預訓練的ImageNet權重實例化卷積神經網路。
注意:VGG16和VGG19的權重文件大於500MB。ResNet為?100MB,而Inception和Xception在90-100MB之間。如果是第一次運行此腳本,這些權重文件自動下載並緩存到本地磁碟。根據您的網路速度,這可能需要一些時間。然而,一旦權重文件被下載下來,他們將不需要重新下載,再次運行classify_image.py會非常快。
模型現在已經載入並準備好進行圖像分類 - 我們只需要準備圖像進行分類:
第65行,從磁碟載入輸入圖像,inputShape調整圖像的寬度和高度。
第66行,將圖像從PIL/Pillow實例轉換為NumPy數組。
輸入圖像現在表示為(inputShape[0],inputShape[1],3)的NumPy數組。
第72行,我們通常會使用卷積神經網路分批對圖像進行訓練/分類,因此我們需要通過np.expand_dims向矩陣添加一個額外的維度(顏色通道)。
經過np.expand_dims處理,image具有的形狀(1,inputShape[0],inputShape[1],3)。如沒有添加這個額外的維度,調用.predict會導致錯誤。
最後,第76行調用相應的預處理功能來執行數據歸一化。
經過模型預測後,並獲得輸出分類:
第80行,調用CNN中.predict得到預測結果。根據這些預測結果,將它們傳遞給ImageNet輔助函數decode_predictions,會得到ImageNet類標籤名字(id轉換成名字,可讀性高)以及與標籤相對應的概率。
然後,第85行和第86行將前5個預測(即具有最大概率的標籤)輸出到終端 。
在我們結束示例之前,我們將在此處執行的最後一件事情,通過OpenCV從磁碟載入我們的輸入圖像,在圖像上繪製#1預測,最後將圖像顯示在我們的屏幕上:
查看預訓練模型的實際運行,請看下節。
VGGNet、ResNet、Inception與Xception的分類結果
這篇博文中的所有示例都使用Keras>=2.0和TensorFlow後端。如果使用TensorFlow,請確保使用版本>=1.0,否則將遇到錯誤。我也用Theano後端測試了這個腳本,並確認可以使用Theano。
安裝TensorFlow/Theano和Keras後,點擊底部的源代碼+示例圖像鏈接就可下載。
現在我們可以用VGG16對圖像進行分類:
我們可以看到VGG16正確地將圖像分類為「足球」,概率為93.43%。
要使用VGG19,我們只需要更改--network命令行參數:
VGG19能夠以91.76%的概率將輸入圖像正確地分類為「convertible」。看看其他top-5預測:「跑車」的概率為4.98%(其實是轎車),「豪華轎車」為1.06%(雖然不正確但看著合理),「車輪」為0.75%(從模型角度來說也是正確的,因為圖像中有車輪)。
在以下示例中,我們使用預訓練ResNet架構,可以看下top-5概率值:
ResNet正確地將ClintEastwood持槍圖像分類為「左輪手槍」,概率為69.79%。在top-5中還有,「步槍」為7.74%,「衝鋒槍」為5.63%。由於"左輪手槍"的視角,槍管較長,CNN很容易認為是步槍,所以得到的步槍也較高。
下一個例子用ResNet對狗的圖像進行分類:
狗的品種被正確識別為「比格犬」,具有94.48%的概率。
然後,我嘗試從這個圖像中分出《加勒比海盜》演員約翰尼?德普:
雖然ImageNet中確實有一個「船」類,但有趣的是,Inception網路能夠正確地將場景識別為「(船)殘骸」,且有具有96.29%概率的。所有其他預測標籤,包括 「海濱」,「獨木舟」,「槳」和「防波堤」都是相關的,在某些情況下也是絕對正確的。
對於Inception網路的另一個例子,我給辦公室的沙發拍攝了照片:
Inception正確地預測出圖像中有一個「桌燈」,概率為69.68%。其他top-5預測也是完全正確的,包括「工作室沙發」、「窗帘」(圖像的最右邊,幾乎不顯眼)「燈罩」和「枕頭」。
Inception雖然沒有被用作對象檢測器,但仍然能夠預測圖像中的前5個對象。卷積神經網路可以做到完美的對物體進行識別!
再來看下Xception:
這裡我們有一個蘇格蘭桶的圖像,尤其是我最喜歡的蘇格蘭威士忌,拉加維林。Xception將此圖像正確地分類為 「桶」。
最後一個例子是使用VGG16進行分類:
幾個月前,當我打完《巫師 III》(The Wild Hunt)這局遊戲之後,我給顯示器照了這個照片。VGG16的第一個預測是「家庭影院」,這是一個合理的預測,因為top-5預測中還有一個「電視/監視器」。
從本文章的示例可以看出,在ImageNet數據集上預訓練的模型能夠識別各種常見的日常對象。你可以在你自己的項目中使用這個代碼!
總結
簡單回顧一下,在今天的博文中,我們介紹了在Keras中五個卷積神經網路模型:
此後,我演示了如何使用這些神經網路模型來分類圖像。希望本文對你有幫助。
原文地址:
http://www.pyimagesearch.com/2017/03/20/imagenet-vggnet-resnet-inception-xception-keras/
AI100點評:
這篇只是介紹了怎麼使用Keras中預訓練模型,雖然直接使用這些模型能得到和專家級別同樣的效果,但模型的具體架構,怎麼調參,背後思想等一些知識還需要讀者去參考其他資料。我建議先直接去讀Keras中這些代碼,遇到不了解的知識點再去查找其他資料。
課程結合實例介紹使用TensorFlow開發機器學習應用的詳細方法和步驟,著重講解了用於圖像識別的卷積神經網路和用於自然語言處理的循環神經網路的理論知識及其TensorFlow實現方法,並結合實際場景和例子描述了深度學習技術的應用範圍與效果。 所有案例均來自講師團隊工作中的親身實踐,所選案例均是深度學習的經典應用,非常具有代表性。


※敗1/4子是刻意設定?蔣濤講解AlphaGo2.0如何進化
TAG:AI100 |
※如果你能識別這些圖像內容,那你還是比 AI 聰明一些的
※學會破解這幾句話 你就能識別這個人城府是深還是淺
※手寫識別就是這樣被弄粗來的
※如何識別渣男?看他有沒有這幾個特徵就夠了
※為什麼有人一眼就能識別你生過孩子,原來這三個部位將你出賣了!
※心理學家是如何識別謊言的?只需要用一下這個小技巧
※識別特定圖像的AI玻璃來了,未來或可用於人臉識別
※千元機面部識別一遇黑夜就失靈?能解決這個的,目前只有這家
※你從未學過繁體字,為何一眼就能識別?
※為了順利吸貓,他們在家裡裝了一個貓臉識別儀,這夫婦倆也是厲害
※這些個六個核桃家族的山寨版好多人恐怕都識別不了,沒錯這就是在侮辱你的智商
※人工智慧都識別不了的字,我竟然看懂了
※你吃的是菠蘿還是鳳梨?它們之間大的區別在這裡,教你一招識別
※陳赫老婆這是怎麼了?近照像是變了個人,網紅臉毫無識別度
※工作中怎樣識別誰是你的貴人?有這四點特質的人,就是你的貴人!
※看圖識別這六大騙局,每一個都能讓人傾家蕩產!
※面部識別=Face ID?別被騙了!這可還真不一樣
※反面部識別眼鏡:戴上它,你就是另一個人!
※這個乾貨一般人我不說:智能語音識別與關鍵詞識別有什麼關係?
※現在AI這麼厲害的嗎?看一眼照片就能識別是直是彎!