零基礎入門深度學習(八 ):目標檢測基礎概念

 

 

 

授課講師 | 孫高峯 百度深度學習技術平臺部資深研發工程師

授課時間 | 每週2、週四晚20:00-21:00php

編輯整理 | 孫高峯python

內容來源 | 百度飛槳深度學習集訓營ios

 

01算法

導讀網絡

本課程是百度官方開設的零基礎入門深度學習課程,主要面向沒有深度學習技術基礎或者基礎薄弱的同窗,幫助你們在深度學習領域實現從0到1+的跨越。從本課程中,你將學習到:架構

  1. 深度學習基礎知識app

  2. numpy實現神經網絡構建和梯度降低算法函數

  3. 計算機視覺領域主要方向的原理、實踐學習

  4. 天然語言處理領域主要方向的原理、實踐測試

  5. 個性化推薦算法的原理、實踐

百度深度學習技術平臺部資深研發工程師孫高峯,繼續爲你們講解計算機視覺中目標檢測任務,今天給你們帶來的是目標檢測的基礎概念。

02

目標檢測概述

對計算機而言,可以「看到」的是圖像被編碼以後的數字,但它很難解高層語義概念,好比圖像或者視頻幀中出現目標的是人仍是物體,更沒法定位目標出如今圖像中哪一個區域。目標檢測的主要目的是讓計算機能夠自動識別圖片或者視頻幀中全部目標的類別,並在該目標周圍繪製邊界框,標示出每一個目標的位置,如 圖1 所示。
 


圖1:圖像分類和目標檢測示意圖

  • 圖1(a)是圖像分類任務,只需識別出這是一張斑馬的圖片。

  • 圖1(b)是目標檢測任務,不只要識別出這是一張斑馬的圖片,還要標出圖中斑馬的位置。

03

目標檢測發展歷程

在上一節中咱們學習了圖像分類處理基本流程,先使用卷積神經網絡提取圖像特徵,而後再用這些特徵預測分類機率,根據訓練樣本標籤創建起分類損失函數,開啓端到端的訓練,如 圖2 所示。
 


圖2:圖像分類流程示意圖

但對於目標檢測問題,按照 圖2 的流程則行不通。由於在圖像分類任務中,對整張圖提取特徵的過程當中沒能體現出不一樣目標之間的區別,最終也就無法分別標示出每一個物體所在的位置。

爲了解決這個問題,結合圖片分類任務取得的成功經驗,咱們能夠將目標檢測任務進行拆分。假設咱們如今有某種方式能夠在輸入圖片上生成一系列可能包含物體的區域,這些區域稱爲候選區域,在一張圖上能夠生成不少個候選區域。而後對每一個候選區域,能夠把它單獨當成一幅圖像來看待,使用圖像分類模型對它進行分類,看它屬於哪一個類別或者背景(即不包含任何物體的類別)。

上一節咱們學過如何解決圖像分類任務,使用卷積神經網絡對一幅圖像進行分類再也不是一件困難的事情。那麼,如今問題的關鍵就是如何產生候選區域?好比咱們可使用窮舉法來產生候選區域,如圖3所示。
 


圖3:候選區域

A爲圖像上的某個像素點,B爲A右下方另一個像素點,A、B兩點能夠肯定一個矩形框,記做AB。

  • 如圖3(a)所示:A在圖片左上角位置,B遍歷除A以外的全部位置,生成矩形框A1B1, …, A1Bn, …

  • 如圖3(b)所示:A在圖片中間某個位置,B遍歷A右下方全部位置,生成矩形框AkB1, …, AkBn, …

當A遍歷圖像上全部像素點,B則遍歷它右下方全部的像素點,最終生成的矩形框集合{AiBj}將會包含圖像上全部能夠選擇的區域。

只要咱們對每一個候選區域的分類足夠的準確,則必定能找到跟實際物體足夠接近的區域來。窮舉法也許能獲得正確的預測結果,但其計算量也是很是巨大的,其所生成的總的候選區域數目約爲 ,假設 ,總數將會達到 個,如此多的候選區域使得這種方法幾乎沒有什麼實用性。可是經過這種方式,咱們能夠看出,假設分類任務完成的足夠完美,從理論上來說檢測任務也是能夠解決的,亟待解決的問題是如何設計出合適的方法來產生候選區域。

