????? 最近在預研一些anchor-free算法,想要把anchor給Free掉,我們總得先知道什么是anchor吧,畢竟知己知彼,百戰不殆。
1.Anchor是啥?
anchor字面意思是錨,是個把船固定的東東(上圖),anchor在計算機視覺中有錨點或錨框,目標檢測中常出現的anchor box是錨框,表示固定的參考框。
目標檢測是"在哪里有什么"的任務,在這個任務中,目標的類別不確定、數量不確定、位置不確定、尺度不確定。傳統非深度學習方法和早期深度學習方法,都要金字塔多尺度+遍歷滑窗的方式,逐尺度逐位置判斷"這個尺度的這個位置處有沒有認識的目標",這種窮舉的方法非常低效。
最近SOTA的目標檢測方法幾乎都用了anchor技術。首先預設一組不同尺度不同位置的anchor,覆蓋幾乎所有位置和尺度,每個anchor負責檢測與其交并比大于閾值 (訓練預設值,常用0.5或0.7) 的目標,anchor技術將問題轉換為"這個固定參考框中有沒有認識的目標,目標框偏離參考框多遠",不再需要多尺度遍歷滑窗,真正實現了又好又快,如在Faster R-CNN和SSD兩大主流目標檢測框架及擴展算法中anchor都是重要部分。
YOLOV1作為Anchor-Free的鼻祖之一,但是作者在v2版本就替換為anchor方法;”真是刺雞“,最近檢測的方向返璞歸真,又往Anchor-Free方向發展?我在YOLOv3中加入了YOLOv1的思想,實現Anchor-Free,發現效果沒有下降卻略有提升,這個激發了我對Anchor的一些思考。
anchor的思想有點近似SPP(spatial pyramid pooling)思想的逆向。而SPP本身是做什么的呢,就是將不同尺寸的輸入resize成為相同尺寸的輸出。所以SPP的逆向就是,將相同尺寸的輸出,倒推得到不同尺寸的輸入。首先明確anchor的位置。anchor是在原圖上的區域,而不是在特征圖上(也就是特征圖上一個點可以對應到原圖上一個n*n的區域)
但是!但是!但是!這種說法是有瑕疵的!
原因不難理解,anchor的設置,導致其在圖像中對應的尺寸和長寬比例是各種各樣的,有的甚至還超過了滑動窗口的 3x3 輸入的感受野的范圍。如果說一塊 feature map 通過網絡的學習,只關注感受野內某一塊區域的信息,這個是合理的;而不是像SPP逆向說的那樣,我們能從9塊不同區域得到特征!anchor 可能比感受野大,也可能比感受野小,如果 anchor 比感受野大,就相當于只看到了我關心的區域(anchor)的一部分(感受野),通過部分判斷整體,如果比感受野小,那就是我知道比我關心的區域更大的區域的信息,判斷其中我關心的區域是不是物體。(這里說的是Faster—RCNN里面的anchor)
Anchor的作用:
上文說的是通過RPN網絡中設置的Anchor,現在檢測研究的主流方向主要在one—stage方法(畢竟我們要快快快)。one-stage里面設置anchor的方式可能與上文的不一樣,但是我們只需要了解Anchor的意義就能舉一反三啦。
anchor主要有兩個作用:1、anchor作為回歸任務中的初始框,這樣網絡就只需要學習初始框和GT之間的坐標偏移量和高寬縮放量,從而簡化網絡的回歸任務。可以解決GT的平移問題,我覺得這個是anchor最大的作用,如果不用anchor而直接預測GT的絕對中心坐標和絕對高寬,或者直接預測GT的絕對左上角坐標和右下角坐標,我覺得是學不出來的,比如說,圖片中有兩個在不同位置,但是卻具有相同類別相同高寬的GT,由于卷積是是共享權重的,所以卷積過后這兩個GT對應的卷積輸出應該是相同的,也就是說從這兩個GT提取的特征應該是相同的,但是如果根據這兩個相同的特征向量去學習不同的目標,那么就矛盾了,這樣就無法學習了。2.有了 anchor,就可以把不同尺寸的目標分配到對應的 anchor 上,這樣對應 anchor的網絡權值就僅僅負責一個比較小的目標尺寸范圍(幾個值就能代表原圖上的一個區域),同時學習過程中,是顯式的通過不同的分支、路徑來傳遞不同尺寸目標的loss,讓網絡更加符合“邏輯”的得到訓練。
綜上所述:anchor作用無非兩點:容易是模型快速收斂,容易找到目標大小和對應的feature map。anchor本身并不會參與到網絡的運算中去,影響的只會是classification和bbox regression分支的target(訓練階段)和怎樣decode box(測試階段)。換句話說,網絡其實預測的是相對于anchor的offset,只有在最終從offset轉換到bbox時,才會使用。這樣的想法也很自然被各種One stage方法所吸收,將achor幾乎成為標配!
anchor的作用非常非常神奇,在網絡運算過程中它是不存在的,但是它就像一張無形的手
Anchor的思考:
(1)Anchor的匹配
目標在那個anchor是簡單粗暴的,按照誰的IOU大就歸誰的方法劃分.而且 anchor 本身的尺寸、比例也是人工指定的,雖然與不同level的featuremap有一定的關系,但并沒有和網絡結構的設計有良好的耦合(雖然 anchor可以通過數據集的聚類來獲得(YOLO),但是這也只是單方面的與數據集有了耦合),實際中往往一個目標適合兩個或多個anchor,是不是可以用一種更加平滑的方法來加權,而非簡單粗暴的0-1選擇。
(2)Anchor的放置
目前FPN架構在檢測網絡模型中使用的很多,anchor的放置位置也需要思考。大家廣泛認為網絡深層因為感受野較大,通常用來檢測大物體(放大anchor);淺層感受野較小,所以通常用來檢測小物體(放小anchor),anchor的生成是根據feature map不同而定義的。在anchor match gt階段,gt與anchor匹配,確定gt歸屬于哪些anchor,這個過程隱式的決定了gt會由哪層feature map負責預測。不管是生成anchor還是gt match 過程,都是由size這個變量決定,雖然我們會設定先驗的規則來選擇最好的feature map,但存在的問題是,僅僅利用size來決定哪些feature map來檢測物體是一種不精確的做法。如下圖所示,60x60大小的car和50x50大小的car被分在了不同feature map,50x50和40x40的被分在了同一級feature map,咱也不知道,這樣好不好,那么何不讓模型自動學習選擇合適的feature 去做預測呢?(CVPR2019 FSAF針對這一問題)
目前的Anchor-Free算法很多就是不用錨框改成錨點了,個人感覺就是換了個形式的anchor。不管怎么說,期待效果吧,畢竟anchor用了很多年也需要換換了。