动手学CV-目标检测入门教程3:锚框(anchor)
3.3 錨框 or 先驗框
本文來自開源組織 DataWhale 🐳 CV小組創作的目標檢測入門教程。
對應開源項目 《動手學CV-Pytorch》 的第3章的內容,教程中涉及的代碼也可以在項目中找到,后續會持續更新更多的優質內容,歡迎??。
如果使用我們教程的內容或圖片,請在文章醒目位置注明我們的github主頁鏈接:https://github.com/datawhalechina/dive-into-cv-pytorch
3.3.1 關于先驗框
在眾多經典的目標檢測模型中,均有先驗框的說法,有的paper(如Faster RCNN)中稱之為anchor(錨點),有的paper(如SSD)稱之為prior bounding box(先驗框),實際上是一個概念。
那么,為什么要有先驗框這個概念呢?按理說我們的圖片輸入模型,模型給出檢測結果就好了,為什么還要有先驗框?那么關于它的作用,我們不妨回顧一下前面在2.1節所說的那個目標檢測最初的解決方案,我們說,我們要遍歷圖片上每一個可能的目標框,再對這些框進行分類和微調,就可以完成目標檢測任務。
你腦中目前很可能沒有清晰的概念,因為這個描述很模糊,本節介紹的先驗框就是在解決如何定義哪些位置是候選目標框的問題。
接下來需要介紹3個概念:
- 設置不同尺度的先驗框
- 先驗框與特征圖的對應
- 先驗框類別信息的確定
設置不同尺度的先驗框
通常,為了覆蓋更多可能的情況,在圖中的同一個位置,我們會設置幾個不同尺度的先驗框。這里所說的不同尺度,不單單指大小,還有長寬比,如下面的示意圖所示:
同一位置設置多個不同尺度先驗框的可視化可以看到,通過設置不同的尺度的先驗框,就有更高的概率出現對于目標物體有良好匹配度的先驗框(體現為高IoU)。
先驗框與特征圖的對應
除了不同尺度,我們肯定要將先驗框鋪灑在圖片中不同位置上面。
但是遍歷原圖每個像素,設置的先驗框就太多了,完全沒必要。如圖3-13所示。一個224x224的圖片,假設每個位置設置3個不同尺寸的先驗框,那么就有224x224x3=150528個,但是如果我們不去遍歷原圖,而是去遍歷原圖下采樣得到的feature map呢?以vgg16的backbone為例,下采樣了5次,得到7x7的feature map,那就只需要得到7x7x3=147個先驗,這樣的設置大大減少了先驗框的數量,同時也能覆蓋大多數情況。
圖3-13 先驗框數量對比因此,我們就將先驗框的設置位置與特征圖建立一一對應的關系。而且,通過建立這種映射關系,我們可以通過特征圖,直接一次性的輸出所有先驗框的類別信息以及坐標信息,而不是想前面一直描述的那樣,每個候選框都去獨立的進行一次分類的預測,這樣太慢了(閱讀后面的章節后,你將會深刻理解這段話的含義,以及建立這種一一映射的重要意義)。
先驗框類別信息的確定
我們鋪設了很多的先驗框,我們先要給出這些先驗框的類別信息,才能讓模型學著去預測每個先驗框是否對應著一個目標物體。
這些先驗框中有很多是和圖片中我們要檢測的目標完全沒有交集或者有很小的交集,
我們的做法是,設定一個IoU閾值,例如iou=0.5,與圖片中目標的iou<0.5的先驗框,這些框我們將其劃分為背景,Iou>=0.5的被歸到目標先驗框,通過這樣劃分,得到供模型學習的ground truth信息,如圖3-14所示:
圖3-14 先驗框劃分3.3.2 先驗框的生成
這里,我們來結合代碼介紹先驗框是如何生成的,更加具體的先驗框的使用以及一些訓練技巧如先驗框的篩選在后面的章節會進一步的介紹。
model.py 腳本下有一個 tiny_detector 類,是本章節介紹的目標檢測網絡的定義函數,其內部實現了一個 create_prior_boxes 函數,該函數便是用來生成先驗框的。
""" 設置細節介紹: 1. 離散程度 fmap_dims = 7: VGG16最后的特征圖尺寸為 7*7 2. 在上面的舉例中我們是假設了三種尺寸的先驗框,然后遍歷坐標。在先驗框生成過程中,先驗框的尺寸是提前設置好的,本教程為特征圖上每一個cell定義了共9種不同大小和形狀的候選框(3種尺度*3種長寬比=9)生成過程: 0. cx, cy表示中心點坐標 1. 遍歷特征圖上每一個cell,i+0.5是為了從坐標點移動至cell中心,/fmap_dims目的是將坐標在特征圖上歸一化 2. 這個時候我們已經可以在每個cell上各生成一個框了,但是這個不是我們需要的,我們稱之為base_prior_bbox基準框。 3. 根據我們在每個cell上得到的長寬比1:1的基準框,結合我們設置的3種尺度obj_scales和3種長寬比aspect_ratios就得到了每個cell的9個先驗框。 4. 最終結果保存在prior_boxes中并返回。需要注意的是,這個時候我們的到的先驗框是針對特征圖的尺寸并歸一化的,因此要映射到原圖計算IOU或者展示,需要: img_prior_boxes = prior_boxes * 圖像尺寸 """def create_prior_boxes():"""Create the 441 prior (default) boxes for the network, as described in the tutorial.VGG16最后的特征圖尺寸為 7*7我們為特征圖上每一個cell定義了共9種不同大小和形狀的候選框(3種尺度*3種長寬比=9)因此總的候選框個數 = 7 * 7 * 9 = 441:return: prior boxes in center-size coordinates, a tensor of dimensions (441, 4)"""fmap_dims = 7 obj_scales = [0.2, 0.4, 0.6]aspect_ratios = [1., 2., 0.5]prior_boxes = []for i in range(fmap_dims):for j in range(fmap_dims):cx = (j + 0.5) / fmap_dimscy = (i + 0.5) / fmap_dimsfor obj_scale in obj_scales:for ratio in aspect_ratios:prior_boxes.append([cx, cy, obj_scale * sqrt(ratio), obj_scale / sqrt(ratio)])prior_boxes = torch.FloatTensor(prior_boxes).to(device) # (441, 4)prior_boxes.clamp_(0, 1) # (441, 4)return prior_boxes根據上面的代碼,我們得到了先驗框,那么接下來進行一下可視化吧,為了便于觀看,僅展示特征圖中間那個cell對應的先驗框。
這里為了對比,我們設置兩組obj_scales尺度參數。
這里的參數是歸一化的,0.1代表anchor的基準大小為原圖長/寬的0.1那么大。
圖3-15 obj_scales = [0.1, 0.2, 0.3]的先驗框可視化可以看到,我們在圖片中心得到了各個尺度和寬高比的先驗框。
這里對比兩組不同的尺度設置,是想展示一個需要注意的小問題,那就是越界,可以看到第二組可視化部分藍色和綠色的先驗框都超出圖片界限了,這種情況其實是非常容易出現的,越靠近四周的位置的先驗框越容易越界,那么這個問題怎么處理呢?這里我們一般用圖片尺寸將越界的先驗框進行截斷,比如某個先驗框左上角坐標是(-5, -9),那么就截斷為(0,0),某個先驗框右下角坐標是(324,134),當我們的圖片大小為(224,224)時,就將其截斷為(224,134)。
對應于代碼中是這行,prior_boxes.clamp_(0, 1),由于進行了歸一化,所以使用0-1進行截斷。
3.3.3 小結
以上就是關于先驗框生成的全部內容,先驗框是目標檢測中一個非常非常重要的概念,因此單獨拿出來一小節進行介紹。
關于先驗框,在訓練時,還有一些技巧需要掌握,后面的章節中會有所提及。
下一節將要進入最重點的部分了,模型設計以及結構的講解。愿各位能夠耗子尾汁,再接再厲,好好學習。
總結
以上是生活随笔為你收集整理的动手学CV-目标检测入门教程3:锚框(anchor)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php红色字体颜色,php生成文字颜色渐
- 下一篇: Guice之Servlet基础