1. 程式人生 > 其它 >目標檢測兩個基礎部分——backbone and detection head

目標檢測兩個基礎部分——backbone and detection head

轉自:《目標檢測》-第2章-Backbone與Detection head

  這裡簡單介紹以下目標檢測網路構成的兩個基礎部分:Backbone 和 Detection head.

圖一,目標檢測網路的兩個重要組成部分:backbone 和 detection head

一,Backbone 和 Detection head

  通常,為了實現從影象中檢測目標的位置和類別,我們會先從影象中提取些必要的特徵資訊,比如HOG特徵,然後利用這些特徵取實現定位和分類。而在深度學習這一塊,backbone部分的網路就是負責從影象中提取特徵。當然,這裡提出的是什麼樣的特徵,我們是無從得知的,畢竟深度學習的“黑盒子”特性至今還無法真正將其面紗揭開。

  那麼,如何取設計一個backbone取提取影象中的特徵呢?

  從某種意義上來說,如何設計好的backbone,更好地從影象中提取資訊,是至關重要地,特徵提取不好,自然會影響到後續的定位檢測。早在目標檢測任務之前,深度學習技術就已經在影象分類領域中發揮了重大的作用,大力促進了這一領域的發展,尤其是在ResNet系列的工作問世後,影象分類任務幾乎達到了一個頂峰——從ImageNet比賽不再舉辦這一點就可以窺見一斑。雖然後續這個領域還在陸陸續續地出現些新工作(如GhostNet,ShuffleNet,ResNet各種升級版本,EfficientNet家族等),提供了很多新的idea,不過基本上已經不再是當年那種百花齊放的盛況了。

  深度學習技術能夠這麼出色的完成影象分類任務,基本上驗證了其在影象特徵提取這一塊的出色表現和巨大潛力。

  現在,讓我們將注意力拉到我們的主人翁來——目標檢測。

  考慮到在目標檢測任務重,也需要對影象中的物體進行類別的識別。因此,一個很直接的想法就是將影象分類的網路拿過來。不過,目標檢測除了需要分類,更重要的一點是在於定位,而這一點恰恰是分類任務的網路所不具備的。

  因此,直接使用影象分類的網路做目標檢測似乎在原理上就存在問題。

  隨著遷移學習概念的興起和普及,遷移+微調這一概念成熟,因此,通過在檢測任務中的資料集上對分類網路進行微調似乎是一個很不錯的想法——所謂的“ImageNet pretrained model”概念就誕生了。簡單地來說,就是目標檢測和影象分類這兩個任務具有一定地相似性,因為可以將分類的網路,比如VGG, ResNet等,用來做特徵提取器。這一部分,我們就稱其為backbone。也許它們對影象中目標的位置不夠敏感,但至少它們能夠提取圖片中目標的類別特徵。

  另一方面,在深度學習領域中,有監督學習仍然是主流,儘管這些年諸如自監督、半監督等方興未艾,仍然難以撼動有監督學習的第位。既然如此,資料量變成了要給不得不考慮的一個點。然而,不幸的是,目標檢測領域不存在類似ImageNet這麼龐大的資料庫(那時候COCO和Object365都還沒有放出來)。這一點也使得“與訓練+遷移+微調”這一路子成為了必然。

  而問題的關鍵就在於“遷移學習+微調”的“工藝”了。

  前面提到了backbone網路這一字眼,所謂的backbone,直接翻譯過來就是“骨幹”,很明顯,這個單詞的含義就表明了它並不是整體的網路。既然兩個任務具有相似性,再加上遷移學習思想的普及,為什麼還會要用這麼個單詞來描述它呢?事實上,儘管OD和影象分類兩個任務具有相似性,但不完全是等價的,OD的目標是實現對物體的定位和分類,而影象分類僅僅是對影象中的物體進行分類,而不會去定位。於時,就在“定位”這一點上,完全將分類網路搬過來使用顯然是不恰當的(準確來說,是將ImageNet上訓練的引數直接載入進來,作為初始引數再去微調是不恰當的,而不是網路模型本身,網路模型本身只是個架構,完全可以隨機初始化去訓練的。因為在ImageNet上訓練出來的引數已經掉進了分類任務的一個區域性最優點,那麼在不改變現有模型任何架構——不增加網路層也不刪減網路層——的情況下,通過這種區域性最優點在OD任務上是否合適呢?或者說,模型能通過微調就跳出這個“舊”的極值點走進“新”的極值點嗎?我難以下個普適的定論。僅根據我個人經驗,這個過程比較困難。

  從優化目標上來看,分類任務只做分類,而OD還需要做定位,因此,任務驅動不同,目標不同,因此,完全有理由相信二者的優化空間有很大的差異。所以,僅僅是微調網路是無法完成OD任務的,當然,這一點,我們會在後續的實踐來驗證的。

  那麼該怎麼辦?

  解決的辦法相當簡單,既然僅僅靠分類網路的引數是不行的,但是我們還需要它(那時候的資料量和訓練tricks還不足以有效直撐train from scratch),那麼我們就在後面加一些(訓練時隨機初始化的)網路層,讓這些額外加進來的網路層去彌補分類網路無法定位的先天缺陷。

  於是,這條脈絡就非常清晰了:分類網路遷移過來,用作特徵提取器,後續的網路負責從這些特徵中,檢測目標的位置和類別。當然,兩部分會合到一起在OD資料集上去訓練,使得它提取出來的特徵更適合OD任務。那麼,我們九江分類網路所在的環節稱之為“Backbone”也就是情理之中的了。而後續連線的網路層由於主要是服務於detection任務,因此稱之為“Detection head”。

  隨著技術的發展,除了backbone和head這兩部分,更多的新奇的技術和模組被提了出來,最著名的,莫過於FPN了——《Feature Pyramid Networks for Object Detection》提出的FPN接面構,在不同的尺度(實際上就是不同大小的feature map)上去提取不同尺度的資訊,並進行融合,充分利用好backbone提取的所有的特徵資訊,從而讓網路能夠更好的檢測物體。有了FPN, backbone提取出的資訊可以被利用的更加充分,使得detector能夠很好的應對多尺度情況——影象中,目標的大小不一,大的、中等的、小的都有,尤其是小物體,幾乎成為了目標檢測這一塊的單獨研究點。

  除了FPN這種新穎的結構,還有諸如ASFF、RFB、SPP等好用的模組,都可以插在backbone和detection head之間。由於其插入的位置的微妙,故而將其稱之為“neck”,有些文章中直接把它翻譯成“瓶頸”或“脖子”,無論哪種翻譯,都怪怪的,沒內味兒……neck這部分的作用就是更好地融合/提取backbone所給出的feature,然後再交由後續的head去檢測,從而提高網路的效能。因此,現在一個完整的目標檢測網路主要由三部分構成:detector=backbone+neck+head

  最後再說一點backbone。

  隨著目標檢測領域的興起,越來越多的學者和研究員意識到了這一領域中資料集匱乏的弊端,故而既老舊的VOC之後,微軟的COCO、曠世Object365,以及其他的該領域資料集,陸續地放了出來。有了充足的資料量,似乎Pretrain on ImageNet就不是必需環節了,遷移+微調也可以省掉了。於是,train from scratch的路線就回來了。注意,這裡用的是“回來”,因為這一路線是很樸素的,甚至不值得掛在嘴邊。網路引數隨機初始化去訓練本就是個基本操作,而imagenet pretrained model能在OD領域中盛行,主要還是因為OD本身資料就不夠,外加大家還有點捨不得ImageNet這麼豐富的影象資料庫。當然,也是因為不是每個人都有足夠的算力去支撐train from scratch的,這點是不容忽視的~

  儘管現在學術界已經知道了不用那些在ImageNet上預訓練的模型作為backbone,而是自己搭建backbone網路或者使用隨機初始化的分類網路,也能夠達到同樣的效果,但是這樣的代價就是需要花更多的實踐來訓練,如何對資料進行預處理也是要注意的,換句話說,給調參帶來了更多的壓力。關於這一點,感興趣的讀者可以閱讀Kaming He的《Rethinking ImageNet Pre-training》。

  即便如此,大家還是會優先使用預訓練模型,畢竟省時省力。不是每個人都有那麼充足的算力去調參的。backbone這部分可以說很大程度上決定了detector的效能,所以,這部分的研究意義也很大,不過,很吃GPU這點還是很現實的,畢竟要先在imagenet上去pretrain一下,這就花不少時間,然後再替換現有的detector的backbone網路,去COCO上訓練看漲點否,這又得花一大把時間……

PS:原部落格評論中作者回答的問題很經典:

  Q:大的方面總結的很好,但是從現在的時間來看,總結的都有點過時了。這兩年又出了好多新的網路和論文,雖然骨幹網路沒多大變化,但是各種模組和tricks的結合,又不斷刷高了map。我搜到這裡的目的是想知道head裡面到底是什麼,因為看到一篇頂會在討論全連線head和卷積head。另外看到文中寫到的關於backbone的說法,提到分類網路和檢測網路的區別,為什麼說分類網路不能直接適用於檢測網路呢?分類網路不是也要對影象中的各類目標進行查詢並根據特徵進行類識別嗎?為什麼說沒有定位呢?是不是說沒有精確的定位的意思?而現在目標檢測的目的肯定是要進行定位和分類識別的,所以兩者都要兼顧?是這個意思嗎?

  A:1,的確,如您所說,從我最初寫完這篇文章到現在,有了很多新的工作,不過,我沒有跟蹤技術發展不斷更新此文的目的就是因為我認為當下的絕大多數OD網路還是在backbone+neck+head的這個框架,儘管這裡面有了好多新module和新trick,但我認為沒有影響到我對這個框架的大的方面的總結。倒是Facebook出的基於transformer做detection 的新思路,我倒一直想單開一章,不過,也是無暇顧及此事了,實屬遺憾~我這文章充其量也不過是入門之作,必須承認,憑我自己的閱歷和水平,還是難以做到與時俱進的更新,還望見諒!

    2,關於head,其實,把整個15年到19年的頂會工作放到一塊揣摩揣摩,不難發現,對於head其實並沒有backbone這麼明確:使用imagenet pretrained model。head這一部分,簡單來看就是在backbone部分給出的feature map上做detection任務,為了增加效能,head之前又多了neck部分,整合那些feature map,然後再交由head。所以,head其實就是負責輸出detection結果的那些卷積層,看很多程式碼裡,也都是把這部分註釋為head。舉個例子,YOLOv3或YOLOv4,都是先用neck部分的FPN(+SPP)將backbone輸出的三個feature map進行融合,然後再依次接了若干卷積層去在每一個feature map上輸出conf,class,bbox。所以,head到底是什麼也就不言而喻了,但是很明顯,對於head部分大家都沒有太關注,這些年大部分的改進都是集中在backbone和neck兩部分,沒有在意head,而我覺得,head很重要,前兩者的作用在於整合出更好的特徵,但head才是決定能否將這些特徵轉換為我們真正需要的bbox引數和class引數。另外,head部分是用全連線更好還是卷積更好呢?我的想法是:全連線可以從全域性感受野中來對影象中的物體進行一個檢測,而卷積的那種視窗等價於滑動視窗,只關注區域性資訊,這個區域性就是感受野,也就是在“數格子”,一個格子一個格子去看。那麼二者哪個更好呢?實在抱歉,我無法解答。

    3. 分類網路不適用於做detection,指的是隻載入imagenet pretrained的weight,不新增額外的網路層,只對最後一層的輸出做下處理(畢竟現在是detection嘛,得帶上bbox一起了)。這麼做,我在實際中就發現,很難學出好的網路,原因我想大概是分類任務上的權重已經進入了一個區域性極小值,這個值在detection的優化空間又處於一個很差的位置,怎麼finetune也難。但是呢,我們不用預訓練權重,直接隨機初始化,然後去學習,那就沒問題了。所以,準確來說,分類網路本身可以做detection(要把輸出層引數稍稍修改下~),但imagenet上的預訓練權重做不好detection,必須新增一些額外的層,而這些層,我認為,就是得到bbox即定位的關鍵。

    4.誠如你所說,分類網路本身也是有“定位”能力的,對於一張影象,它會在要分類的那個物體所處的區域有大的響應,別的地方相對要小,但是問題就在於,分類網路是全域性感受野,它這種響應不會有某種平移恆變性,比如一隻貓在一張圖的各個位置都出現了,分類網路做不到在這些位置都有響應,也就很難泛化到我們想要的定位了,也就是您說的“精確定位”,即bbox的引數。這個gap的原因還是分類任務和detection任務二者之間的區別帶來的,沒辦法,無法抹除這個gap,不然這倆就成一個任務了~因此呢,為了能夠實現滿足detection任務的精確定位,就得新增幾層卷積了。

  Q:Training from Scratch 到目前2021.6為止,CNN的目標檢測依然是大資料集從頭練,小資料集預訓練。最新的一篇浙大關於預訓練的論文,剛剛閱讀完,在COCO上表現可以,VOC差了一大截。

  A:現在(2021年)來看,在COCO上從頭訓練已經不是什麼新鮮事了,因為COCO資料集本身規模足夠大,往往train from scratch會獲得更好的效能,像v5已經都是這麼做了。VOC就是差在了資料量上,不過也無所謂,畢竟VOC基本上也沒啥用了。對於新手來說,或者自身沒有充足計算裝置的研究者來說,預訓練仍舊是個廉價而有效的方案。