厲害了!用不到20行的Python代碼構(gòu)建一個(gè)對(duì)象檢測(cè)模型
原創(chuàng)【51CTO.com原創(chuàng)稿件】當(dāng)一張圖片顯示在眼前時(shí),我們的大腦會(huì)馬上會(huì)識(shí)別出圖片里面所含的對(duì)象。另一方面,我們需要花費(fèi)大量的時(shí)間和訓(xùn)練數(shù)據(jù)才能讓機(jī)器識(shí)別這些對(duì)象。
不過(guò)鑒于硬件和深度學(xué)習(xí)方面最近的進(jìn)步,這個(gè)計(jì)算機(jī)視覺(jué)領(lǐng)域變得容易和直觀了許多。
以下面這張圖片為例,該系統(tǒng)能夠識(shí)別圖片中的不同對(duì)象,準(zhǔn)確度極高。
圖 1
現(xiàn)在對(duì)象檢測(cè)技術(shù)在各行各業(yè)已迅速得到了采用。它幫助自動(dòng)駕駛汽車安全地行駛,在擁擠的場(chǎng)所發(fā)現(xiàn)暴力行為,協(xié)助球隊(duì)分析和制作選秀報(bào)告,確保制造零件得到適當(dāng)?shù)馁|(zhì)量控制,不一而足。
這些僅僅是對(duì)象探測(cè)技術(shù)強(qiáng)大功能的幾個(gè)應(yīng)用!在本文中我們將了解對(duì)象檢測(cè)是什么,看看可用來(lái)在該領(lǐng)域解決問(wèn)題的幾種不同方法。
然后我們將深入研究使用 Python 構(gòu)建我們自己的對(duì)象檢測(cè)系統(tǒng)??赐瓯疚暮?,你將掌握足夠的知識(shí),克服不同的對(duì)象檢測(cè)難題!
注意:本教程假設(shè)你了解了深度學(xué)習(xí)的基礎(chǔ)知識(shí),之前已解決了簡(jiǎn)單的圖像處理問(wèn)題。
如果你還沒(méi)有或需要惡補(bǔ)一下,建議先閱讀下列文章:
- 《深度學(xué)習(xí)的基礎(chǔ):從人工神經(jīng)網(wǎng)絡(luò)開(kāi)始》
- 《面向計(jì)算機(jī)視覺(jué)的深度學(xué)習(xí):卷積神經(jīng)網(wǎng)絡(luò)簡(jiǎn)介》
- 《教程:使用Keras優(yōu)化神經(jīng)網(wǎng)絡(luò)(附有圖像識(shí)別案例研究)》
對(duì)象檢測(cè)是什么?
在我們開(kāi)始構(gòu)建最先進(jìn)的模型之前,先了解一下對(duì)象檢測(cè)是什么。我們不妨假設(shè)為自動(dòng)駕駛汽車構(gòu)建一個(gè)行人檢測(cè)系統(tǒng)。
假設(shè)你開(kāi)的汽車捕捉到如下圖這樣的圖像,你會(huì)如何描述這個(gè)圖像?
圖 2
該圖像實(shí)際上描繪了我們的汽車駛近廣場(chǎng),幾個(gè)人在我們的車前方橫過(guò)馬路。
由于交通標(biāo)志看不清楚,汽車的行人檢測(cè)系統(tǒng)應(yīng)準(zhǔn)確識(shí)別人們行走的位置,以便能避開(kāi)他們。
那么,汽車的系統(tǒng)該怎樣確保避免行人呢?它能做的就是用邊界框?qū)⑦@些人圈出來(lái),那樣系統(tǒng)就能準(zhǔn)確識(shí)別圖像中行人的位置,然后相應(yīng)地決定走哪條路,以免發(fā)生任何意外。
圖 3
我們做對(duì)象檢測(cè)有兩方面的目標(biāo):
- 識(shí)別圖像中的所有對(duì)象及其位置
- 過(guò)濾掉關(guān)注的對(duì)象
解決對(duì)象檢測(cè)問(wèn)題的不同方法
我們已知道陳述的問(wèn)題是什么,那么可以用哪種方法(或哪幾種方法)來(lái)解決問(wèn)題呢?
在本節(jié)中我們將介紹可用于檢測(cè)圖像中對(duì)象的幾種技術(shù)。先從最簡(jiǎn)單的方法開(kāi)始介紹,然后逐漸深入。
方法 1:樸素方法(分治法)
我們可以采取的最簡(jiǎn)單方法就是將圖像分解成四個(gè)部分:
圖 4:左上角
圖 5:右上角
圖 6:左下角
圖 7:右下角
下一步是將這每一個(gè)部分都饋送給圖像分類器。其輸出結(jié)果就是圖像的某部分有沒(méi)有行人。如果有行人,就在原始圖像中標(biāo)記這個(gè)圖像塊(patch)。
輸出結(jié)果會(huì)像這樣:
圖 8
這是值得先試一下的好方法,但我們尋求的是一種準(zhǔn)確性和精確性極高的系統(tǒng)。
它需要識(shí)別整個(gè)對(duì)象(或本文中的行人),因?yàn)閮H僅定位對(duì)象的某些部分可能導(dǎo)致災(zāi)難性的結(jié)果。
方法 2:增加分解數(shù)量
前一個(gè)系統(tǒng)做得很好,但我們還能做些什么?我們可以大幅增加輸入到系統(tǒng)的圖像塊的數(shù)量,以此改進(jìn)該系統(tǒng)。
輸出結(jié)果應(yīng)該是這樣:
圖 9
最終這有利也有弊。當(dāng)然,我們的解決方案看起來(lái)比樸素方法好一點(diǎn),但存在太多大同小異的邊界框。這是個(gè)問(wèn)題,我們需要一種更結(jié)構(gòu)化的方法來(lái)解決問(wèn)題。
方法 3:執(zhí)行結(jié)構(gòu)化分解
為了以一種更結(jié)構(gòu)化的方式構(gòu)建對(duì)象檢測(cè)系統(tǒng),我們可以遵照下列步驟:
第 1 步:將圖像分解成 10x10 網(wǎng)格,如下圖所示:
圖 10
第 2 步:為每個(gè)圖像塊定義質(zhì)心(centroid)。
第 3 步:對(duì)于每個(gè)質(zhì)心,取高度和縱橫比不一的三個(gè)不同的圖像塊,如下圖所示:
圖 11
第 4 步:讓創(chuàng)建的所有圖像塊過(guò)一遍圖像分類器,進(jìn)行預(yù)測(cè)。
那么最終的輸出結(jié)果怎樣?當(dāng)然更結(jié)構(gòu)化一點(diǎn)、更規(guī)范化一點(diǎn),請(qǐng)看下面:
圖 12
但我們可以進(jìn)一步改進(jìn)這方面!下面介紹獲得更好結(jié)果的另一種方法。
方法 4:提高效率
我們看到的前一種方法在很大程度上可以接受,但我們可以構(gòu)建比它更高效一點(diǎn)的系統(tǒng)。
對(duì)此你有何建議?我首先想到的就是優(yōu)化。如果我們考慮采用方法 3,可以做兩件事來(lái)改善模型。
增加網(wǎng)格大小
我們可以將網(wǎng)格大小增加到 20,而不是選擇 10。
圖 13
使用高度和縱橫比不一的更多圖像塊,而不是三個(gè)圖像塊
在這里,我們可以讓一個(gè)錨點(diǎn)(anchor)對(duì)應(yīng) 9 個(gè)圖像塊,即 3 個(gè)高度不一的方形圖像塊和 6 個(gè)高度不一的垂直和水平矩形圖像塊。這將給我們帶來(lái)縱橫比不一的圖像塊。
圖 14
這同樣有其優(yōu)缺點(diǎn)。當(dāng)然,這兩種方法都可以幫助我們更精細(xì)化。但它會(huì)再次生成不得不過(guò)一遍圖像分類器模型的眾多圖像塊。
我們能做的是,取用選擇性的圖像塊,而不是取用所有圖像塊。比如我們可以構(gòu)建一個(gè)中間分類器,試著預(yù)測(cè)某圖像塊實(shí)際上有沒(méi)有背景,即可能含有一個(gè)對(duì)象。這將大大減少圖像分類器模型所看到的圖像塊。
我們能做的另一種優(yōu)化就是減少表明“同一結(jié)果”的預(yù)測(cè)。不妨再以方法 3 的輸出結(jié)果為例:
圖 15
如你所見(jiàn),兩個(gè)邊界框預(yù)測(cè)基本上是同一個(gè)人。我們可以選擇其中任何一個(gè)。
所以為了做預(yù)測(cè),我們考慮“表明同一結(jié)果”的所有邊界框,然后選擇最有可能檢測(cè)到人的那個(gè)邊界框。
到目前為止,所有這些優(yōu)化都給了我們效果相當(dāng)不錯(cuò)的預(yù)測(cè)。我們幾乎穩(wěn)操勝券,但你猜到少了什么嗎?當(dāng)然是少了深度學(xué)習(xí)!
方法 5:使用深度學(xué)習(xí)
使用深度學(xué)習(xí)用于特征選擇并構(gòu)建端到端方法,深度學(xué)習(xí)在對(duì)象檢測(cè)領(lǐng)域大有潛力。我們可以在哪里利用深度學(xué)習(xí)來(lái)解決我們的問(wèn)題?如何利用?
我在下面列出了幾種方法:
- 我們可以讓原始圖像過(guò)一遍神經(jīng)網(wǎng)絡(luò)以減少維數(shù),而不是取用來(lái)自原始圖像的圖像塊。
- 我們還可以使用神經(jīng)網(wǎng)絡(luò)來(lái)建議選擇性的圖像塊。
- 我們可以強(qiáng)化深度學(xué)習(xí)算法,讓預(yù)測(cè)盡可能接近原始邊界框。這將確保算法給出更嚴(yán)謹(jǐn)、更精細(xì)的邊界框預(yù)測(cè)。
現(xiàn)在我們可以采用單個(gè)深度神經(jīng)網(wǎng)絡(luò)模型來(lái)嘗試自行解決所有問(wèn)題,而不是訓(xùn)練不同的神經(jīng)網(wǎng)絡(luò)來(lái)解決每一個(gè)問(wèn)題。
這么做的優(yōu)點(diǎn)是,神經(jīng)網(wǎng)絡(luò)每個(gè)較小的部分將有助于優(yōu)化同一個(gè)神經(jīng)網(wǎng)絡(luò)的其他部分。這將幫助我們共同訓(xùn)練整個(gè)深度模型。
輸出結(jié)果將帶來(lái)目前為止我們看到的所有方法中最佳的性能,有點(diǎn)類似于下圖。我們?cè)谙乱还?jié)將看到如何使用 Python 來(lái)構(gòu)建這個(gè)模型。
圖 16
如何使用 ImageAI 庫(kù)構(gòu)建對(duì)象檢測(cè)模型?
我們已知道了對(duì)象檢測(cè)是什么、解決這個(gè)問(wèn)題的最佳方法,現(xiàn)在不妨構(gòu)建自己的對(duì)象檢測(cè)系統(tǒng)!
我們將使用 ImageAI(https://github.com/OlafenwaMoses/ImageAI),這個(gè) Python 庫(kù)支持面向計(jì)算機(jī)視覺(jué)任務(wù)的最先進(jìn)的機(jī)器學(xué)習(xí)算法。
運(yùn)行對(duì)象檢測(cè)模型來(lái)獲得預(yù)測(cè)很簡(jiǎn)單。我們不必操心復(fù)雜的安裝腳本即可入手,甚至不需要 GPU 來(lái)生成預(yù)測(cè)!我們將使用這個(gè) ImageAI 庫(kù)來(lái)獲得在上面方法 5 中看到的輸出預(yù)測(cè)。
強(qiáng)烈建議你遵循下面的代碼(在你自己的機(jī)器上),因?yàn)檫@讓你能夠從本節(jié)獲得盡可能多的知識(shí)。
請(qǐng)注意,你在構(gòu)建對(duì)象檢測(cè)模型之前需要設(shè)置好系統(tǒng)。一旦你在本地系統(tǒng)中安裝了 Anaconda,就可以開(kāi)始執(zhí)行下列步驟。
第 1 步:使用 Python 版本 3.6 創(chuàng)建 Anaconda 環(huán)境。
- conda create -n retinanet python=3.6 anaconda
第 2 步:激活該環(huán)境,安裝必要的程序包。
- source activate retinanet
- conda install tensorflow numpy scipy opencv pillow matplotlib h5py keras
第 3 步:隨后安裝 ImageAI 庫(kù)。
- pip install https://github.com/OlafenwaMoses/ImageAI/releases/download/2.0.1/imageai-2.0.1-py3-none-any.whl
第 4 步:現(xiàn)在下載生成預(yù)測(cè)所需要的預(yù)訓(xùn)練模型。該模型基于 RetinaNet。
點(diǎn)擊鏈接即可下載:RetinaNet 預(yù)訓(xùn)練模型(https://github.com/OlafenwaMoses/ImageAI/releases/download/1.0/resnet50_coco_best_v2.0.1.h5)。
第 5 步:將下載的文件復(fù)制到當(dāng)前的工作文件夾。
第6 步:從該鏈接(https://s3-ap-south-1.amazonaws.com/av-blog-media/wp-content/uploads/2018/06/I1_2009_09_08_drive_0012_001351-768x223.png)下載圖像,將圖像命名為 image.png。
第 7 步:打開(kāi) jupyter 筆記本(在終端中輸入 jupyter notebook),運(yùn)行下列代碼:
- from imageai.Detection import ObjectDetection
- import os
- execution_path = os.getcwd()
- detector = ObjectDetection()
- detector.setModelTypeAsRetinaNet()
- detector.setModelPath( os.path.join(execution_path , "resnet50_coco_best_v2.0.1.h5"))
- detector.loadModel()
- custom_objects = detector.CustomObjects(person=True, car=False)
- detections = detector.detectCustomObjectsFromImage(input_image=os.path.join(execution_path , "image.png"), output_image_path=os.path.join(execution_path , "image_new.png"), custom_objects=custom_objects, minimum_percentage_probability=65)
- for eachObject in detections:
- print(eachObject["name"] + " : " + eachObject["percentage_probability"] )
- print("--------------------------------")
這將創(chuàng)建一個(gè)名為 image_new.png 的修改后的圖像文件,文件含有圖像的邊界框。
第 8 步:想打印輸出圖像,請(qǐng)使用下列代碼:
- fromIPython.display import Image
- Image("image_new.png")
恭喜!你已自行構(gòu)建了檢測(cè)行人的對(duì)象檢測(cè)模型。瞧瞧有多棒?
結(jié)束語(yǔ)
在本文中我們了解了對(duì)象檢測(cè)是什么以及構(gòu)建對(duì)象檢測(cè)模型背后的機(jī)理。我們還了解了如何使用 ImageAI 庫(kù)來(lái)構(gòu)建檢測(cè)行人的這個(gè)對(duì)象檢測(cè)模型。
只要稍稍改一下代碼,你就很容易改變模型,克服自己的對(duì)象檢測(cè)難題。
【51CTO原創(chuàng)稿件,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文作者和出處為51CTO.com】