????????本文將根據(jù) Mask R-CNN 和 Faster R-CNN 論文以及 TensorFlow 實(shí)現(xiàn)的 目標(biāo)檢測(cè) 來(lái)詳細(xì)的解析通過(guò) R-CNN 方法來(lái)進(jìn)行目標(biāo)檢測(cè)的原理(使用 TensorFlow 訓(xùn)練目標(biāo)檢測(cè)器請(qǐng)參考 TensorFlow 訓(xùn)練自己的目標(biāo)檢測(cè)器)杠人。
????????如下圖所示,我們想要知道圖像中有哪些目標(biāo)(人、風(fēng)箏等)担忧,知道了存在的目標(biāo)之后倍奢,還想知道這些目標(biāo)在圖像中的哪個(gè)位置(左上角捶闸、右下角等)拷沸。知道這些信息延届,在實(shí)際中的某些任務(wù)上很有幫助椭符,比如荔燎,在自動(dòng)駕駛中,通過(guò)攝像頭傳回的圖像销钝,可以檢測(cè)出前方是否存在行人有咨、車(chē)輛等障礙物,而且可以計(jì)算出離他們的距離蒸健。目標(biāo)檢測(cè)的目的即是從一張給定的圖像中檢測(cè)出固定種類(lèi)的目標(biāo)以及定位這些目標(biāo)在圖像的位置(如圖中的綠色邊框座享、橙色邊框)。因此似忧,目標(biāo)檢測(cè)包含兩個(gè)子任務(wù):分類(lèi)和定位渣叛,既要識(shí)別目標(biāo)的類(lèi)別,又要定位目標(biāo)的位置盯捌。
????????上圖充分說(shuō)明了目標(biāo)檢測(cè)的難度淳衙。主要難度有:1.一張圖像中的可識(shí)別的目標(biāo)可能很多,很難在識(shí)別準(zhǔn)確的基礎(chǔ)上不漏掉其中一些目標(biāo)饺著;2.目標(biāo)尺度變化很大滤祖,很難兼顧大尺度目標(biāo)和小尺度目標(biāo);3.目標(biāo)之間可能存在重疊瓶籽、遮擋匠童、形變等復(fù)雜關(guān)系。相比之下塑顺,下圖的檢測(cè)過(guò)程就容易很多汤求,因?yàn)橹话粋€(gè)目標(biāo),而且目標(biāo)清晰严拒,但即便如此扬绪,最后的定位(黑框)精度也不甚理想。
????????我們知道識(shí)別目標(biāo)屬于哪個(gè)類(lèi)別是一個(gè)分類(lèi)任務(wù)裤唠,最終只需要賦予這個(gè)目標(biāo)一個(gè)類(lèi)標(biāo)號(hào)(0, 1, 2, 3, ...)或類(lèi)名(人挤牛、車(chē)、貓种蘸、狗墓赴、......)即可【荷牛現(xiàn)在我們想知道的是:要怎么來(lái)表達(dá)定位結(jié)果?正如你看到(想到)的一樣诫硕,用一個(gè)包含目標(biāo)的邊框來(lái)表達(dá)目標(biāo)的定位位置坦辟,通常可以用邊框的左上角章办、右下角的坐標(biāo)锉走,即 (ymin, xmin)、(ymax, xmax)藕届,或者中心坐標(biāo)以及寬高挪蹭,即 (xc, yc)、w休偶、h 這兩種方式來(lái)表示目標(biāo)的位置(見(jiàn)上面兩圖)嚣潜。
????????目標(biāo)檢測(cè)不同于分類(lèi)任務(wù)的關(guān)鍵在于:所面臨的圖像中可識(shí)別的目標(biāo)可能不止一個(gè),而且還可以是零個(gè)椅贱,這就使得通常的分類(lèi)網(wǎng)絡(luò)不能直接應(yīng)用于目標(biāo)檢測(cè)懂算,但使用分類(lèi)網(wǎng)絡(luò)進(jìn)行特征提取卻是通用的技巧。當(dāng)前庇麦,常用的目標(biāo)檢測(cè)算法包括:1.單階段算法:YOLO 系列计技,SSD 系列;2.雙階段算法:R-CNN系列山橄。本文主要講解 R-CNN 系列垮媒,特別是 Faster R-CNN。
一航棱、Faster R-CNN 思想
????????我們已經(jīng)知道目標(biāo)檢測(cè)包含兩個(gè)任務(wù)睡雇,分別是定位和分類(lèi)。因?yàn)橐粡垐D像中可能包含 0 個(gè)或 多 個(gè)目標(biāo)饮醇,因此目標(biāo)檢測(cè)與單純的分類(lèi)任務(wù)存在本質(zhì)的區(qū)別它抱。但如果先從圖像中把所有的目標(biāo)都單獨(dú)分割出來(lái),形成分割出來(lái)的圖像中有且僅有一個(gè)目標(biāo)朴艰,則此時(shí)就將原任務(wù)轉(zhuǎn)化成了一個(gè)單純的分類(lèi)問(wèn)題观蓄。這就是 R-CNN 論文最原始的思想。因?yàn)榫哂羞壿嬌系南群箨P(guān)系:先分割出目標(biāo)祠墅,然后再對(duì)分割出的目標(biāo)分類(lèi)侮穿,因此 R-CNN 算法是一個(gè)兩階段的算法。此時(shí)毁嗦,目標(biāo)檢測(cè)的核心問(wèn)題在于:1.怎么將目標(biāo)從圖像中分割出來(lái)亲茅;2.怎么對(duì)分割的目標(biāo)進(jìn)行識(shí)別。因?yàn)?2 是一個(gè)單純的分類(lèi)問(wèn)題,已經(jīng)有很多成熟的算法克锣,所以目標(biāo)檢測(cè)的關(guān)鍵問(wèn)題是:怎么從圖像中分割目標(biāo)茵肃?
????????分割目標(biāo)其實(shí)不是一件容易的事,原因有二:1.目標(biāo)數(shù)量娶耍、尺度和位置都是任意變化的,分割要做到不遺漏饼酿,特別是要做到不加入無(wú)效的背景區(qū)域很困難榕酒。這里涉及到一個(gè)技術(shù)問(wèn)題,即:從圖像中分割出的一個(gè)區(qū)域要怎么判定它包含可識(shí)別的目標(biāo)(即目標(biāo)區(qū)域)或不包含目標(biāo)(即背景區(qū)域)故俐?一個(gè)下意識(shí)的想法也許是:這不是一個(gè)二分類(lèi)任務(wù)嗎想鹰?確實(shí)是一個(gè)二分類(lèi)任務(wù)!把所有可識(shí)別的目標(biāo)都泛化成一個(gè)大類(lèi)药版,比如叫正類(lèi)(類(lèi)標(biāo)號(hào)為 1)辑舷,所有背景為另一個(gè)類(lèi),比如負(fù)類(lèi)(類(lèi)標(biāo)號(hào)為 0)槽片,判斷一個(gè)分割區(qū)域是否為目標(biāo)區(qū)域就成了一個(gè)典型的二分類(lèi)問(wèn)題何缓。分類(lèi)問(wèn)題都是簡(jiǎn)單的,因此目標(biāo)檢測(cè)的關(guān)鍵問(wèn)題再次被簡(jiǎn)化还栓,現(xiàn)在的關(guān)鍵問(wèn)題是:怎么從圖像中獲取分割區(qū)域碌廓?這就引出了分割目標(biāo)困難的第二個(gè)原因:2.要高效的對(duì)圖像進(jìn)行區(qū)域分割,也很困難剩盒,困難之處在于高效谷婆,即:在分割區(qū)域數(shù)量盡可能少的情況下,不遺漏所有可識(shí)別的目標(biāo)辽聊。一個(gè)最原始的分割區(qū)域的方式是滑動(dòng)窗口算法纪挎,幾乎是以一種窮竭的方法把所有子區(qū)域都從圖像中分割出來(lái)了,但是顯然它不夠高效跟匆。
????????R-CNN 最先使用的分割方法是選擇搜索(Selective Search)异袄,基本思想是:先用圖像分割的方法把圖像分割成充分多的足夠小的區(qū)域,然后根據(jù)相鄰區(qū)域的相似性(包括顏色玛臂、紋理隙轻、尺寸、空間交疊等相似性度量)不斷的合并小區(qū)域垢揩,直至所有的小區(qū)域合并成整張圖像為止玖绿,記錄下此過(guò)程中的所有中間結(jié)果(包括最開(kāi)始的小區(qū)域),這些區(qū)域就是最終用于二分類(lèi)判定是否是目標(biāo)區(qū)域的數(shù)據(jù)集合叁巨。這個(gè)過(guò)程依舊很慢斑匪,但比起滑動(dòng)窗口算法還是快很多。
????????現(xiàn)在可以來(lái)縱觀一下上面所述的目標(biāo)檢測(cè)算法的整個(gè)流程了(如下圖所示):對(duì)給定的一張圖像,首先使用 選擇搜索 算法分割出數(shù)量較多的子區(qū)域(包括 目標(biāo)區(qū)域 和 背景區(qū)域)蚀瘸,然后使用 CNN 二分類(lèi)算法從所有子區(qū)域中分離出所有(疑似)目標(biāo)區(qū)域狡蝶,接著使用 CNN 對(duì)所有(疑似)目標(biāo)區(qū)域做最后的分類(lèi),得到檢測(cè)結(jié)果贮勃。你是否會(huì)問(wèn)贪惹,以上過(guò)程只是處理了分類(lèi)任務(wù),那么定位任務(wù)呢寂嘉?實(shí)際上奏瞬,定位在分割這一步隱式的實(shí)現(xiàn)了,因?yàn)楫?dāng)你從原圖像中分割一個(gè)矩形子區(qū)域時(shí)泉孩,勢(shì)必已經(jīng)知道這個(gè)矩形區(qū)域相對(duì)于原圖像的像素位置(比如硼端,你必須知道這個(gè)矩形區(qū)域的左上角,以及寬高寓搬,才能裁剪出這個(gè)區(qū)域)珍昨。(之所以帶 【疑似】 兩字,是因?yàn)榉诸?lèi)算法都不是 100% 準(zhǔn)確的)
????????以上過(guò)程實(shí)際上可以做一些簡(jiǎn)化句喷,合并分割之后的 二分類(lèi) 和 分類(lèi) 這兩步镣典,就是 R-CNN 論文的整體檢測(cè)框架。二分類(lèi)這一步實(shí)際上是不需要的唾琼,因?yàn)榫退阕隽诉@一步也無(wú)法保證所有判定的目標(biāo)區(qū)域就都是真的目標(biāo)區(qū)域(而不會(huì)完全不存在噪聲的背景區(qū)域)骆撇,因此后續(xù)的 分類(lèi) 過(guò)程,還是必須引入除了 可識(shí)別目標(biāo)類(lèi)別 之外的一個(gè)額外類(lèi)別:背景父叙,還不如直接對(duì)所有分割出來(lái)的矩形區(qū)域進(jìn)行 可識(shí)別目標(biāo)類(lèi)別 + 背景類(lèi)別 分類(lèi)神郊。這樣,R-CNN 算法的步驟為:1.從圖像中分割矩形區(qū)域趾唱;2.對(duì)矩形區(qū)域分類(lèi)(類(lèi)別數(shù)量 = 可識(shí)別目標(biāo)類(lèi)別數(shù)量 + 1涌乳,多出來(lái)的一個(gè)類(lèi)別為背景)。這里甜癞,之所以畫(huà)蛇添足引入一個(gè)二分類(lèi)過(guò)程夕晓,除了邏輯上自然之外,還因?yàn)楹竺嬷攸c(diǎn)講解的 Faster R-CNN 算法中存在這一步悠咱。
????????接下來(lái)蒸辆,我們從上述流程來(lái)分析一下 R-CNN 算法的缺點(diǎn)。以上分析所知析既,大體上躬贡,R-CNN 算法分兩步:1.分割子區(qū)域;2.對(duì)子區(qū)域分類(lèi)眼坏》鞑#基于此,明顯的缺點(diǎn)如下:
- 不是端到端的模型。R-CNN 算法中檐蚜,分割子區(qū)域使用的是傳統(tǒng)的圖像分割方法魄懂,所有子區(qū)域分割出來(lái)后,統(tǒng)一縮放到固定尺寸闯第,然后使用卷積神經(jīng)網(wǎng)絡(luò)對(duì)這些區(qū)域進(jìn)行分類(lèi)市栗。顯然,以上兩步的處理是割裂的咳短,分別使用了兩種不同的模型(算法)填帽,并不是一個(gè)端到端的模型(指從輸入一步到位到最終的輸出)。另外诲泌,第一步的傳統(tǒng)圖像分割方法是在 CPU 上進(jìn)行的盲赊,非常耗時(shí)(相對(duì)于后續(xù)的卷積神經(jīng)網(wǎng)絡(luò)運(yùn)行在 GPU 上)铣鹏,也是一個(gè)大缺陷敷扫。
- 需要存儲(chǔ)中間結(jié)果。這個(gè)缺點(diǎn)是由第一個(gè)缺點(diǎn)直接導(dǎo)致的诚卸,因?yàn)榍昂蟛襟E是割裂的葵第,因此為了進(jìn)行后續(xù)的操作,勢(shì)必要存儲(chǔ)前一階段的結(jié)果合溺,所造成的直接影響是必須要花費(fèi)巨大的存儲(chǔ)空間卒密。
- 重復(fù)提取卷積特征。這是因?yàn)榈谝徊椒指畛鰜?lái)的矩形區(qū)域棠赛,很多都是相互重疊的哮奇,即每個(gè)矩形區(qū)域都或多或少的與其他很多矩形區(qū)域存在共同的部分,當(dāng)對(duì)它們進(jìn)行分類(lèi)時(shí)睛约,這些公共部分被重復(fù)的送進(jìn)卷積神經(jīng)網(wǎng)絡(luò)鼎俘,從而相同的卷積特征被重復(fù)的提取,造成巨大的計(jì)算消耗辩涝。
????????聰明的讀者想必已經(jīng)想到贸伐,改進(jìn) R-CNN 可以從兩點(diǎn)入手:1.改造 R-CNN 使其成為端到端的模型;2.減少怔揩,甚至避免特征被重復(fù)提取捉邢。按照 R-CNN 系列論文發(fā)表順序來(lái)看,2 要比 1 簡(jiǎn)單商膊,因?yàn)?2 對(duì)應(yīng)的 Fast R-CNN 要比 1 對(duì)應(yīng)的 Faster R-CNN 發(fā)表更早伏伐。
????????接下來(lái)來(lái)看 Fast R-CNN。Fast R-CNN 承襲了 R-CNN 的框架晕拆,旨在減少重復(fù)提取圖像特征秘案。R-CNN 特征提取重復(fù)的原因是直接把從圖像中分割的區(qū)域傳入卷積神經(jīng)網(wǎng)絡(luò),這樣當(dāng)分割的區(qū)域超過(guò)一定數(shù)量之后(R-CNN 實(shí)際裁剪數(shù)量約為 2000),區(qū)域與區(qū)域之間的重疊程度會(huì)很?chē)?yán)重阱高,即同一區(qū)域被包含在很多分割區(qū)域內(nèi)赚导,直接導(dǎo)致同一區(qū)域的特征被不斷的反復(fù)提取。問(wèn)題的關(guān)鍵在于:R-CNN 在分割圖像后赤惊,對(duì)所有子區(qū)域直接提取特征:即先從圖像中分割子區(qū)域吼旧,然后將子區(qū)域送入 CNN 中,這樣只要子區(qū)域與子區(qū)域有交集未舟,這個(gè)交集就會(huì)先后兩次進(jìn)入 CNN 造成重復(fù)圈暗。解決的辦法是:先對(duì)全圖一次性提取特征,然后分割出各子區(qū)域?qū)?yīng)的特征裕膀,即先將整張圖像送入 CNN 中提取特征员串,然后根據(jù)子區(qū)域相對(duì)于全圖像的位置來(lái)計(jì)算對(duì)應(yīng)區(qū)域在全圖像特征中的位置,直接從全圖像特征中裁剪出子區(qū)域?qū)?yīng)的特征昼扛,然后使用這個(gè)特征進(jìn)行第二階段的分類(lèi)寸齐。
????????Fast R-CNN 在處理第二階段的分類(lèi)任務(wù)時(shí)顯然更合理,計(jì)算量得到非常大的削減抄谐,計(jì)算速度得到非常大的提升渺鹦。此時(shí),因?yàn)榉诸?lèi)的卷積神經(jīng)網(wǎng)絡(luò)是 GPU 上運(yùn)行的蛹含,耗時(shí)極少毅厚,整個(gè)目標(biāo)檢測(cè)過(guò)程中時(shí)間基本消耗在第一階段的圖像分割上。為了解決耗時(shí)問(wèn)題浦箱,一個(gè)很直接的方法是:將運(yùn)行在 CPU 上的圖像分割過(guò)程遷移到 GPU 上吸耿,這樣只需要工程手段即可,但顯然這不是研究人員想要的酷窥。