科學家們開始思考,是否能夠應用傳統圖像算法先產生候選區域,而後再用卷積神經網絡對這些區域進行分類?

  • 2013年,Ross Girshick 等人於首次將CNN的方法應用在目標檢測任務上,他們使用傳統圖像算法selective search產生候選區域,取得了極大的成功,這就是對目標檢測領域影響深遠的區域卷積神經網絡(R-CNN)模型。

  • 2015年,Ross Girshick 對此方法進行了改進,提出了Fast RCNN模型。經過將不一樣區域的物體共用卷積層的計算,大大縮減了計算量,提升了處理速度,並且還引入了調整目標物體位置的迴歸方法,進一步提升了位置預測的準確性。

  • 2015年,Shaoqing Ren 等人提出了Faster RCNN模型,提出了RPN的方法來產生物體的候選區域,這一方法裏面再也不須要使用傳統的圖像處理算法來產生候選區域,進一步提高了處理速度。

  • 2017年,Kaiming He 等人於提出了Mask RCNN模型,只須要在Faster RCNN模型上添加比較少的計算量,就能夠同時實現目標檢測和物體實例分割兩個任務。

以上都是基於R-CNN系列的著名模型,對目標檢測方向的發展有着較大的影響力。此外,還有一些其餘模型,好比SSD、YOLO(1, 2, 3)、R-FCN等也都是目標檢測領域流行的模型結構。

R-CNN的系列算法分紅兩個階段,先在圖像上產生候選區域,再對候選區域進行分類並預測目標物體位置,它們一般被叫作兩階段檢測算法。SSD和YOLO算法則只使用一個網絡同時產生候選區域並預測出物體的類別和位置,因此它們一般被叫作單階段檢測算法。因爲篇幅所限,本章將重點介紹YOLO-V3算法,並用其完成林業病蟲害數據集中的昆蟲檢測任務,主要涵蓋以下內容:

  • 圖像檢測基礎概念:介紹與目標檢測任相關的基本概念,包括邊界框、錨框和交併比等。

  • 林業病蟲害數據集:介紹數據集結構及數據預處理方法。

  • YOLO-V3目標檢測模型:介紹算法原理,及如何應用林業病蟲害數據集進行模型訓練和測試。

04

目標檢測基礎概念

在介紹目標檢測算法以前,先介紹一些跟檢測相關的基本概念,包括邊界框、錨框和交併比等。

邊界框(bounding box)

檢測任務須要同時預測物體的類別和位置,所以須要引入一些跟位置相關的概念。一般使用邊界框(bounding box,bbox)來表示物體的位置,邊界框是正好能包含住物體的矩形框,如 圖4 所示,圖中3我的分別對應3個邊界框。
 

圖4:邊界框

一般有兩種格式來表示邊界框的位置:

  1. xyxy,即 ,其中 是矩形框左上角的座標, 是矩形框右下角的座標。圖4中3個紅色矩形框用xyxy格式表示以下:

  • 左:

  • 中:

  • 右:

  1. xywh,即 ,其中 是矩形框中心點的座標,w是矩形框的寬度,h是矩形框的高度。

在檢測任務中,訓練數據集的標籤裏會給出目標物體真實邊界框所對應的 ,這樣的邊界框也被稱爲真實框(ground truth box),如 圖4 所示,圖中畫出了3我的像所對應的真實框。模型會對目標物體可能出現的位置進行預測,由模型預測出的邊界框則稱爲預測框(prediction box)。


注意:

  1. 在閱讀代碼時,請注意使用的是哪種格式的表示方式。

  2. 圖片座標的原點在左上角,x軸向右爲正方向,y軸向下爲正方向。


要完成一項檢測任務,咱們一般但願模型可以根據輸入的圖片,輸出一些預測的邊界框,以及邊界框中所包含的物體的類別或者說屬於某個類別的機率,例如這種格式:  ,其中L是類別標籤,P是物體屬於該類別的機率。一張輸入圖片可能會產生多個預測框,接下來讓咱們一塊兒學習如何完成這樣一項任務。

錨框(Anchor)

錨框與物體邊界框不一樣,是由人們假想出來的一種框。先設定好錨框的大小和形狀,再以圖像上某一個點爲中心畫出矩形框。在下圖中,以像素點[300, 500]爲中心可使用下面的程序生成3個框,如圖中藍色框所示,其中錨框A1跟人像區域很是接近。

# 畫圖展現如何繪製邊界框和錨框import numpy as npimport matplotlib.pyplot as pltimport matplotlib.patches as patchesfrom matplotlib.image import imreadimport math
# 定義畫矩形框的程序    def draw_rectangle(currentAxis, bbox, edgecolor = 'k', facecolor = 'y', fill=False, linestyle='-'):    # currentAxis,座標軸,經過plt.gca()獲取    # bbox,邊界框,包含四個數值的list, [x1, y1, x2, y2]    # edgecolor,邊框線條顏色    # facecolor,填充顏色    # fill, 是否填充    # linestype,邊框線型    # patches.Rectangle須要傳入左上角座標、矩形區域的寬度、高度等參數    rect=patches.Rectangle((bbox[0], bbox[1]), bbox[2]-bbox[0]+1, bbox[3]-bbox[1]+1, linewidth=1,                           edgecolor=edgecolor,facecolor=facecolor,fill=fill, linestyle=linestyle)    currentAxis.add_patch(rect)

