當前最佳的YOLOv4是如何煉成的?細數那些小細節

機器之心發表於2020-06-06
當前最佳的YOLOv4是如何煉成的?細數那些小細節
 目標檢測在近幾年開始發展成熟,但即便如此,競爭依舊激烈。如下所示,YOLOv4 宣稱已經實現了當前最前沿技術的準確度,同時還能維持較高的處理幀率。使用 Tesla V100 GPU,在 MS COCO 資料集上以接近 65 FPS 的推理速度,YOLOv4 實現了 43.5% AP (65.7% AP₅₀)的準確度。但對於目標檢測而言,高準確度早已不是唯一的目標。我們還希望邊緣裝置也能流暢地執行這些模型。因此,如何使用低成本硬體實時地處理輸入影片也成為了一個重要的研究方向。

YOLOv4 的開發歷程很有意思,其中評估、修改和整合了很多有趣的新技術。而且其也最佳化了計算效率,使檢測器在單個 GPU 上也能很好地完成訓練。

Bag of freebies (BoF) 與 Bag of specials (BoS)

為了提升準確度,可以針對訓練過程進行一些最佳化,比如資料增強、類別不平衡、成本函式、軟標註…… 這些改進不會影響推理速度,可被稱為「Bag of freebies」。另外還有一些改進可稱為「bag of specials」,僅需在推理時間方面做少許犧牲,就能獲得優良的效能回報。這類改進包括增大感受野、使用注意力機制、整合跳過連線(skip-connection)或 FPN 等特性、使用非極大值抑制等後處理方法。本文將探討特徵提取器和頸部的設計方式以及那些好用的 BoF 和 BoS 改進策略。

骨幹網路

密集模組與 DenseNet

為了提升準確度,我們可透過提高網路深度來擴充套件感受野和增大模型複雜度。同時,為了降低訓練難度,還可應用跳過連線。我們還可以進一步延伸這一概念,即使用高度互連的層。

密集模組(Dense Block)包含多個卷積層,其中每一層 H_i 都由批歸一化、ReLU 與之後的卷積構成。H_i 的輸入不僅包含前一層的輸出,還包含之前所有層的輸出以及原始輸入,即 x_₀, x_₁, …, x_{i-1}。下圖中每個 H_i 都輸出 4 個特徵圖。因此,在每一層,特徵圖的數量都增加 4 倍——增長率。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


然後,透過組合多個密集模組與其間的過渡層(由卷積和池化構成),可以構建出 DenseNet。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


下面給出了這種架構設計的詳情。

當前最佳的YOLOv4是如何煉成的?細數那些小細節


交叉階段部分連線(CSP)

CSPNet 將密集模組的輸入特徵圖分為了兩部分。第一部分 x_₀’ 會繞過密集模組,成為下個過渡層的輸入的一部分。第二部分 x_₀’’ 則會透過密集模組,如下圖所示。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


這種新設計透過將輸入分為兩部分而降低了計算複雜度——此時僅有一部分輸入會經過密集模組。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


CSPDarknet53

YOLOv4 使用了上面的 CSP 與下面的 Darknet-53 作為特徵提取的骨幹。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


相比於基於 ResNet 的設計,CSPDarknet53 模型的目標檢測準確度更高,不過 ResNet 的分類效能更好一些。但是,藉助後文將討論的 Mish 和其它技術,CSPDarknet53 的分類準確度可以得到提升。因此,YOLOv4 最終選擇了 CSPDarknet53。

頸部(Neck)

目標檢測器由用於特徵提取的骨幹部分(backbone)和用於目標檢測的頭部(head,下圖最右邊的模組)構成。而為了檢測不同大小的目標,需要使用一種分層結構,使得頭部可探測不同空間解析度的特徵圖。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


為了讓輸入頭部的資訊更豐富,在輸入頭部前,會將來自自底向上和自上而下的資料流按逐元素的方式相加或相連。因此,頭部的輸入將包含來自自底向上資料流的豐富空間資訊以及來自自上而下資料流的豐富語義資訊。該系統的這一部分稱為頸部(neck)。下面更詳細地談談這一設計。

特徵金字塔網路(FPN)

YOLOv3 採用了與 FPN 類似的方法來實現不同大小層次的目標檢測預測。

當前最佳的YOLOv4是如何煉成的?細數那些小細節


在針對特定尺寸大小進行預測時,FPN 會對自上而下的資料流進行上取樣(2 倍),並將其與自底向上的相鄰層相加(見下圖)。得到的結果會被傳遞給一個 3×3 的卷積核,以減少上取樣偽影以及為頭部建立下圖中的特徵圖 P4。

