從深度學習的最新發(fā)展來看,對象檢測是一個非常有用的領域。近年來人們發(fā)現(xiàn)了許多用于目標檢測的算法,其中包括YOLO、SSD、Mask-RCNN 和 ValnANET 等等。在過去的幾個月里,我一直致力于改進目標檢測的方法。在這一過程我漸漸認識到,學習對象檢測的最佳途徑是從頭開始實現(xiàn)一遍。這正是本教程中所要做的。我們將使用 PyTorch 來實現(xiàn)基于 YOLO V3 的對象檢測器。本教程的代碼基于 Python 3.5, 和 PyTorch 0.4. 代碼發(fā)布在 Github repo 上。本教程分為5個部分:第1部分(本文):理解 YOLO 的原理第2部分:創(chuàng)建網絡結構第3部分:實現(xiàn)網絡的前向傳遞第4部分:目標分閾值和非極大值抑制第5部分:網絡的輸入和輸出文章目錄1 背景知識2 什么是 YOLO?2.1 全卷積神經網絡 FCN2.2 輸出2.3 錨點框(Anchor Box)2.4 預測2.5 中心坐標2.6 邊界框的維度2.7 Objectness 分數2.8 類別置信度2.9 在不同尺度上的預測2.10 輸出處理3 實現(xiàn)背景知識理解卷積神經網絡的原理,包括 Residual Blocks, skip connections, 和 Upsampling。目標檢測的定義、邊界框回歸、IoU 和非極大值抑制。PyTorch 的基本用法。什么是 YOLO?YOLO 的全稱是 You Only Look Once。它是一種基于深度卷積神經網絡的目標檢測器。我們先了解 YOLO 的工作原理。全卷積神經網絡 FCNYOLO 僅僅使用卷積層,這種僅適用卷基層的網絡我們稱之為全卷積神經網絡(Fully Convolutional Network)。YOLO 擁有 75 個卷積層,還有 skip connections 和 上采樣 Upsampling 層。它使用步幅為 2 的卷積層對特征圖進行下采樣,而不是使用池化層,這有助于防止通常由池化導致的低級特征丟失。作為 FCN,YOLO 對于輸入圖像的大小并沒有要求。然而,在實踐中,我們可能想要固定輸入的大小,以防止后續(xù)一些問題的出現(xiàn)。這其中的一個重要原因是:如果我們希望按 batch 處理圖像(batch 由 GPU 并行處理,這樣可以提升速度),我們就需要固定所有圖像的高度和寬度。這就需要將多個圖像整合進一個大的 batch(將將許多 PyTorch Tensors 合并成一個)。YOLO 通過 stride(步幅)對圖像進行上采樣。例如,如果網絡的步幅是 32,則大小為 416×416 的輸入圖像將產生 13×13 的輸出。輸出一般來講,卷積層所學習的特征會被傳遞到分類器/回歸器進行預測(邊界框的坐標、類別標簽等)。在 YOLO 中,預測是通過 1 x 1 的卷積層完成的。現(xiàn)在要注意的是,我們的輸出都是特征圖(feature map),因為使用 1 x 1 的卷基層,所以每次輸出的特征圖都和之前的特征圖是一樣大小的。在 YOLO v3上,預測圖就是每個可以預測固定數量邊界框的單元格。對于網絡的深度,我們的特征圖包含 (B x (5 C)) 個條目, B 代表每個單元可以預測的邊界框數量。根據 YOLO 的論文,這些 B 邊界框中的每一個都可能專門用于檢測某種對象。每個邊界框都有 5 C 個屬性,分別描述每個邊界框的中心坐標、維度、objectness 分數和 C 類置信度。YOLO v3 在每個單元中預測 3 個邊界框。如果對象的中心位于單元格的感受野內,你會希望特征圖的每個單元格都可以通過其中一個邊界框預測對象。(感受野是輸入圖像對于單元格可見的區(qū)域。)這與 YOLO 是如何訓練的有關,只有一個邊界框負責檢測任意給定對象。首先,我們必須確定這個邊界框屬于哪個單元格。因此,我們需要切分輸入圖像,把它拆成維度等于最終特征圖的網格。讓我們思考下面一個例子,其中輸入圖像大小是 416×416,網絡的步幅是 32。如之前所述,特征圖的維度會是 13×13。隨后,我們將輸入圖像分為 13×13 個網格。輸入圖像中包含了真值對象框中心的網格會作為負責預測對象的單元格。在圖像中,它是被標記為紅色的單元格,其中包含了真值框的中心(被標記為黃色)?,F(xiàn)在,紅色單元格是網格中第七行的第七個。我們現(xiàn)在使特征圖中第七行第七個單元格(特征圖中的對應單元格)作為檢測狗的單元?,F(xiàn)在,這個單元格可以預測三個邊界框。哪個將會分配給狗的真值標簽?為了理解這一點,我們必須理解錨點的概念。請注意,我們在這里討論的單元格是預測特征圖上的單元格,我們將輸入圖像分隔成網格,以確定預測特征圖的哪個單元格負責預測對象。錨點框(Anchor Box)預測邊界框的寬度和高度看起來非常合理,但在實踐中,訓練會帶來不穩(wěn)定的梯度。所以,現(xiàn)在大部分目標檢測器都是預測對數空間(log-space)變換,或者預測與預訓練默認邊界框(即錨點)之間的偏移。然后,這些變換被應用到錨點框來獲得預測。YOLO v3 有三個錨點,所以每個單元格會預測 3 個邊界框。回到前面的問題,負責檢測狗的邊界框的錨點有最高的 IoU,且有真值框。預測下面的公式描述了網絡輸出是如何轉換,以獲得邊界框預測結果的。中心坐標注意:我們使用 sigmoid 函數進行中心坐標預測。這使得輸出值在 0 和 1 之間。原因如下:正常情況下,YOLO 不會預測邊界框中心的確切坐標。它預測:與預測目標的網格單元左上角相關的偏移;使用特征圖單元的維度(1)進行歸一化的偏移。以我們的圖像為例。如果中心的預測是 (0.4, 0.7),則中心在 13 x 13 特征圖上的坐標是 (6.4, 6.7)(紅色單元的左上角坐標是 (6,6))。但是,如果預測到的 x,y 坐標大于 1,比如 (1.2, 0.7)。那么中心坐標是 (7.2, 6.7)。注意該中心在紅色單元右側的單元中,或第 7 行的第 8 個單元。這打破了 YOLO 背后的理論,因為如果我們假設紅色框負責預測目標狗,那么狗的中心必須在紅色單元中,不應該在它旁邊的網格單元中。因此,為了解決這個問題,我們對輸出執(zhí)行 sigmoid 函數,將輸出壓縮到區(qū)間 0 到 1 之間,有效確保中心處于執(zhí)行預測的網格單元中。邊界框的維度我們對輸出執(zhí)行對數空間變換,然后乘錨點,來預測邊界框的維度。檢測器輸出在最終預測之前的變換過程,圖源:http://christopher5106.github.io/得出的預測 bw 和 bh 使用圖像的高和寬進行歸一化。即,如果包含目標(狗)的框的預測 bx 和 by 是 (0.3, 0.8),那么 13 x 13 特征圖的實際寬和高是 (13 x 0.3, 13 x 0.8)。Objectness 分數Object 分數表示目標在邊界框內的概率。紅色網格和相鄰網格的 Object 分數應該接近 1,而角落處的網格的 Object 分數可能接近 0。objectness 分數的計算也使用 sigmoid 函數,因此它可以被理解為概率。類別置信度類別置信度表示檢測到的對象屬于某個類別的概率(如狗、貓、香蕉、汽車等)。在 v3 之前,YOLO 需要對類別分數執(zhí)行 softmax 函數操作。但是,YOLO v3 舍棄了這種設計,作者選擇使用 sigmoid 函數。因為對類別分數執(zhí)行 softmax 操作的前提是類別是互斥的。簡言之,如果對象屬于一個類別,那么必須確保其不屬于另一個類別。這在我們設置檢測器的 COCO 數據集上是正確的。但是,當出現(xiàn)類別「女性」(Women)和「人」(Person)時,該假設不可行。這就是作者選擇不使用 Softmax 激活函數的原因。在不同尺度上的預測YOLO v3 在 3 個不同尺度上進行預測。檢測層用于在三個不同大小的特征圖上執(zhí)行預測,特征圖步幅分別是 32、16、8。這意味著,當輸入圖像大小是 416 x 416 時,我們在尺度 13 x 13、26 x 26 和 52 x 52 上執(zhí)行檢測。該網絡在第一個檢測層之前對輸入圖像執(zhí)行下采樣,檢測層使用步幅為 32 的層的特征圖執(zhí)行檢測。隨后在執(zhí)行因子為 2 的上采樣后,并與前一個層的特征圖(特征圖大小相同)拼接。另一個檢測在步幅為 16 的層中執(zhí)行。重復同樣的上采樣步驟,最后一個檢測在步幅為 8 的層中執(zhí)行。在每個尺度上,每個單元使用 3 個錨點預測 3 個邊界框,錨點的總數為 9(不同尺度的錨點不同)。作者稱這幫助 YOLO v3 在檢測較小目標時取得更好的性能,而這正是 YOLO 之前版本經常被抱怨的地方。上采樣可以幫助該網絡學習細粒度特征,幫助檢測較小目標。輸出處理對于大小為 416 x 416 的圖像,YOLO 預測 ((52 x 52) (26 x 26) 13 x 13)) x 3 = 10647 個邊界框。但是,我們的示例中只有一個對象——一只狗。那么我們怎么才能將檢測次數從 10647 減少到 1 呢?目標置信度閾值:首先,我們根據它們的 objectness 分數過濾邊界框。通常,分數低于閾值的邊界框會被忽略。非極大值抑制:非極大值抑制(NMS)可解決對同一個圖像的多次檢測的問題。例如,紅色網格單元的 3 個邊界框可以檢測一個框,或者臨近網格可檢測相同對象。實現(xiàn)YOLO 只能檢測出屬于訓練所用數據集中類別的對象。我們的檢測器將使用官方權重文件,這些權重通過在 COCO 數據集上訓練網絡而獲得,因此我們可以檢測 80 個對象類別。該教程的第一部分到此結束。這部分詳細講解了 YOLO 算法。如果你想深度了解 YOLO 的工作原理、訓練過程和與其他檢測器的性能規(guī)避,可閱讀原始論文:YOLO V1: You Only Look Once: Unified, Real-Time Object DetectionYOLO V2: YOLO9000: Better, Faster, StrongerYOLO V3: An Incremental Improvement文章來源:Hello Paperspace