plt.figure(figsize=(10, 10))
filename = '/home/aistudio/work/images/p3/000000086956.jpg'im = imread(filename)plt.imshow(im)
# 使用xyxy格式表示物體真實框bbox1 = [214.29, 325.03, 399.82, 631.37]bbox2 = [40.93, 141.1, 226.99, 515.73]bbox3 = [247.2, 131.62, 480.0, 639.32]
currentAxis=plt.gca()
draw_rectangle(currentAxis, bbox1, edgecolor='r')draw_rectangle(currentAxis, bbox2, edgecolor='r')draw_rectangle(currentAxis, bbox3,edgecolor='r')
# 繪製錨框def draw_anchor_box(center, length, scales, ratios, img_height, img_width):    """    以center爲中心,產生一系列錨框    其中length指定了一個基準的長度    scales是包含多種尺寸比例的list    ratios是包含多種長寬比的list    img_height和img_width是圖片的尺寸,生成的錨框範圍不能超出圖片尺寸以外    """    bboxes = []    for scale in scales:        for ratio in ratios:            h = length*scale*math.sqrt(ratio)            w = length*scale/math.sqrt(ratio)             x1 = max(center[0] - w/2., 0.)            y1 = max(center[1] - h/2., 0.)            x2 = min(center[0] + w/2. - 1.0, img_width - 1.0)            y2 = min(center[1] + h/2. - 1.0, img_height - 1.0)            print(center[0], center[1], w, h)            bboxes.append([x1, y1, x2, y2])
    for bbox in bboxes:        draw_rectangle(currentAxis, bbox, edgecolor = 'b')
img_height = im.shape[0]img_width = im.shape[1]        draw_anchor_box([300., 500.], 100., [2.0], [0.5, 1.0, 2.0], img_height, img_width)

################# 如下爲添加文字說明和箭頭###############################
plt.text(285, 285, 'G1', color='red', fontsize=20)plt.arrow(300, 288, 30, 40, color='red', width=0.001, length_includes_head=True, \         head_width=5, head_length=10, shape='full')
plt.text(190, 320, 'A1', color='blue', fontsize=20)plt.arrow(200, 320, 30, 40, color='blue', width=0.001, length_includes_head=True, \         head_width=5, head_length=10, shape='full')
plt.text(160, 370, 'A2', color='blue', fontsize=20)plt.arrow(170, 370, 30, 40, color='blue', width=0.001, length_includes_head=True, \         head_width=5, head_length=10, shape='full')
plt.text(115, 420, 'A3', color='blue', fontsize=20)plt.arrow(127, 420, 30, 40, color='blue', width=0.001, length_includes_head=True, \         head_width=5, head_length=10, shape='full')
#draw_anchor_box([200., 200.], 100., [2.0], [0.5, 1.0, 2.0])    plt.show()
(300.0, 500.0, 282.84271247461896, 141.4213562373095)
(300.0, 500.0, 200.0, 200.0)
(300.0, 500.0, 141.42135623730948, 282.842712474619)

在目標檢測模型中,一般會以某種規則在圖片上生成一系列錨框,將這些錨框當成可能的候選區域。模型對這些候選區域是否包含物體進行預測,若是包含目標物體,則還須要進一步預測出物體所屬的類別。還有更爲重要的一點是,因爲錨框位置是固定的,它不大可能恰好跟物體邊界框重合,因此須要在錨框的基礎上進行微調以造成能準確描述物體位置的預測框,模型須要預測出微調的幅度。在訓練過程當中,模型經過學習不斷的調整參數,最終能學會如何判別出錨框所表明的候選區域是否包含物體,若是包含物體的話,物體屬於哪一個類別,以及物體邊界框相對於錨框位置須要調整的幅度。

不一樣的模型每每有着不一樣的生成錨框的方式,在後面的內容中,會詳細介紹YOLO-V3算法裏面產生錨框的規則,理解了它的設計方案,也很容易類推到其它模型上。

交併比

上面咱們畫出了以點 爲中心,生成的三個錨框,咱們能夠看到錨框A1 與真實框 G1的重合度比較好。那麼如何衡量這三個錨框跟真實框之間的關係呢,在檢測任務中是使用交併比(Interp of Union,IoU)做爲衡量指標。這一律念來源於數學中的集合,用來描述兩個集合 和 之間的關係,它等於兩個集合的交集裏面所包含的元素個數,除以它們的並集裏面所包含的元素個數,具體計算公式以下:

 

咱們將用這個概念來描述兩個框之間的重合度。兩個框能夠當作是兩個像素的集合,它們的交併比等於兩個框重合部分的面積除以它們合併起來的面積。下圖a中紅色區域是兩個框的重合面積,圖b中藍色區域是兩個框的相併面積。用這兩個面積相除便可獲得它們之間的交併比,如 圖5 所示。