當前最佳的YOLOv4是如何煉成的?細數那些小細節


SPP(空間金字塔池化層)

SPP 應用了略有不同的策略來檢測不同尺寸大小的目標,即使用一個空間金字塔池化層替代了最後的池化層(在最後的卷積層之後)。其特徵圖在空間上分成了 m×m 個 bin,其中 m 可以分別為 1、2、4 等值。然後針對每個通道,為每個 bin 應用一次最大池化。這會形成一個長度固定的表徵,然後可以使用 FC 層對該表徵進行進一步的分析。

當前最佳的YOLOv4是如何煉成的?細數那些小細節


許多基於 CNN 的模型都包含 FC 層,因此只能接受指定尺寸的輸入影像。相對而言,SPP 可使用不同大小的影像。然而,也還存在不包含 FC 層的技術,比如全卷積網路(FCN);這些技術可以接受不同尺寸的影像。對於空間資訊非常重要的影像分割等任務而言,這類設計尤為重要。因此,對於 YOLO,並不必需將 2D 特徵圖轉化為固定大小的 1D 向量。

使用 SPP 的 YOLO

YOLO 中使用的 SPP 經過修改,以保留輸出的空間尺寸大小。而且還在大小為 1×1、5×5、9×9、13×13 等的滑動核(sliding kernel)應用了最大池化。空間尺寸大小得以保留。然後將來自不同核大小的特徵圖連線起來作為輸出。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


下圖展示了 SPP 是如何整合進 YOLO 的。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


路徑聚合網路(PAN)

早期的深度學習的模型設計相對簡單。每一層的輸入都來自其上一層。更前面的層會提取區域性的紋理和圖案資訊,並構建出後續層所需的語義資訊。但是,隨著網路向右側推進,微調最佳化預測結果時所需的區域性資訊可能會丟失。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


在後來的深度學習開發中,層之間的互連方式變得更加複雜。DenseNet 在這方面達到了極致。其中每一層都連線了其前面的所有層。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


在 FPN 中,來自自底向上和自上而下資料流的鄰近層的資訊會結合到一起。

當前最佳的YOLOv4是如何煉成的?細數那些小細節


層之間資訊的流動方式變成了模型設計中需要考慮的又一關鍵事項。

下圖是用於目標檢測的路徑聚合網路(PAN)。其中,自底向上的路徑得到增強,使得低層資訊更容易傳播到頂部。在 FPN 中,區域性空間資訊會向上傳播,如紅色箭頭所示。儘管圖中可能沒有展示清楚,但這條紅色路徑穿過了大約 100 多層。PAN 引入了一個捷徑路徑(綠色路徑),其僅需 10 層左右就能抵達頂部的 N₅ 層。這個短迴路概念使得頂層也能獲取到細粒度的區域性資訊。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


順帶一提,頸部設計可以進行如下的視覺化:
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


但是,YOLOv4 並沒有將鄰近層加到一起,而是將特徵圖連線到一起。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


在 FPN 中,不同尺寸大小的目標是分開獨立檢測的。這可能會導致出現重複的預測結果,而且無法利用來自其它特徵圖的資訊。PAN 最早使用了逐元素最大運算將這些資訊融合到一起(這裡不再詳述相關細節)。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


空間注意力模組(SAM)

注意力已經在深度學習設計中得到了廣泛的應用。SAM 會為輸入特徵圖分別應用最大池化和平均池化,從而得到兩個特徵圖集合。其結果會被送入一個卷積層,之後再由一個 sigmoid 函式建立出空間注意力。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


這個空間注意力掩碼再被應用於輸入特徵,從而輸出經過最佳化的特徵圖。

當前最佳的YOLOv4是如何煉成的?細數那些小細節


YOLOv4 使用了一種修改版的 SAM,其中沒有使用最大池化和平均池化
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


YOLOv4 使用修改版的 SPP、PAN 和 SAM 逐步實現 / 替換了 FPN 概念。

用於骨幹部分的 Bag of freebies (BoF)

用於 YOLOv4 骨幹部分的 BoF 特徵包括:

  • CutMix 和 Mosaic 資料增強

  • DropBlock 正則化

  • 類別標籤平滑化


CutMix 資料增強

Cutout 資料增強會移除影像的部分割槽域(見下圖)。這會迫使模型在執行分類時不過於相信特定的特徵。但是,如果影像的某部分充滿了無用資訊,則這種操作就浪費了。CutMix 的做法則不同,其是將影像的一部分剪下下來再貼上到另一張影像上。其基本真值標籤會根據補丁的面積比例進行調整,比如狗的部分佔 0.6,貓的部分佔 0.4。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節



