圖森技術匯 | 聊聊Anchor的"前世今生"(上)

巖歸正傳發表於2020-06-13

正如大家所見,最近一段時間各種所謂anchor-free的detection演算法得到了很多的關注,我其實是一個非常不願意蹭熱點的人,技術上的東西更願意“讓子彈飛一會”,再發表看法。所以今天在這裡,我們先來談談各種對於anchor based detection方法中anchor設定的改進。在正式開始介紹這些改進之前,先先來介紹一些我理解的anchor,以及它在detection系統中發揮的作用。

首先,我想說的第一個觀點是絕大多數top-down detector都是在做某種意義上的refinement和cascade區別無外乎在於,refine的次數以及每次refine的方法。在傳統方法中從無論sliding window出發,不斷去篩選正樣本;還是後續使用Selective search或者Edgebox直接生成proposal都是基於這樣的思路。後續基於Deep learning的方法也沒有走出這個套路,在one stage演算法中,主流的方法便是在refine預先指定的anchor;在two stage演算法中,試圖使用RPN來替代sliding window或者其他生成proposal的方法,再透過提取的region feature來refine這些proposal。

anchor這個概念最早出現在Faster RCNN的paper中,如果能理解前面提到的內容,其實anchor就是在這個cascade過程中的起點。由於在Faster RCNN那個年代還沒有FPN這種顯式處理scale variation的辦法,anchor的一大作用便是顯式列舉出不同的scale和aspect ratio。原因也很簡單,只使用一個scale的feature map和同一組weight,要去預測出所有scale和aspect ratio的目標,本身就是很困難的一件事。透過anchor的引入,將scale和aspect ratio進行劃分,針對某個特定的區間和組合,使用一組特定學習到的weight去處理,從而緩解這個問題。需要注意的是,anchor本身並不會參與到網路的運算中去,影響的只會是classification和bbox regression分支的target(訓練階段)和怎樣decode box(測試階段)。換句話說,網路其實預測的是相對於anchor的offset,只有在最終從offset轉換到bbox時,才會使用。這樣的想法也很自然被各種One stage方法所吸收,形成了anchor已經是detection標配的stereotype。說了這麼多為什麼現在anchor free的方法又捲土重來了呢?這個問題我會在下一篇文章中講講我個人的看法,下面言歸正傳,我們來看看這些嘗試去學習和最佳化anchor的方法都具體做了什麼。

在這幾篇文章中,想法最為直接的是[1],想要解決的問題也最為簡單,就是在一個dataset上,我怎麼選擇anchor shape。注意,在這個工作中區別於後續幾個工作,學習出來的anchor是在整個dataset上共享的。一般而言,對於anchor shape的設定,除了手工拍拍腦袋隨意設定幾個scale和aspect ratio之外,對於ground-truth bbox進行一次聚類也是一個常用的方法。在[1]中,作者就是希望減少這部分hand-crafted的工作(雖然還是使用了kmeans作為初始化...)。具體做法也是非常地直接和直觀,由於anchor shape在One stage方法中隻影響bbox regression分支,我們可以在bbox regression的loss中,把anchor也作為一個最佳化的變數,求導最佳化。具體細節就不再贅述,有興趣的讀者可以參照原文。另外一些同時期的工作,在這個基礎上更進一步,希望能夠得到每張圖,甚至是對於feature map上每個位置上都有不同的adaptive anchor,也可以針對不同的dataset泛化效能更強。MetaAnchor[2]算是在這個方向是最早的一個嘗試。MetaAnchor希望從一些預設定的anchor出發,有可能再結合上影像本身的feature,生成一組新的anchor weight。如下圖所示:

圖森技術匯 | 聊聊Anchor的"前世今生"(上)

注意,在這裡其實生成的並不是refine過的anchor本身,而是直接用於classification和bbox regression分支的weight。這也就是為什麼這個工作叫做MetaAnchor的原因,因為這個思想其實源自於meta learning。具體實現上,生成函式G的選取就直接選擇為兩層的MLP,分別有依賴於影像自身的feature和不依賴於影像自身的feature的兩種形式,即:

圖森技術匯 | 聊聊Anchor的"前世今生"(上)

其中theta*為所有anchor共享的weight。b_i為anchor box自身的表示,作者在文中直接選擇了normalized過的長和寬這兩維作為anchor的feature。x很直接,即為這個feature map對應位置上的feature。回到上面整體的觀點上看,MetaAnchor其實是implicit地多做了一次refinement,只不過不是explicit地生成了新的anchor,而是直接生成了對應的weight。下一個要介紹的工作[3]雖然介紹的motivation看上去和anchor本身無關,但實際的做法也算是某種refinement。在這裡,我來講一講我自己的看法,而不再重複paper中講的故事,有興趣的讀者可以直接參閱作者本人的解讀:https://zhuanlan.zhihu.com/p/55416312。個人理解,這篇工作其實最想做的是在One stage的框架內,實現了一個兩級的Cascade refinement。但是由於不像two stage的方法,可以透過region features來直接align anchor和提取出的feature,作者在文中嘗試了下圖(b)(c)(d)三種實現方式,測試得到的最終結果類似,便使用了最直接的辦法:兩個stage共享同一個head,使用一樣的feature,直接去做兩次預測。如下圖。

