本文編譯自 Adrian Rosebrock 發(fā)表在PyImageSearch 上的一篇博文。該博文緣起于一位網(wǎng)友向原作者請(qǐng)教的兩個(gè)關(guān)于目標(biāo)檢測(cè)的問(wèn)題:
如何過(guò)濾或忽略我不感興趣的類(lèi)?
如何在目標(biāo)檢測(cè)模型中添加新的類(lèi)?這是否可行?
Adrian Rosebrock 認(rèn)為這兩個(gè)問(wèn)題是學(xué)習(xí)目標(biāo)檢測(cè)的同學(xué)經(jīng)常問(wèn)到的問(wèn)題,于是創(chuàng)作了本篇文章統(tǒng)一回答。
具體來(lái)說(shuō),在這篇文章中你會(huì)了解到:
圖像分類(lèi)和目標(biāo)檢測(cè)的區(qū)別;
深度學(xué)習(xí)目標(biāo)檢測(cè)模型的構(gòu)成,包括目標(biāo)檢測(cè)框架和基本模型框架的不同;
如何將訓(xùn)練好的深度網(wǎng)絡(luò)模型用于目標(biāo)檢測(cè);
如何過(guò)濾和忽略深度學(xué)習(xí)模型所檢測(cè)的類(lèi)別;
在深度神經(jīng)網(wǎng)絡(luò)中,添加或刪除檢測(cè)類(lèi)別時(shí)常見(jiàn)誤區(qū)。
想要了解更多的關(guān)于深度學(xué)習(xí)目標(biāo)檢測(cè)方面的知識(shí),或者想要解開(kāi)關(guān)于深度學(xué)習(xí)目標(biāo)檢測(cè)的相關(guān)疑惑,請(qǐng)繼續(xù)閱讀。
▌深度學(xué)習(xí)目標(biāo)檢測(cè)指南
今天的博客旨在簡(jiǎn)單介紹基于深度學(xué)習(xí)的目標(biāo)檢測(cè)。
我已經(jīng)盡量提供關(guān)于深度學(xué)習(xí)目標(biāo)檢測(cè)模型構(gòu)成的內(nèi)容,包括提供使用預(yù)先訓(xùn)練的目標(biāo)檢測(cè)模型實(shí)現(xiàn)深度學(xué)習(xí)的 OpenCV + Python 的源代碼。
使用這個(gè)指南能夠幫助你初步了解深度學(xué)習(xí)目標(biāo)檢測(cè),但同時(shí)你也會(huì)意識(shí)到,涉及目標(biāo)檢測(cè)的很多技術(shù)細(xì)節(jié),我無(wú)法在這篇博客中講得面面俱到。
也就是說(shuō),我們將通過(guò)討論圖像分類(lèi)和目標(biāo)檢測(cè)的本質(zhì)區(qū)別來(lái)引出今天的博客內(nèi)容,包括圖像分類(lèi)訓(xùn)練好的模型能否用于目標(biāo)檢測(cè)(以及在什么情況下)。
我們一旦理解了什么是目標(biāo)檢測(cè)后,我們將會(huì)回顧深度學(xué)習(xí)目標(biāo)檢測(cè)模型的核心部分,包括目標(biāo)檢測(cè)框架和基礎(chǔ)模型,這是初次接觸目標(biāo)檢測(cè)的讀者感到疑惑的兩個(gè)關(guān)鍵部分。
在這基礎(chǔ)上,我們將會(huì)使用 OpenCV 運(yùn)行實(shí)時(shí)深度學(xué)習(xí)目標(biāo)檢測(cè)模型。
在不改動(dòng)網(wǎng)絡(luò)結(jié)構(gòu)和重新訓(xùn)練模型的前提下,我將會(huì)演示如何能夠忽略和過(guò)濾你不感興趣的目標(biāo)類(lèi)別。
最后,我們將討論在深度學(xué)習(xí)目標(biāo)檢測(cè)中如何添加或刪減類(lèi)別,我們將以此結(jié)束今天的博客,包括我推薦的資源來(lái)幫助你入門(mén)。
讓我們開(kāi)始深入了解深度學(xué)習(xí)目標(biāo)檢測(cè)吧!
▌圖像分類(lèi)和目標(biāo)檢測(cè)的區(qū)別
圖1:分類(lèi)(左邊)和目標(biāo)檢測(cè)(右邊)的直觀區(qū)別。對(duì)于圖像分類(lèi),是將整張圖片進(jìn)行分類(lèi),并且是單一標(biāo)簽。對(duì)于目標(biāo)檢測(cè)的情況,我們的神經(jīng)網(wǎng)絡(luò)會(huì)對(duì)圖片中的(潛在的多個(gè))目標(biāo)進(jìn)行定位。
當(dāng)進(jìn)行標(biāo)準(zhǔn)圖像分類(lèi)時(shí),指定一個(gè)輸入圖像,我們將它輸入到我們的神經(jīng)網(wǎng)絡(luò)中,我們會(huì)獲得一個(gè)類(lèi)標(biāo)簽,或者是相應(yīng)被分類(lèi)標(biāo)簽的概率。
這個(gè)類(lèi)標(biāo)簽旨在描述整張圖像的內(nèi)容,或至少是圖像中最主要的可視內(nèi)容。
舉例子來(lái)說(shuō),如圖1中指定的輸入圖像(左邊),我們的卷積神經(jīng)網(wǎng)絡(luò)把圖像標(biāo)記為“比格犬”。
因此,我們可以將圖像分類(lèi)視為:
一張圖片輸入;
一個(gè)類(lèi)標(biāo)簽輸出。
目標(biāo)檢測(cè),無(wú)論是通過(guò)深度學(xué)習(xí)還是其他計(jì)算機(jī)視覺(jué)技術(shù)實(shí)現(xiàn),目標(biāo)檢測(cè)均基于圖像分類(lèi),同時(shí)試圖精準(zhǔn)定位圖像中每個(gè)目標(biāo)的位置。
在執(zhí)行目標(biāo)檢測(cè)時(shí),給定一個(gè)輸入圖像,我們希望能夠獲得:
邊框列表,或者圖像中每個(gè)目標(biāo)的 (x, y) 坐標(biāo);
每個(gè)邊框所對(duì)應(yīng)的類(lèi)標(biāo)簽;
每個(gè)邊框和類(lèi)標(biāo)簽相應(yīng)的概率和置信度分?jǐn)?shù)。
圖 1(右邊)給出了一個(gè)運(yùn)用深度學(xué)習(xí)進(jìn)行目標(biāo)檢測(cè)的例子。注意,用邊界框?qū)θ撕凸愤M(jìn)行定位,并給出預(yù)測(cè)類(lèi)標(biāo)簽。
因此,目標(biāo)檢測(cè)讓我們能夠:
向網(wǎng)絡(luò)輸入一張圖像;
獲得多個(gè)邊框和類(lèi)標(biāo)簽作為輸出。
▌可以將深度學(xué)習(xí)圖像分類(lèi)器用于目標(biāo)檢測(cè)嗎?
圖 2:使用滑動(dòng)窗口的非端到端深度學(xué)習(xí)目標(biāo)檢測(cè)模型(左邊)+ 結(jié)合分類(lèi)的圖像金字塔(右邊)方法
好的,所以此時(shí)你理解了圖像分類(lèi)和目標(biāo)檢測(cè)最重要的區(qū)別:
當(dāng)實(shí)行圖像分類(lèi)時(shí),我們向網(wǎng)絡(luò)中輸入一張圖像,并獲得一個(gè)類(lèi)標(biāo)簽作為輸出;
但是,當(dāng)實(shí)行目標(biāo)檢測(cè)時(shí),我們輸入一張圖像,將獲得多個(gè)邊界框和類(lèi)標(biāo)簽輸出。
引出了這個(gè)問(wèn)題:
對(duì)于已經(jīng)訓(xùn)練好的用于分類(lèi)的網(wǎng)絡(luò),我們是否能將它用于目標(biāo)檢測(cè)?
答案有點(diǎn)復(fù)雜,因?yàn)榧夹g(shù)上“可以”,但是原因并不那么淺顯。
解決方案涉及:
運(yùn)用傳統(tǒng)基于計(jì)算機(jī)視覺(jué)的目標(biāo)檢測(cè)方法(即非深度學(xué)習(xí)方法),比如滑動(dòng)窗口和圖像金字塔,這類(lèi)方法通常用于基于 HOG 特征和線性支持向量機(jī)的目標(biāo)檢測(cè)器中;
獲取預(yù)先訓(xùn)練好的模型,并將它作為深度學(xué)習(xí)目標(biāo)檢測(cè)框架的基礎(chǔ)網(wǎng)絡(luò)。(比如 Faster R-CNN, SSD, YOLO )。
方法 1:傳統(tǒng)目標(biāo)檢測(cè)方法
第一種方法不是純粹的端到端的深度學(xué)習(xí)目標(biāo)檢測(cè)模型。
我們采用:
固定大小的滑動(dòng)窗口,這個(gè)窗口自左到右,自上到下滑動(dòng)去定位不同位置的目標(biāo);
圖像金字塔,用于檢測(cè)不同尺度的目標(biāo);
通過(guò)預(yù)先訓(xùn)練好的卷積神經(jīng)網(wǎng)絡(luò)(分類(lèi)器)進(jìn)行分類(lèi)。
在滑動(dòng)窗口和圖像金字塔的每次停頓中,我們找出感興趣的區(qū)域,傳輸?shù)骄矸e神經(jīng)網(wǎng)絡(luò)中,并且輸出這個(gè)區(qū)域的分類(lèi)。
如果標(biāo)簽L的分類(lèi)概率比某個(gè)閾值T高,我們將標(biāo)記這個(gè)感興趣區(qū)域的邊框?yàn)闃?biāo)簽 L。每次滑動(dòng)窗口和圖像金字塔停頓都將重復(fù)這個(gè)過(guò)程,我們將會(huì)獲得輸出的目標(biāo)檢測(cè)結(jié)果。最后,我們對(duì)所有的邊框采用非極大值抑制,生成我們最終輸出的檢測(cè)結(jié)果:
圖 3:應(yīng)用非極大值抑制將抑制重疊,減少邊框置信度
這個(gè)方法可以用于某些特定用例中,但是,一般而言,這種方法很慢,冗長(zhǎng)乏味,并且容易出錯(cuò)。
然而,因?yàn)檫@種方法可以將任意圖像分類(lèi)網(wǎng)絡(luò)轉(zhuǎn)換成目標(biāo)檢測(cè)模型,如何運(yùn)用這個(gè)方法還是值得好好研究的,從而避免直接訓(xùn)練端到端的深度學(xué)習(xí)目標(biāo)檢測(cè)模型。根據(jù)你的用例,這種方法能為你節(jié)省大量的時(shí)間和精力。
如果你對(duì)這種目標(biāo)檢測(cè)的方法很感興趣,還想了解更多將滑動(dòng)窗口、圖像金字塔和圖像分類(lèi)方法用于目標(biāo)檢測(cè)內(nèi)容,請(qǐng)請(qǐng)參閱我的書(shū),Deep Learning for Computer Vision with Python
方法 2:目標(biāo)檢測(cè)框架的基礎(chǔ)網(wǎng)絡(luò)
深度學(xué)習(xí)目標(biāo)檢測(cè)中的第二種方法,這種方法將事先訓(xùn)練好的分類(lèi)網(wǎng)絡(luò)視為深度學(xué)習(xí)目標(biāo)檢測(cè)框架中的基礎(chǔ)網(wǎng)絡(luò)(比如 Faster R-CNN, SSD, or YOLO )。
這樣做的好處是你可以創(chuàng)建一個(gè)基于深度學(xué)習(xí)的完整的端到端的目標(biāo)檢測(cè)模型。
缺點(diǎn)就是這種方法要求對(duì)深度學(xué)習(xí)目標(biāo)檢測(cè)工作原理有一定的了解,下一節(jié)將對(duì)此加以討論。
▌深度學(xué)習(xí)目標(biāo)檢測(cè)的組成元素
圖 4:VGG16 基礎(chǔ)網(wǎng)絡(luò)是 SSD 深度學(xué)習(xí)目標(biāo)檢測(cè)框架中的一部分
深度學(xué)習(xí)目標(biāo)檢測(cè)模型有很多組件、子組件和二級(jí)子組件,但是,今天我們主要關(guān)注兩點(diǎn),深度學(xué)習(xí)目標(biāo)檢測(cè)新手經(jīng)常混淆的兩點(diǎn):
目標(biāo)檢測(cè)框架(比如 Faster R-CNN, SSD, YOLO);
符合目標(biāo)檢測(cè)框架的基礎(chǔ)網(wǎng)絡(luò)。
你可能已經(jīng)了解基礎(chǔ)網(wǎng)絡(luò),基礎(chǔ)網(wǎng)絡(luò)是我們常見(jiàn)的(分類(lèi)器)卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu),包括:
VGGNet
ResNet
MobileNet
DenseNet
一般來(lái)說(shuō),為了學(xué)習(xí)得到豐富的判別濾波集合,這些用于圖像分類(lèi)的網(wǎng)絡(luò)預(yù)先在大型圖像數(shù)據(jù)集(如 ImageNet)中已經(jīng)訓(xùn)練完成。
目標(biāo)檢測(cè)框架由很多組件和子組件構(gòu)成。
舉例子來(lái)說(shuō),F(xiàn)aster R-CNN 的框架包括:
候選區(qū)域生成網(wǎng)絡(luò) (RPN);
候選窗口集合;
感興趣區(qū)域 ROI pooling 層;
最終基于區(qū)域的卷積神經(jīng)網(wǎng)絡(luò)。
當(dāng)使用 Single Shot Detectors (SSDs) 時(shí),SSD 會(huì)包括如下的組件和子組件:
MultiBox,邊框回歸技術(shù);
Priors,預(yù)先計(jì)算的固定大小的邊框(像 Faster-R-CNN terminology 候選窗口);
Fixed priors,每個(gè)特征圖單元都與不同維度和尺寸默認(rèn)邊框的集合相關(guān)聯(lián)。
記住了,基礎(chǔ)網(wǎng)絡(luò)只是其中一個(gè)符合總體深度學(xué)習(xí)目標(biāo)檢測(cè)框架的組件,在這一節(jié)頂部的圖3中,它描述了 SSD 框架中的作為基礎(chǔ)網(wǎng)絡(luò)的 VGG16。
通常情況下,在基礎(chǔ)網(wǎng)絡(luò)上進(jìn)行修改,這個(gè)修改包括:
將基礎(chǔ)網(wǎng)絡(luò)編排成全卷積形式(即能夠接受任意維度的輸入);
移除基礎(chǔ)網(wǎng)絡(luò)結(jié)構(gòu)中更深的 CONV 和 POOL 層,將它們替換成一系列新的層(SSD)、新的模型(Faster R-CNN)或是兩者的結(jié)合。
術(shù)語(yǔ)“網(wǎng)絡(luò)手術(shù)”是一種口語(yǔ)化的表達(dá),用來(lái)說(shuō)明我們刪減了一些基礎(chǔ)網(wǎng)絡(luò)中的原始層,并插入一些新的層來(lái)取代它們。
你可能看過(guò)低預(yù)算的恐怖電影,電影中的兇手也許攜帶斧子或大刀,攻擊他們的受害者,毫不手軟地攻擊他們。
網(wǎng)絡(luò)手術(shù)比典型的 B 級(jí)恐怖電影中的殺手更加精確和嚴(yán)格。
網(wǎng)絡(luò)手術(shù)很有戰(zhàn)略意義,我們刪除了網(wǎng)絡(luò)中我們不需要的部分,將它替換成一組新的組件。
然后,當(dāng)我們?nèi)ビ?xùn)練框架用于目標(biāo)檢測(cè)時(shí),以下兩項(xiàng)的權(quán)重均已修改(1)新的層和模塊;(2)基本網(wǎng)絡(luò)。
重復(fù)一下,針對(duì)各種深度學(xué)習(xí)目標(biāo)檢測(cè)框架工作原理的完整的回顧(包括基礎(chǔ)網(wǎng)絡(luò)所扮演的角色)已經(jīng)超出了本博客的范圍。如果想深入了解深度學(xué)習(xí)目標(biāo)檢測(cè)的內(nèi)容,包括原理和實(shí) 現(xiàn),請(qǐng)參考我的書(shū)籍,Deep Learning for Computer Vision with Python。
▌如何評(píng)估深度學(xué)習(xí)目標(biāo)檢測(cè)模型的精度?
當(dāng)評(píng)估目標(biāo)檢測(cè)模型的性能時(shí),我們使用的評(píng)價(jià)指標(biāo)是平均精度均值(mAP),mAP是基于我們數(shù)據(jù)集中所有類(lèi)別的交并比(IoU)計(jì)算得到的。
交并比(IoU)
圖 5:在這個(gè)交并比 IoU 的直觀例子中,將真實(shí)值的邊框(綠色)與預(yù)測(cè)的邊框(紅色)進(jìn)行對(duì)比。IoU 與平均精度均值 mAP 一起被用于深度學(xué)習(xí)目標(biāo)檢測(cè)的精度評(píng)估。右邊為用于計(jì)算 IoU 的等式
也許你會(huì)發(fā)現(xiàn) IoU 和 mAP 通常用于評(píng)價(jià) HOG 特征 +線性 SVM 檢測(cè)模型,Haar特征級(jí)聯(lián)分類(lèi)器和基于深度學(xué)習(xí)模型的性能; 然而,記住,實(shí)際上用于生成預(yù)測(cè)邊框的算法并不重要。
任何用來(lái)提供預(yù)測(cè)邊框(以及供參考的類(lèi)標(biāo)簽)作為輸出的算法,這些算法均能是用 IoU 進(jìn)行評(píng)估。更正式地說(shuō),為了使用 IoU 來(lái)評(píng)價(jià)任意一種目標(biāo)檢測(cè)模型,我們需要:
1.真實(shí)值的邊框(也就是,在測(cè)試集中,通過(guò)我們手動(dòng)標(biāo)記的,目標(biāo)對(duì)象所處位置的邊框);
2.來(lái)自我們模型的預(yù)測(cè)邊框;
3.如果你想要計(jì)算召回率和精確率,你還需要真實(shí)值的類(lèi)標(biāo)簽和預(yù)測(cè)值的類(lèi)標(biāo)簽。
在圖 4(左邊)中,我給出了一個(gè)直觀的例子,真實(shí)值的邊框(綠色)與預(yù)測(cè)邊框(紅色)對(duì)比。通過(guò)圖 4(右邊)的等式來(lái)計(jì)算IoU。
審視這個(gè)等式,你會(huì)發(fā)現(xiàn) IoU 是一個(gè)簡(jiǎn)單的比值。
在分子部分,我們計(jì)算的是預(yù)測(cè)邊框與真實(shí)值邊框之間的重疊面積。
分母是并集區(qū)域面積,或者更簡(jiǎn)單地說(shuō),分母是被預(yù)測(cè)邊框和實(shí)際邊框兩者包含的面積。
交集區(qū)域除以并集區(qū)域?qū)⒌玫阶罱K的分?jǐn)?shù),交并比得分。
平均精度均值(mAP)
為了在我們的數(shù)據(jù)集中評(píng)估目標(biāo)檢測(cè)模型的性能,我們需要計(jì)算基于 IoU 的mAP:
基于每個(gè)類(lèi)(也就是每個(gè)類(lèi)的平均精度);
基于數(shù)據(jù)集中的所有類(lèi)別(也就是所有類(lèi)別的平均精度值的平均值,術(shù)語(yǔ)為平均精度均值)
為了計(jì)算每個(gè)類(lèi)的平均精度,對(duì)指定類(lèi)中所有數(shù)據(jù)點(diǎn)計(jì)算它的 IoU。
一旦我們得到了這個(gè)類(lèi)別中用全部數(shù)據(jù)計(jì)算的 IoU,我們就可以計(jì)算該類(lèi)的平均精度(初次均值)。
為了計(jì)算 mAP,我們要計(jì)算所有N個(gè)類(lèi)別中的平均 IoU,然后就可到了 N 個(gè)平均精度的均值(平均精度的均值)。
通常情況下,我們使用 mAP@0.5,mAP@0.5 的意思是在測(cè)試集中,為了使目標(biāo)能夠標(biāo)記為“正檢測(cè)樣本”,這個(gè)目標(biāo)與真實(shí)值的 IoU 值至少必須達(dá)到 0.5(并且被正確標(biāo)記類(lèi)別)。這個(gè) 0.5 值是可以調(diào)整的,但是在大多數(shù)的目標(biāo)檢測(cè)數(shù)據(jù)集和挑戰(zhàn)中,0.5 是標(biāo)準(zhǔn)值。
▌基于 OpenCV 的深度學(xué)習(xí)目標(biāo)檢測(cè)
在以前的博客中,我們已經(jīng)討論了深度學(xué)習(xí)目標(biāo)檢測(cè),完整起見(jiàn),讓我們先來(lái)回顧一下實(shí)際運(yùn)用中的源代碼。
我們的例子中包括 SSD 檢測(cè)器和 MobileNet 基礎(chǔ)網(wǎng)絡(luò)模型。GitHub 用戶 chuanqi305 在 COCO 數(shù)據(jù)集上訓(xùn)練了這個(gè)模型。
讓我們先來(lái)回顧 Ezekiel 的第一個(gè)問(wèn)題,在本文開(kāi)頭就提到的問(wèn)題:
如何過(guò)濾或忽略不感興趣的類(lèi)?
這是個(gè)很好的問(wèn)題,我將用以下樣例腳本來(lái)回答。
但是,首先,需要準(zhǔn)備以下系統(tǒng):
你需要至少在你的 Python 虛擬環(huán)境中安裝 OpenCV 3.3 版本(假設(shè)你使用的是 Python 虛擬環(huán)境)。運(yùn)行以下的代碼需要 OpenCV 3.3 或 3.3 以上的版本中的 DNN 模塊。請(qǐng)選擇下頁(yè)中其中一種 OpenCV 的安裝教程,同時(shí)特別注意你所下載和安裝的 OpenCV 的版本。
同時(shí),你還應(yīng)該安裝我的 imutils 包。想在你的 Python 虛擬環(huán)境中安裝或更新 imutils 包,可以簡(jiǎn)單地使用
pip: pip install --upgrade imutils
準(zhǔn)備好了之后,繼續(xù)創(chuàng)建命名為 filter_object_detection.py 的新文件,然后開(kāi)始:
在 2~8 行中,我們導(dǎo)入了必須的附加包和模塊,特別是 imutils 和 OpenCV 。我將會(huì)用 VideoStream 類(lèi)來(lái)處理從攝像頭捕獲的幀圖像。
我們配備了必須的工具,然后繼續(xù)解析命令行參數(shù):
在運(yùn)行時(shí),我們的腳本需要兩個(gè)命令行參數(shù):
--prototxt:Caffe原型文件的路徑,這個(gè)明確了模型定義;
--model:我們的CNN模型的權(quán)重文件路徑。
.
或者,你可以指定--confidence,過(guò)濾弱檢測(cè)器的閾值。
我們的模型能夠預(yù)測(cè) 21 個(gè)目標(biāo)類(lèi)別:
CLASSES 列表中包括了網(wǎng)絡(luò)訓(xùn)練的所有類(lèi)別( COCO 數(shù)據(jù)集中的標(biāo)簽)
關(guān)于 CLASSES 列表常見(jiàn)的困惑是:
1.在列表中添加新的類(lèi)別;
2.或者,從列表中刪除類(lèi)別。
并能自動(dòng)的讓網(wǎng)絡(luò)“知道”你正在努力完成什么任務(wù)。
事實(shí)并非如此。
你不能通過(guò)對(duì)文本標(biāo)簽簡(jiǎn)單的修改,從而使網(wǎng)絡(luò)通過(guò)自動(dòng)修正后再去學(xué)習(xí)、添加和刪除未經(jīng)過(guò)訓(xùn)練的數(shù)據(jù)模式。神經(jīng)網(wǎng)絡(luò)不是這樣工作的。
這里有一個(gè)快速的竅門(mén),你可以用來(lái)過(guò)濾和忽略你不感興趣的預(yù)測(cè)標(biāo)簽。
解決方案是:
1.定義 IGNORE 標(biāo)簽的集合(用于訓(xùn)練網(wǎng)絡(luò)的標(biāo)簽列表,你想要過(guò)濾和忽略的列表);
2.對(duì)輸入的圖像和視頻幀圖片進(jìn)行預(yù)測(cè);
3.忽略任何包含在 IGNORE 集合中類(lèi)標(biāo)簽的預(yù)測(cè)。
在 Python 中運(yùn)行,IGNORE 集合如下:
在這里,我們將會(huì)忽略所有標(biāo)簽為“人”的預(yù)測(cè)目標(biāo)(用于過(guò)濾的if語(yǔ)句稍后講解)。
在集合中,添加附加的元素(CLASSES 列表中的類(lèi)標(biāo)簽)是很容易的。
接下來(lái),我們將生成隨機(jī)標(biāo)簽和邊框顏色,加載我們的模型,并開(kāi)始 VideoStream:
在第 27 行,生成的 COLORS 的隨機(jī)數(shù)組,被用于對(duì)應(yīng) 21 個(gè) CLASSES。我們將會(huì)用這些顏色進(jìn)行后續(xù)的展示。
在 31 行,我們使用 cv2.dnn.readNetFromCaffe 函數(shù)和我們所需的兩個(gè)命令行參數(shù)作為參數(shù)傳遞加載了的 Caffe 模型。
然后,我們將 VideoStream 目標(biāo)實(shí)例化為 vs,并開(kāi)始我們的 fps 計(jì)數(shù)(第 36~38 行)。2 秒的休眠讓我們的攝像機(jī)有足夠的時(shí)間準(zhǔn)備。
此時(shí),我們準(zhǔn)備好了接收來(lái)自攝像機(jī)的循環(huán)輸入幀圖像,并將這些圖像輸入到 CNN 目標(biāo)檢測(cè)模型中:
在第 44 行,我們讀取圖像并調(diào)整圖片大小,同時(shí)保留顯示的縱橫比(第 45 行)。
在這里,由于后期需要,我們提取了高度和寬度值。
第 48 和 49 行,從幀圖像中生成了 blob。
接下來(lái),我們將 blob 輸入到神經(jīng) net 中,用于目標(biāo)檢測(cè)。(第 54 和 55 行)
讓我們來(lái)循環(huán)遍歷檢測(cè)模型:
在 58 行,我們將開(kāi)始檢測(cè)器的循環(huán)。
在每次檢測(cè)中,我們提取了 confidence(61 行),將它與我們的置信度閾值對(duì)比(第 65 行)。
如果我們的 confidence 大于最小值(默認(rèn)值是 0.2,能夠通過(guò)命令行參數(shù)修改)這個(gè)檢測(cè)結(jié)果將會(huì)被視為正檢測(cè)結(jié)果,有效的檢測(cè)并繼續(xù)進(jìn)一步的處理。
首先,我們提取從檢測(cè)模型中提取了類(lèi)標(biāo)簽的索引(第 68 行)。
然后,回顧 Ezekiel 的第一個(gè)問(wèn)題,我們可以忽略在 IGNORE 集合中的列表,在 72 和 73 行。如果這是屬于被忽略的類(lèi)別,我們將簡(jiǎn)單的繼續(xù)回到檢測(cè)模型的初始循環(huán)階段(我們并不展示這個(gè)類(lèi)別的標(biāo)簽或邊框)。這實(shí)現(xiàn)了“快速破解”解決方案。
否則,我們我們?cè)诎酌麊沃袡z測(cè)到目標(biāo)時(shí),我們需要在幀圖片中顯示這個(gè)目標(biāo)的類(lèi)標(biāo)簽和矩形框:
在這個(gè)代碼模塊中,我們提取邊框坐標(biāo)(第 77 和 78 行),然后,在幀圖片上繪制了類(lèi)標(biāo)簽和矩形框(第 81~87 行)。
同一個(gè)類(lèi)中標(biāo)簽的顏色和矩形框相同,相同類(lèi)別中的目標(biāo)將使用相同的顏色(也就是,視頻中的“船”,都將使用相同顏色標(biāo)簽和邊框)
最后,仍然在 while 循環(huán)中,我們將在屏幕上展示我們努力工作的結(jié)果:
在第 90 和 91 行中,我們顯示了幀圖片,并捕獲按鍵輸入。
如果按下“q”鍵,我們停止并推出循環(huán)(第 94 和 95 行)
否則,我們繼續(xù)更新 fps 計(jì)數(shù)器(98 行),并繼續(xù)提取和處理幀圖片。
在剩下的代碼行中,當(dāng)循環(huán)停止時(shí),我們將顯示時(shí)間和每秒幀數(shù)量度,并清除。
▌運(yùn)行你的深度學(xué)習(xí)目標(biāo)檢測(cè)模型
運(yùn)行腳本,打開(kāi)終端并進(jìn)入到代碼和模型目錄,從那里運(yùn)行接下來(lái)的命令:
圖6:使用相同的模型進(jìn)行實(shí)時(shí)深度學(xué)習(xí)目標(biāo)檢測(cè)演示,在右邊的視頻中,我編程忽略了特定的目標(biāo)類(lèi)別。
在上面的 GIF 中,從左側(cè)你可以看到“人”類(lèi)別被檢測(cè),這是由于我的 IGNORE 集合是空的。在右側(cè),你會(huì)發(fā)現(xiàn)我沒(méi)有被檢測(cè)到,這是因?yàn)閷?“person” 類(lèi)添加到 IGNORE 集合。
雖然我們的深度學(xué)習(xí)目標(biāo)檢測(cè)器從技術(shù)上仍然檢測(cè)“人”的類(lèi)別,但我們后期處理代碼能夠?qū)⑦@個(gè)類(lèi)別過(guò)濾掉。
在運(yùn)行深度學(xué)習(xí)目標(biāo)檢測(cè)模型時(shí)你遇到了錯(cuò)誤?
排除錯(cuò)誤的第一步是檢查你是否連接了攝像頭。如果不是這個(gè)問(wèn)題,也許你會(huì)在終端中看到以下錯(cuò)誤信息:
如果你看到這個(gè)信息,那么是你沒(méi)有將“命令行參數(shù)”傳遞到程序中。如果 PyImageSearch 讀者對(duì) Python、argparse 和命令行參數(shù)不熟悉,這將是他們普遍會(huì)遇到的問(wèn)題。
▌我如何在深度學(xué)習(xí)目標(biāo)檢測(cè)模型中添加和移除類(lèi)?
圖 7:深度學(xué)習(xí)目標(biāo)檢測(cè)模型的微調(diào)和遷移學(xué)習(xí)
正如我在本篇指南中提到的,你不能簡(jiǎn)單的修改 CLASSES 列表來(lái)進(jìn)行類(lèi)標(biāo)簽的添加和刪除,底層網(wǎng)絡(luò)本身并沒(méi)有發(fā)生變化。
你所做的,充其量只是修改一個(gè)類(lèi)標(biāo)簽的文本文件。
反之,如果你想從神經(jīng)網(wǎng)絡(luò)中添加或刪除類(lèi),你需要:
1.重新訓(xùn)練;
2.進(jìn)行微調(diào)。
重新訓(xùn)練往往是耗時(shí)、成本高的操作,所以,我們盡可能的避免重新訓(xùn)練,但在某些情況下,從頭開(kāi)始訓(xùn)練是無(wú)法避免的。
另一種方式是對(duì)網(wǎng)絡(luò)進(jìn)行微調(diào)。
微調(diào)是遷移學(xué)習(xí)的一種形式,微調(diào)可以通過(guò)以下的過(guò)程來(lái)完成:
1.將用于分類(lèi)和標(biāo)記的全連接層移除;
2.將其替換成全新的、隨機(jī)初始化的全連接層。
我們也可以修改網(wǎng)絡(luò)中的其他層(包括凍結(jié)某些層的權(quán)重,在訓(xùn)練過(guò)程中再解凍它們)。
具體如何訓(xùn)練你自定義的深度學(xué)習(xí)目標(biāo)檢測(cè)模型(包括微調(diào)和重新訓(xùn)練),本文不涉及這樣的高級(jí)主題,但是,可以參考以下部分來(lái)幫助你入門(mén)。
▌總結(jié)
在今天的博客中,我大致介紹了涉及深度學(xué)習(xí)目標(biāo)檢測(cè)的復(fù)雜問(wèn)題。我們首先回顧了圖像分類(lèi)和目標(biāo)檢測(cè)的本質(zhì)區(qū)別,包括我們?nèi)绾螌D像分類(lèi)訓(xùn)練的網(wǎng)絡(luò)用于目標(biāo)檢測(cè)。
然后,我們回顧了深度學(xué)習(xí)目標(biāo)檢測(cè)的核心部分:
框架
基礎(chǔ)模型
基礎(chǔ)模型通常是預(yù)先訓(xùn)練好的網(wǎng)絡(luò)(分類(lèi)器),通常是在大型圖像數(shù)據(jù)集中完成訓(xùn)練的,比如 ImageNet ,為的是讓網(wǎng)絡(luò)去學(xué)習(xí)魯棒性的判別過(guò)濾器集合。
我們也可以重新訓(xùn)練基礎(chǔ)網(wǎng)絡(luò),不過(guò)這通常需要訓(xùn)練很長(zhǎng)的時(shí)間,目標(biāo)檢測(cè)模型才能達(dá)到合理的精度。
在大多數(shù)情況下,你應(yīng)該從預(yù)先訓(xùn)練好的基礎(chǔ)模型入手,而不是重新訓(xùn)練。
一旦我們深入了解深度學(xué)習(xí)目標(biāo)檢測(cè)模型之后,我們就可以在 OpenCV 中在運(yùn)行實(shí)時(shí)目標(biāo)檢測(cè)模型。
我還演示了怎樣做才能過(guò)濾或忽略你不感興趣的類(lèi)標(biāo)簽。
最后我們了解到,從深度學(xué)習(xí)目標(biāo)檢測(cè)模型中添加或刪減類(lèi)并不像從硬編碼中的類(lèi)標(biāo)簽列表中添加或刪減類(lèi)標(biāo)簽?zāi)敲慈菀住?/p>
神經(jīng)網(wǎng)絡(luò)本身并不關(guān)心你是否修改了類(lèi)標(biāo)簽列表,相反,你將需要:
修改網(wǎng)絡(luò)結(jié)構(gòu)本身,移除全連接的類(lèi)預(yù)測(cè)層,并進(jìn)行微調(diào);
或者重新訓(xùn)練目標(biāo)檢測(cè)框架。
對(duì)于大多數(shù)深度學(xué)習(xí)目標(biāo)檢測(cè)項(xiàng)目,你將從預(yù)先已在目標(biāo)檢測(cè)任務(wù)(如 COCO )中訓(xùn)練完成的深度學(xué)習(xí)目標(biāo)檢測(cè)模型開(kāi)始,然后,通過(guò)對(duì)模型進(jìn)行微調(diào)獲取你自己的檢測(cè)模型。
-
神經(jīng)網(wǎng)絡(luò)
+關(guān)注
關(guān)注
42文章
4726瀏覽量
100325 -
深度學(xué)習(xí)
+關(guān)注
關(guān)注
73文章
5442瀏覽量
120798
原文標(biāo)題:深度學(xué)習(xí)目標(biāo)檢測(cè)指南:如何過(guò)濾不感興趣的分類(lèi)及添加新分類(lèi)?
文章出處:【微信號(hào):AI_Thinker,微信公眾號(hào):人工智能頭條】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論