從概念上講,CutMix 在目標的可能組成成分方面有更寬廣的視角。裁減掉的部分會迫使模型學習使用不同的特徵組合進行分類。這可避免信心過高。因為是用另一張影像替代該區域,所以影像中的資訊量和訓練效率都不會受到顯著的影響。

Mosaic 資料增強

Mosaic 這種資料增強方法是將 4 張訓練影像組合成一張來進行訓練(而非 CutMix 中的 2 張)。這讓模型在非慣例的環境中能更好地執行目標檢測。此外,由於每個 mini-batch 都包含影像的較多變體(4×),因此在估計均值和方差時,對較大 mini-batch 的需求會降低。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


DropBlock 正則化

在全連線層中,我們可透過丟棄一些連線來迫使模型學習不同的特徵,而不是過於依賴少量特徵。但是,這可能不適用於卷積層。相鄰的位置可能高度相關。所以即使丟棄一些畫素(如中部的圖所示),仍然可以檢測出空間資訊。DropBlock 正則化基於類似的概念,但適用於卷積層。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節



不過 DropBlock 丟棄的不是各個畫素,而是大小為 block_size × block_size 的一個畫素塊。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節



類別標籤平滑化

每當你覺得自己完全正確時,你可能只是想錯了。如果一個預測結果的置信度為 100%,可能只是說明模型記憶了這個資料,而非學習了什麼東西。標籤平滑化將預測結果的目標上界調整至了一個更低的值,比如 0.9。然後在計算損失時,模型會以這個值為目標,而不是 1.0。這一方法可緩解過擬合問題。


p = tf.placeholder(tf.float32, shape=[None, 10])# Use 0.9 instead of 1.0.feed_dict = {  p: [[0, 0, 0, 0.9, 0, 0, 0, 0, 0, 0]] # Image with label "3"}# logits_real_image is the logits calculated by# the discriminator for real images.d_real_loss = tf.nn.sigmoid_cross_entropy_with_logits(                    labels=p, logits=logits_real_image)


用於骨幹部分的 Bag of Specials(BoS)

  • Mish 啟用

  • 交叉階段部分連線(CSP)

  • 多輸入加權的殘差連線(MiWRC)


Mish 啟用

假設啟用函式的形式為:

當前最佳的YOLOv4是如何煉成的?細數那些小細節


其中一元或二元運算元有很多不同的候選函式,比如餘弦函式。在選用這些函式時,我們可以隨機猜測,然後基於不同的任務(比如分類)和資料集來評估對應模型的表現。最終,我們可以選出能讓模型表現最好的啟用函式

我們還可以應用強化學習來更高效地搜尋解空間。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


使用此方法並進行實驗,結果發現了下面這個新啟用函式 Swish,其表現優於 ReLU 以及其它許多啟用函式
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節



具有不同 β 值的 Swish 啟用函式

Mish 是另一個與 ReLU 和 Swish 很相似的啟用函式。Mish 的論文(arXiv:1908.08681)宣稱使用 Mish 的深度網路在許多不同資料集上的表現都更優。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


為 CSPDarknet53 和檢測器使用 Mish,YOLOv4 的兩個準確度都獲得了提升。

多輸入加權的殘差連線(MiWRC)

過去幾年裡,研究者很關注應該向網路層輸入哪些特徵圖。有時候,我們會突破僅使用之前一層的傳統方法。

現在,更重要的是層的連線方式,尤其是目標檢測器中層的連線方式。前面已經討論過 FPN 和 PAN 示例。下圖中的 d 展示了另一種頸部設計 BiFPN,其論文(arXiv:1911.09070)宣稱 BiFPN 在準確度與效率的權衡方面表現更好。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


YOLOv4 比較了其與 EfficientDet 的表現,而後者被認為是目前最先進的技術之一。我們來看看這種技術。如下所示,EfficientDet 以 EfficientNet 作骨幹,以 BiFPN 為頸部。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節



為便參照,下面給出了基於 MBConv 層構建的 EfficientNet 的架構,這些層由反向殘差模組組成。

當前最佳的YOLOv4是如何煉成的?細數那些小細節


正如其論文(arXiv:1801.04381)中提到的那樣,這種反向殘差模組的構成方式為:


第一層稱為逐深度卷積,其透過為每個輸入通道應用單個卷積過濾器來執行輕量級的過濾。第二層是一個 1×1 卷積,稱為逐點卷積,負責透過計算輸入通道的線性組合來構建新特徵。