圖森技術匯 | 聊聊Anchor的"前世今生"(上)

其中和原始的RetinaNet的區別在於,在分類和迴歸的兩支上,分別加入對第一次refine之後的新anchor設定新的training target:

圖森技術匯 | 聊聊Anchor的"前世今生"(上)

在分類的分支上,可以認為同樣的一個預測(注意兩個term裡都是c_i)有兩個監督訊號,一個是原始anchor對應的label,一個是第一次refine過後的anchor對應的label。在迴歸分支上略有區別的是這兩次refinement對應的regression weight不等,也就是兩個term中一個是t_i^0,一個是t_i^1。個人覺得最起碼迴歸這個branch的方法更合理一些,在這個分類branch中兩個輸入都不變,在cascade不同層之間只是變化anchor,也就是訓練的target,這看上去是一個比較wired的方案。不過,作者在實驗中也證明了,哪怕只訓練refine之後的label,仍然可以得到可觀的效能提升。最後一個要介紹的工作Guided Anchor算是我個人覺得在這幾篇工作中完成度最高的一篇。同樣,作者本人也有自己介紹過這個工作:https://zhuanlan.zhihu.com/p/55854246

圖森技術匯 | 聊聊Anchor的"前世今生"(上)

整個方法分為兩個大的部分,第一部分是Anchor generation,這個部分並沒有太多特別的地方,可以認為是一個特殊的RPN,分別預測這個位置是否存在物體,和以這個位置為中心的anchor的長和寬。和RPN的區別在於,沒有中心點的迴歸,關於為什麼這麼做,作者自己在上面知乎專欄中已有回覆。第二部分是Feature adaptation,個人覺得這是一個非常重要的模組,試圖解決one stage中一個核心的問題:anchor和其對應的feature怎樣align?這裡作者的方案是Feature adaptation模組。作者使用生成的anchor的shape來預測給Deformable Conv使用的offset,這樣可以使用deformable conv來aggregate anchor內的feature,可以算是某種簡化版本的region feature。透過這個辦法,使得最終預測的feature map和實際的anchor scale相關。

另外這篇文章中,比較有意思的一點是探究了對於two stage的方法,怎樣使用更好的proposal?也就是說怎樣把proposal中更高的recall轉換成最終detection結果中的precision。這裡作者給出了一些經驗:1) 使用更少的proposal訓練。 2) 使用更高的正樣本IoU threshold。簡單來說,在recall更高的時候,我們應該讓後續的任務變得更“簡單”和“專注”一些,這樣避免一些困難樣本對detection head的影響。雖然沒有特別深入探究這個現象的原因,但這個發現也是很有指導意義的。

總結一下,除了第一篇工作以外,我們都可以從一個統一的視角下來理解這個事情:1) 用盡量低的代價,在one stage detector或者是two stage生成proposal的過程中引入一次額外的refinement,anchor其實只是refine這件事情的一個載體。2) 在detection的head上,有兩個輸入,即輸入的feature和對應的網路weight,決定一個輸出,即前面提到的和anchor相關的分類和迴歸目標,即變化了anchor其實變化的話head的輸出。後三篇文章中,都變化了輸出,但是對於輸入的處理不同:MetaAnchor中變化的是weight,GuidedAnchor中,透過feature adaptation變化了輸入的feature,Consistent optimization中全部固定。希望講了這麼多,能夠幫助大家更好地理解這一系列的工作。下一篇當然是會來講講最近火爆的Anchor free方法啦,敬請期待!

[1] Zhong, Y., Wang, J., Peng, J., & Zhang, L. (2018). Anchor Box Optimization for Object Detection. arXiv preprint arXiv:1812.00469.

[2] Yang, T., Zhang, X., Li, Z., Zhang, W., & Sun, J. (2018). Metaanchor: Learning to detect objects with customized anchors. In NIPS2018.

[3] Kong, T., Sun, F., Liu, H., Jiang, Y., & Shi, J. (2019). Consistent Optimization for Single-Shot Object Detection. arXiv preprint arXiv:1901.06563.

[4] Wang, J., Chen, K., Yang, S., Loy, C. C., & Lin, D. (2019). Region proposal by guided anchoring. In CVPR2019.

相關文章