<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          目標檢測入門和實現(xiàn)思路!

          共 5470字,需瀏覽 11分鐘

           ·

          2020-12-26 17:25

          ↑↑↑關注后"星標"Datawhale
          每日干貨?&?每月組隊學習,不錯過
          ?Datawhale干貨?
          作者:徐和鼎,浙江大學,Datawhale優(yōu)秀學習者
          本文講解了目標檢測的基本概念,分析了實現(xiàn)目標檢測的常用思路。下一篇將介紹目標檢測經典數(shù)據(jù)集—VOC數(shù)據(jù)集的基本信息,和對VOC數(shù)據(jù)集進行處理的方法。

          一、目標檢測基本概念

          1. 什么是目標檢測

          目標檢測是計算機視覺中的一個重要任務,近年來傳統(tǒng)目標檢測方法已經難以滿足人們對目標檢測效果的要求,隨著深度學習在計算機視覺任務上取得的巨大進展,目前基于深度學習的目標檢測算法已經成為主流。

          相比較于基于深度學習的圖像分類任務,目標檢測任務更具難度,具體區(qū)別如下圖所示。

          圖像分類:只需要判斷輸入的圖像中是否包含感興趣物體。

          目標檢測:需要在識別出圖片中目標類別的基礎上,還要精確定位到目標的具體位置,并用外接矩形框標出。

          分類和目標檢測任務示意圖

          2. 目標檢測常用思路

          自2012年Alex Krizhevsky憑借Alex在ImageNet圖像分類挑戰(zhàn)賽中拿下冠軍之后,深度學習在圖像識別尤其是圖像分類領域開始大放異彩,大眾的視野也重新回到深度神經網絡中。緊接著,不斷有更深更復雜的網絡出現(xiàn),一再刷新ImageNet圖像分類比賽的記錄。

          大家發(fā)現(xiàn),通過合理的構造,神經網絡可以用來預測各種各樣的實際問題。于是人們開始了基于CNN的目標檢測研究, 但是隨著進一步的探索大家發(fā)現(xiàn),似乎CNN并不善于直接預測坐標信息。并且一幅圖像中可能出現(xiàn)的物體個數(shù)也是不定的,模型如何構建也比較棘手。

          因此,人們就想,如果知道了圖中某個位置存在物體,再將對應的局部區(qū)域送入到分類網絡中去進行判別,那我不就可以知道圖像中每個物體的位置和類別了嗎?

          但是,怎么樣才能知道每個物體的位置呢?顯然我們是沒辦法知道的,但是我們可以去猜?。∷^猜,其實就是通過滑窗的方式,羅列圖中各種可能的區(qū)域,一個個去試,分別送入到分類網絡進行分類得到其類別,同時我們會對當前的邊界框進行微調,這樣對于圖像中每個區(qū)域都能得到(class,x1,y1,x2,y2)五個屬性,匯總后最終就得到了圖中物體的類別和坐標信息。

          總結一下我們的這種方案思路:先確立眾多候選框,再對候選框進行分類和微調。

          觀察下圖,更形象的理解下這種思想:

          從分類角度去看目標檢測

          3. 目標框定義方式

          任何圖像任務的訓練數(shù)據(jù)都要包括兩項,圖片和真實標簽信息,通常叫做GT。

          圖像分類中,標簽信息是類別。目標檢測的標簽信息除了類別label以外,需要同時包含目標的位置信息,也就是目標的外接矩形框bounding box。

          用來表達bbox的格式通常有兩種,(x1, y1, x2, y2) 和 (c_x, c_y, w, h) ,如圖所示:

          目標框定義方式

          之所以使用兩種不同的目標框信息表達格式,是因為兩種格式會分別在后續(xù)不同場景下更加便于計算。

          兩種格式互相轉換的實現(xiàn)在utils.py中,代碼也非常簡單:

          def xy_to_cxcy(xy):
          """
          Convert bounding boxes from boundary coordinates (x_min, y_min, x_max, y_max) to center-size coordinates (c_x, c_y, w, h).

          :param xy: bounding boxes in boundary coordinates, a tensor of size (n_boxes, 4)
          :return: bounding boxes in center-size coordinates, a tensor of size (n_boxes, 4)
          """

          return torch.cat([(xy[:, 2:] + xy[:, :2]) / 2, # c_x, c_y
          xy[:, 2:] - xy[:, :2]], 1) # w, h


          def cxcy_to_xy(cxcy):
          """
          Convert bounding boxes from center-size coordinates (c_x, c_y, w, h) to boundary coordinates (x_min, y_min, x_max, y_max).

          :param cxcy: bounding boxes in center-size coordinates, a tensor of size (n_boxes, 4)
          :return: bounding boxes in boundary coordinates, a tensor of size (n_boxes, 4)
          """

          return torch.cat([cxcy[:, :2] - (cxcy[:, 2:] / 2), # x_min, y_min
          cxcy[:, :2] + (cxcy[:, 2:] / 2)], 1) # x_max, y_max

          用torch.cat()將兩個形狀為(n,2)的tensor在第一維度拼接成(n,4)。

          4. 交并比(IoU)

          在目標檢測任務中,關于IOU的計算貫穿整個模型的訓練測試和評價過程,是非常非常重要的一個概念,其目的是用來衡量兩個目標框的重疊程度。

          IoU的全稱是交并比(Intersection over Union),表示兩個目標框的交集占其并集的比例。下圖為IOU計算示意圖:

          IOU計算示意圖

          圖中可以看到,分子中黃色區(qū)域為紅bbox和綠bbox的交集,分母中黃+紅+綠區(qū)域為紅bbox和綠bbox的并集,兩者之比即為iou。

          那么具體怎么去計算呢?這里給出計算流程的簡述:

          • 首先獲取兩個框的坐標,紅框坐標: 左上(red_x1, red_y1), 右下(red_x2, red_y2),綠框坐標: 左上(green_x1, green_y1),右下(green_x2, green_y2)
          • 計算兩個框左上點的坐標最大值:(max(red_x1, green_x1), max(red_y1, green_y1)), 和右下點坐標最小值:(min(red_x2, green_x2), min(red_y2, green_y2))
          • 利用2算出的信息計算黃框面積:yellow_area
          • 計算紅綠框的面積:red_area 和 green_area
          • iou = yellow_area / (red_area + green_area - yellow_area)

          如果文字表述的不夠清晰,就再看下代碼:

          def find_intersection(set_1, set_2):
          """
          Find the intersection of every box combination between two sets of boxes that are in boundary coordinates.

          :param set_1: set 1, a tensor of dimensions (n1, 4)
          :param set_2: set 2, a tensor of dimensions (n2, 4)
          :return: intersection of each of the boxes in set 1 with respect to each of the boxes in set 2, a tensor of dimensions (n1, n2)
          """


          # PyTorch auto-broadcasts singleton dimensions
          lower_bounds = torch.max(set_1[:, :2].unsqueeze(1), set_2[:, :2].unsqueeze(0)) # (n1, n2, 2)
          upper_bounds = torch.min(set_1[:, 2:].unsqueeze(1), set_2[:, 2:].unsqueeze(0)) # (n1, n2, 2)
          intersection_dims = torch.clamp(upper_bounds - lower_bounds, min=0) # (n1, n2, 2)
          return intersection_dims[:, :, 0] * intersection_dims[:, :, 1] # (n1, n2)


          def find_jaccard_overlap(set_1, set_2):
          """
          Find the Jaccard Overlap (IoU) of every box combination between two sets of boxes that are in boundary coordinates.

          :param set_1: set 1, a tensor of dimensions (n1, 4)
          :param set_2: set 2, a tensor of dimensions (n2, 4)
          :return: Jaccard Overlap of each of the boxes in set 1 with respect to each of the boxes in set 2, a tensor of dimensions (n1, n2)
          """


          # Find intersections
          intersection = find_intersection(set_1, set_2) # (n1, n2)

          # Find areas of each box in both sets
          areas_set_1 = (set_1[:, 2] - set_1[:, 0]) * (set_1[:, 3] - set_1[:, 1]) # (n1)
          areas_set_2 = (set_2[:, 2] - set_2[:, 0]) * (set_2[:, 3] - set_2[:, 1]) # (n2)

          # Find the union
          # PyTorch auto-broadcasts singleton dimensions
          union = areas_set_1.unsqueeze(1) + areas_set_2.unsqueeze(0) - intersection # (n1, n2)

          return intersection / union # (n1, n2)

          以上代碼位于utils.py腳本的find_intersection和find_jaccard_overlap。

          • 函數(shù) find_intersectionfind_intersection(set_1, set_2) 是求形狀為 (n1,4) 和 (n2,4) 的boxes的交集的面積。set_1[:, :2]的形狀為(n1,2),后面加上.unsqueeze(1),形狀變?yōu)?n1,1,2)。同理set_2[:, :2].unsqueeze(0) ,形狀為(1,n2,2)。

            (n1,1,2)和(1,n2,2),作了torch.max,有廣播存在,(n1,1,2)變成(n1,n2,2) ,(1,n2,2)也變成(n1,n2,2)。因此得到了形狀為(n1,n2,2)的框的左上角坐標 那個2 就是儲存了x1,y1。

            torch.clamp()是將函數(shù)限制在最大值和最小值范圍內,如果超過就變成那個最大值或者最小值。這里min=0,意思是如果面積小于0,那么面積取0(排除異常)。

          • 函數(shù)find_jaccard_overlap計算iou,交集/并集,最后union計算, ?升維 (n1)->(n1,1) ? ?、 ?(n2)->(1,n2) ? 、 接下去相加,廣播成(n1,n2),減去一個(n1,n2)的交集面積,得到并集面積。

          5. 小結

          本小節(jié)首先介紹了目標檢測的問題背景,隨后分析了一個實現(xiàn)目標檢測的解決思路,這也是眾多經典檢測網絡所采用的思路(即先確立眾多候選框,再對候選框進行分類和微調)。最后介紹了bbox和IoU這兩個目標檢測相關的基本概念。

          下一篇將會從數(shù)據(jù)入手,介紹下目標檢測領域最常見的一個數(shù)據(jù)集VOC,以及數(shù)據(jù)讀取相關的代碼。


          “干貨學習,三連
          瀏覽 106
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级特黄AA片 | 中文字幕国产在线 | 天天日天天色天天干 | 影音先锋在线成人视频 | 做爱视频毛片 |