假設輸入的維度為 hᵢ × wᵢ × dᵢ。則其會應用 dᵢ 個 k × k 的卷積過濾器——每個通道一個。然後其會為所有通道應用 1×1 卷積過濾器,得到大小為 hᵢ × wᵢ × dⱼ 的輸出。因此,總計算複雜度為:


當前最佳的YOLOv4是如何煉成的?細數那些小細節



其關鍵優勢是所需的計算量比傳統卷積層要少得多。

在許多機器學習深度學習問題中,我們都要學習輸入的低維表徵。我們會透過建立「資訊」瓶頸來提取資料的核心資訊。這會迫使我們發現最重要的資訊,這正是學習的核心原理。遵循這一原理,反向殘差模組以低維表徵為輸入,然後使用卷積(線性運算)和非線性運算對其進行操作。但是,ReLU 等非線性部分面臨著一大問題:非線性運算會不成比例地拉伸或壓縮某些區域。在發生這樣的壓縮時,輸入可能會對映到同樣的區域 / 點。舉個例子,ReLU 可能會將通道摺疊進這片低維空間中,從而導致資訊不可避免地丟失。正如其論文中寫道:

移除窄小層中的非線性特性是很重要的,這樣才能維持表徵能力。


為了解決這一問題,我們可對維度(通道的數量)進行臨時的擴充套件。我們希望當我們的通道數量較多時,在經過非線性運算之後,資訊仍可能儲存於某些通道之中。下面給出了反向殘差模組的一些細節:
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節



可以看到,低維表徵首先被擴充套件到了 t_k 個通道。然後,使用輕量的 3 × 3 逐深度卷積對其進行過濾。在該模組的最後,特徵又會被約減回低維。當其保持在高維空間中時,就加入非線性運算。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節



該模組的起始處和終點之間新增了一個殘差連線。下面左圖是傳統的殘差模組,右圖是這裡描述的反向殘差模組。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


理解 EfficientDet 的核心概念是很有趣的。但 EfficientDet 在 YOLOv4 上的主要貢獻是多輸入加權的殘差連線。在 EfficientDet 論文中,可以觀察到不同解析度下不同的輸入特徵,它們對輸出特徵的貢獻也不相等。但在之前的討論中,我們無差別地新增了這些特徵。在 EfficientDet 中,在構建輸出時,輸入特徵的加權是各不相同的:

當前最佳的YOLOv4是如何煉成的?細數那些小細節


其中 wᵢ 的訓練和學習方式與其它可訓練引數一樣。

用於檢測器的 Bag of freebies (BoF)

用於 YOLOv4 檢測器的 BoF 特徵包括:

  • CIoU-loss

  • CmBN

  • DropBlock 正則化

  • Mosaic 資料增強

  • 對抗訓練

  • 消除網格敏感度

  • 為單個基本真值使用多個錨

  • 餘弦退火排程

  • 最優超引數

  • 隨機訓練形狀


CIoU-loss

損失函式能為我們提供如何調整權重以降低成本的訊號。所以在預測結果錯誤時,我們期望其能為我們提供前進的方向。但在使用 IoU 且基本真值框與預測結果不重疊時,這卻無法實現。假設有兩個預測結果與基本真值都不重疊,則 IoU 損失函式無法確定哪個結果更好——即便其中一個結果可能與基本真值更接近。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節

 

Generalized IoU(GIoU)透過將該損失最佳化為以下形式而解決了這一問題:

當前最佳的YOLOv4是如何煉成的?細數那些小細節


但這個損失函式通常會首先擴充套件其預測邊界框,直到其與基本真值區域有重疊。然後它會縮小以增大 IoU。相比於理論上的迭代次數需求,這個過程實際需要更多迭代次數。

首先,引入 Distance-IoU Loss(DIoU):

當前最佳的YOLOv4是如何煉成的?細數那些小細節



其引入了一個新的目標以減少兩個框的中心點之間的距離。

最後,引入 Complete IoU Loss(CIoU)以便:

  • 增大基本真值框與預測框之間的重疊面積;

  • 最小化它們的中心點之間的距離;

  • 維持框的長寬比的一致性。


其最終定義為:

當前最佳的YOLOv4是如何煉成的?細數那些小細節


CmBN

原始的批歸一化會收集小批次資料內樣本的均值和方差,以白化(whiten)層輸入。但是,如果小批次資料規模很小,則這些估計結果將具有很高的噪聲。一種解決方案是在許多小批次資料上估計它們。但是,由於每次迭代中權重都會變化,因此在這些權重下收集的統計資料可能會在新的權重下變得不準確。單純地求平均可能出錯。幸運的是,權重的改變是逐漸發生的。交叉迭代批歸一化(CBM)使用了以下的調整來基於 k 個之前的迭代估計這些統計資料。