圖5:交併比

假設兩個矩形框A和B的位置分別爲:

 

 

假如位置關係如 圖6 所示:
 


圖6:計算交併比

若是兩者有相交部分,則相交部分左上角座標爲:

相交部分右下角座標爲:

計算先交部分面積:

矩形框A和B的面積分別是:

計算相併部分面積:

計算交併比:


思考:

兩個矩形框之間的相對位置關係,除了上面的示意圖以外,還有哪些可能,上面的公式可否覆蓋全部的情形?


並交比計算程序以下:

# 計算IoU,矩形框的座標形式爲xyxy,這個函數會被保存在box_utils.py文件中def box_iou_xyxy(box1, box2):    # 獲取box1左上角和右下角的座標    x1min, y1min, x1max, y1max = box1[0], box1[1], box1[2], box1[3]    # 計算box1的面積    s1 = (y1max - y1min + 1.) * (x1max - x1min + 1.)    # 獲取box2左上角和右下角的座標    x2min, y2min, x2max, y2max = box2[0], box2[1], box2[2], box2[3]    # 計算box2的面積    s2 = (y2max - y2min + 1.) * (x2max - x2min + 1.)
    # 計算相交矩形框的座標    xmin = np.maximum(x1min, x2min)    ymin = np.maximum(y1min, y2min)    xmax = np.minimum(x1max, x2max)    ymax = np.minimum(y1max, y2max)    # 計算相交矩形行的高度、寬度、面積    inter_h = np.maximum(ymax - ymin + 1., 0.)    inter_w = np.maximum(xmax - xmin + 1., 0.)    interp = inter_h * inter_w    # 計算相併面積    union = s1 + s2 - interp    # 計算交併比    iou = interp / union    return iou

bbox1 = [100., 100., 200., 200.]bbox2 = [120., 120., 220., 220.]iou = box_iou_xyxy(bbox1, bbox2)print('IoU is {}'.format(iou))
IoU is 0.474026443176
# 計算IoU,矩形框的座標形式爲xywhdef box_iou_xywh(box1, box2):    x1min, y1min = box1[0] - box1[2]/2.0, box1[1] - box1[3]/2.0    x1max, y1max = box1[0] + box1[2]/2.0, box1[1] + box1[3]/2.0    s1 = box1[2] * box1[3]
    x2min, y2min = box2[0] - box2[2]/2.0, box2[1] - box2[3]/2.0    x2max, y2max = box2[0] + box2[2]/2.0, box2[1] + box2[3]/2.0    s2 = box2[2] * box2[3]
    xmin = np.maximum(x1min, x2min)    ymin = np.maximum(y1min, y2min)    xmax = np.minimum(x1max, x2max)    ymax = np.minimum(y1max, y2max)    inter_h = np.maximum(ymax - ymin, 0.)    inter_w = np.maximum(xmax - xmin, 0.)    interp = inter_h * inter_w
    union = s1 + s2 - interp    iou = interp / union    return iou

爲了直觀的展現交併比的大小跟重合程度之間的關係,圖7 示意了不一樣交併比下兩個框之間的相對位置關係,從 IoU = 0.95 到 IoU = 0.
 


圖7:不一樣交併比下兩個框之間相對位置示意圖

05

總結

本週課程中孫老師主要爲你們講解了計算機視覺中目標檢測的基礎概念,下一節課咱們將以林業病蟲害識別的數據集爲例,爲你們介紹目標檢測任務中的數據預處理方法。同時,在後期課程中,將繼續爲你們帶來內容更豐富的課程,幫助學員快速掌握深度學習方法。

【如何學習】

1 如何觀看配套視頻?如何代碼實踐?

視頻+代碼已經發布在AI Studio實踐平臺上,視頻支持PC端/手機端同步觀看,也鼓勵你們親手體驗運行代碼哦。掃碼或者打開如下連接:

https://aistudio.baidu.com/aistudio/course/introduce/888

2 學習過程當中,有疑問怎麼辦?

加入深度學習集訓營QQ羣:726887660,班主任與飛槳研發會在羣裏進行答疑與學習資料發放。

3 如何學習更多內容?

百度飛槳將經過飛槳深度學習集訓營的形式,繼續更新《零基礎入門深度學習》課程,由百度深度學習高級研發工程師親自授課,工做日每週2、每週四8:00-9:00不見不散,採用直播+錄播+實踐+答疑的形式,歡迎關注~

請搜索AI Studio,點擊課程-百度架構師手把手教深度學習,或者點擊文末「閱讀原文」收看。

>> 訪問 PaddlePaddle 官網,瞭解更多相關內容

相關文章
相關標籤/搜索