當前最佳的YOLOv4是如何煉成的?細數那些小細節


CmBN 是一個經過修改的選項,其僅收集單個批次內小批次資料之間的統計資料。

對抗訓練(SAT)

SAT 是一種資料增強技術。其首先會在訓練樣本上執行一次前向透過。使用傳統方法時,我們會在反向傳播過程中調整模型的權重來提升檢測器檢測影像中目標的能力。但這裡所取樣的方向卻相反。它會修改影像,使其能在最大程度上降低檢測器的效能,即建立以當前模型為目標的對抗攻擊——即使新影像可能在人眼看來與原來的一樣。接下來,使用這張新影像與原始的邊界框和類別標籤來訓練該模型。這有助於提升模型的泛化能力並降低過擬合

消除網格敏感度

邊界框 b 的計算方式為:
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節



對於 bₓ=cₓ 和 bₓ=cₓ+1 的情況,我們需要 tₓ 分別具有很大的負值和正值。但我們可以將 σ 與一個比例因子(>1.0)相乘,從而更輕鬆地實現這一目標。以下是對原始碼的修改:

當前最佳的YOLOv4是如何煉成的?細數那些小細節



為單個基本真值使用多個錨點

如果 IoU(ground truth, anchor) > IoU threshold,則為單個基本真值使用多個錨點。(注:作者沒有更多地說明該方法在 YOLOv4 中的作用。)

餘弦退火排程

餘弦排程會根據一個餘弦函式來調整學習率。首先,較大的學習率會以較慢的速度減小。然後在中途時,學習的減小速度會變快,最後學習率的減小速度又會變得很慢。
 

當前最佳的YOLOv4是如何煉成的?細數那些小細節


這張圖展示了學習率衰減的方式(下圖中還應用了學習率預熱)及其對 mAP 的影響。可能看起來並不明顯,這種新的排程方法的進展更為穩定,而不是在停滯一段時間後又取得進展。

當前最佳的YOLOv4是如何煉成的?細數那些小細節

餘弦學習率 + 預熱

使用遺傳演算法(進化演算法)的超引數選擇

進化演算法是一種有根據的猜測方法。其遵循「適者生存」的概念。舉個例子,如果我們隨機選擇 100 組超引數。然後使用它們訓練 100 個模型。之後,我們從中選出表現最好的 10 個模型。對於每個被選中的模型,都根據原始版本建立 10 個超引數略有不同的變體版本。再使用這些新的超引數重新訓練模型,再次選出其中表現最好的。隨著我們不斷迭代,我們應該可以找到超引數的最佳集合。另外,我們也可以一開始使用預設超引數,然後再執行突變。正如其論文(arXiv: 2004.10934)中寫道:

遺傳演算法使用 YOLOv3-SPP,根據 GIoU 損失進行訓練,併為 min-val 5k 資料集搜尋 300 epoch。我們為遺傳演算法實驗採用了搜尋得到的學習率 0.00261、動量 0.949、用於分配基本真值的 IoU 閾值 0.213 以及損失歸一化運算元 0.07。


隨機訓練形狀

許多單階段目標檢測器都是用固定的輸入影像形狀進行訓練的。為了提升泛化能力,我們可以使用不同的影像大小訓練模型。(YOLO 中的多尺度訓練。)

用於檢測器的 Bag of Specials(BoS)

用於 YOLOv4 檢測器的 BoS 特徵包括:

  1. Mish 啟用

  2. 修改版 SPP 模組

  3. 修改版 SAM 模組

  4. 修改版 PAN 路徑聚合模組

  5. DIoU-NMS


DIoU-NMS

非極大值抑制(NMS)會過濾掉其它預測同一目標的邊界框並保留置信度最高的邊界框。

當前最佳的YOLOv4是如何煉成的?細數那些小細節


DIoU(前面討論過)用作 NMS 的一個因子。該方法在抑制冗餘的邊界框時會使用 IoU 和兩個邊界框的中心點之間的距離。這能使得模型能更加穩健地應對有遮擋的情況。

評估過的技術

儘管本文介紹的都是已被整合進 YOLOv4 中的技術,但 YOLOv4 也投入了很大努力來評估其它技術。最後,展示一下 YOLOv4 考慮過的技術列表:

當前最佳的YOLOv4是如何煉成的?細數那些小細節

原文連結:https://medium.com/@jonathan_hui/yolov4-c9901eaa8e61

相關文章