# [Object Detection_YOLO] YOLOv7 論文筆記
###### tags: `Object Detection` `YOLO` `paper`
### [AI / ML領域相關學習筆記入口頁面](https://hackmd.io/@YungHuiHsu/BySsb5dfp)
---
### 模型部署與加速
- [[Object Detection_YOLO] YOLOv7 論文筆記](https://hackmd.io/xhLeIsoSToW0jL61QRWDcQ)
- [Deploy YOLOv7 on Nvidia Jetson](https://hackmd.io/kZftj6AgQmWJsbXsswIwEQ)
- [Convert PyTorch model to TensorRT for 3-8x speedup<br>將PyTorch模型轉換為TensorRT,實現3-8倍加速](https://hackmd.io/_oaJhYNqTvyL_h01X1Fdmw?both)
- [Accelerate multi-streaming cameras with DeepStream and deploy YOLO series models<br>使用DeepStream加速多串流攝影機並部署YOLO系列模型](https://hackmd.io/@YungHuiHsu/rJKx-tv4h)
- [Use Deepstream python API to extract the model output tensor and customize model post-processing (e.g., YOLO-Pose)<br>使用Deepstream python API提取模型輸出張量並定製模型后處理(如:YOLO-Pose)](https://hackmd.io/@YungHuiHsu/rk41ISKY2)
- [Model Quantization Note 模型量化筆記](https://hackmd.io/riYLcrp1RuKHpVI22oEAXA)
---
## YOLOv7官方連結
#### [YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors](https://arxiv.org/abs/2207.02696)
#### [yolov7 offical github](https://github.com/WongKinYiu/yolov7)
#### [yolo 原作者 github](https://github.com/pjreddie/darknet)
:::spoiler 效能進步
![](https://i.imgur.com/7U9hK5P.png =500x)
![](https://i.imgur.com/8jSlaM7.png =500x)
:::
## YOLO家族圖譜與模型架構
### yolov7 架構說明
#### yolov7 架構簡圖
彩色的方塊可以看作是各自的輸出特徵圖,而箭頭則是轉換這些數據的多個卷積模塊。
![](https://i.imgur.com/AO6M9km.png =800x)
modified from : [YOLOv7を完全に理解した](https://dev.classmethod.jp/articles/yolov7-architecture-overall/#toc-11)
:::spoiler yolov7的三層次架構
- Backbone(左邊的藍色金字塔)
- 結構,主要用於特徵提取,處理輸入圖像的第一個金字塔結構
- 隨著數字從B1到B5的增加,輸入圖像的特徵圖變得越來越小。隨著數量的增加,具有更多通道 (channels)的特徵數量也在增加。
- Neck(中間的橘色金字塔結構)
- 透過上採樣由上而下擴增,隨著數字從P5到P3的減少,特徵圖逐層放大
- 透過橫向連結,融合Backbone各層特徵而獲得個尺度豐富的表徵訊息
- Head(右邊的綠色金字塔)
- 再次進行還原處裡的金字塔結構(由下而上的下採用)形成H4-H5
- 檢測
- 最後的特徵圖P3、H4和H5被用來處理3種不同分辨率的檢測。
- YOLOv7使用anchor(anchor-based),所以對於這3種不同分辨率的特徵圖,分別生成了3個anchor。(這3種分辨率的特徵圖中,每一種都分配了3個anchor)
:::info
#### 物件偵測模型的常見架構 Backbone, Neck, Head
![](https://i.imgur.com/1kSsuoZ.png)
source : [Comparison of YOLOv3, YOLOv5s and MobileNet-SSD V2 for Real-Time Mask Detection](https://www.researchgate.net/publication/353211011_Comparison_of_YOLOv3_YOLOv5s_and_MobileNet-SSD_V2_for_Real-Time_Mask_Detection)
- Backbone 骨幹網絡
- 主要用於特徵提取。例如`VGG`, `ResNet`,`Darknet`, 應用於邊緣裝置的輕量級網路(`MobileNet`, `ShuffleNet`, EfficientNet, etc.
- Neck
- 用於提取更抽象、複雜表徵。在金字塔不同階段產出不同尺度特徵圖的網路層
- Head 檢測頭
- 主要用於預測目標的類別和位置(bounding boxes)
:::
### 錯綜複雜的YOLO家族圖譜
![](https://i.imgur.com/ASw852w.png =500x)
source: [DeepHub IMBA](https://cloud.tencent.com/developer/article/2212232?areaSource=104001.4&traceId=bTXJdiCqPM48qF63XTtFY)。
其中,v7為繼承自v4,為官方認證。(另外v7還有個非官方版,不列入討論)
:::spoiler 歷代版本架構與數據增強演變
![](https://i.imgur.com/JXN0bNS.png =900x)
source: [DeepHub IMBA](https://cloud.tencent.com/developer/article/2212233?from=article.detail.2212232&areaSource=106000.1&traceId=nejPgKXw-QpHREHAs91yJ)。
> 雖然上表並未提及所有提高性能的改進和發現。但是YOLO的發展我們可以看到一些模式。
> - Backbone:最初由一個分支(GoogLeNet、VGG、Darknet)組成,然後過渡到包含跳躍連接的架構(Cross-Stage Partial connections — CSPDarknet、CSPRepResNet、Extended-ELAN)。
>
> - Neck:最初也由一個分支組成,然後以特徵金字塔網絡的各種修改形式逐步發展,這樣可以在不同尺度下保持物體檢測的準確性。
>
> - Head:在早期版本中只有一個 head,它包含所有輸出參數——分類、bbox 的坐標等。後面的研究發現將它們分成不同的頭會更有效率。從基於錨點到無錨點也發生了轉變(v7 除外——出於某種原因,它仍然有錨點)。
>
> - 數據增強:仿射變換、HSV 抖動和曝光變化等早期增強非常簡單,不會改變對象的背景或環境。而最近的一些——MixUp、Mosaic、CutOut 等改變了圖像的內容。平衡這兩個方向增強的比例對於神經網絡的有效訓練都很重要。
:::
- 補充:`FPN` 特徵金字塔網路
:::info
`FPN`透過1.由上而下以及2.橫向連接,讓原本深層特徵圖(低解析度、高階表徵如羽毛、鳥喙)與淺層特徵圖(高解析度、但學習到的表徵多為低層次,如線條、紋理)融合,得到具有更高解析度與豐富表徵的多尺度特徵圖。這個架構後來被廣泛應用於物件檢測模型
![](https://i.imgur.com/jdkXefk.png =600x)
特徵圖由藍色的輪廓表示,較粗的 輪廓表示語義上更強的特徵
- FPN帶來的主要優點包括:
1. **多尺度偵測**:FPN允許網絡同時處理不同尺寸的特徵圖,從而**增強對不同尺寸物體的偵測能力**。這是因為大物體通常在低解析度的特徵圖中更容易被偵測,而小物體則在高解析度的特徵圖中更為明顯。
2. **改善特徵表達**:透過將不同層次的特徵融合,FPN能夠結合高層的語義資訊和低層的細節資訊,這樣可以提供更豐富、更精確的特徵表達,對於物件的定位和識別都有正面的影響。
3. **效能和速度的平衡**:FPN通過共享特徵計算,能夠在保持高效能的同時減少計算成本。這對於需要實時處理的應用來說尤其重要。
4. **泛化能力**:FPN的架構使其能夠更好地泛化到不同的物件偵測任務和數據集,因為它不依賴於特定尺寸的物體。
- [Feature Pyramid Networks for Object Detection](https://arxiv.org/abs/1612.03144)
:::
## 主要特點
YOLOv7通過引入幾項架構重塑提高了速度和準確性。與Scaled YOLOv4類似,YOLOv7的骨架不使用ImageNet預訓練的骨架。相反,這些模型完全使用COCO數據集來訓練。因為YOLOv7與Scaled YOLOv4是由同一作者編寫的,因此架構相近。在YOLOv7的論文中引入了以下主要變化:
:::info
重點摘要如下
1. 設計新的模型重參數化(re-parameterized model)的方法。發現RepConv中的identity連接破壞了ResNet中的殘差和Denset中的串聯,提出使用無indentity連接的RepConv(RepConvN)來設計網絡架構
2. 提出新的動態標籤分配策略(dynamic label assignment strategy )透過階層式的深層監督與動態標籤分配,提升特徵學習能力(coarse-to-fine lead guided label assignment)
3. 提出了可以有效利用參數和記憶體使用量的 "擴展"(extend)和 "複合縮放 "方法(compound scaling)。以ELAN改進,提出Extend-ELAN(E-ELAN),在不破壞原始梯度路徑的情況下持續增強網絡學習的能力
4. 有效地讓最先進的即時物件偵測模型減少40%的參數和50%的計算量,並且具有更快的推理速度和更高的檢測精度。
上述1與2在論文中稱為"可訓練的贈品"(bag-of-freebies),雖然會增加訓練成本,但可以提高檢測的準確性,且不增加推理時的計算成本
:::
整體來說,在API上,yolov7參考yolov5的設計用Pytorch實現,更為簡潔亦用。
在模型架構設計與各種減少參數量、提升計算效能的改進上,則集近年CNN神經網路各種在效能上的改進,特別是近期在邊緣裝置運算上參數量與計算效率的進展,包括re-parameterized convolution來自`RepVGG`、`RepVGG`則簡化`GoogleNet`多分支概念,在推理階段重現簡單的單路徑無分支VGG架構。
`E-ELAN`的多分支與`group convolution`則源自`AlexNet`為了分散運算所設計、ELAN源自VovNet,而`VovNet`源自`DenseNet`在計算量上的改進提供在邊緣裝置使用的可行性、`DenseNet`則繼承`ResNet`概念,以特徵殘差取代輸入殘差、...。因此在理解volov7各種原理時,需要補充相關背景知識、彷彿跟著跑了一遍CNN演進的近代史。
以下逐一檢視各項設計
---
## Architectural Reforms
### 擴展的高效層聚合網路 E-ELAN (Extended Efficient Layer Aggregation Network)
在大多數關於設計高效架構的文獻中,主要考慮的因素不外乎是參數的數量、計算量和計算密度。 包括從記憶體訪問成本(Memory Access Cost, MAC)的特點出發,分析了輸入/輸出通道比率、架構的分支數量和逐元素操作對網路推理速度的影響等
![](https://i.imgur.com/nVHPnO9.png =900x)
圖2(b)中的CSPVoVNet[79]的設計是VoVNet[39]的一個變種。除了考慮上述基本的設計問題外,CSPVoVNet[79]的結構還分析了梯度路徑( gradient path),使不同層的權重可以學習更多不同的特徵。
VoVNet設計式意圖
![](https://i.imgur.com/bscAMBV.png =300x)
source : [An Energy and GPU-Computation Efficient Backbone Network for Real-Time Object Detection(VoVNet)](https://arxiv.org/pdf/1904.09730.pdf)
上述的梯度分析方法使推論階段可以更快、更準確。圖2(c )中的ELAN 。考慮了以下設計策略--"如何設計一個 高效的網絡?"。得出了一個結論:==通過控制最短的最長梯度路徑,一個更深的神經網路可以有效地學習和收斂==(詳見[Designing Network Design Strategies Through Gradient Path Analysis](https://arxiv.org/pdf/2211.04800.pdf)),而提出了基於ELAN的擴展ELAN(E-ELAN)。其主要結構如圖2(d)所示
- E-ELAN 模組圖
- 右側為group convolution單元的圖解
![](https://i.imgur.com/Ilhl6hv.png =600x)
sorce: [圖解 YOLOv7 - part1](https://www.youtube.com/watch?v=Ot__47ItjDs)
#### ==Extended==-ELAN
由於在`ELAN`架構的堆疊數量已達到穩定飽和的狀態,使用原架構在再往上堆疊無異於增進效能,因此,在ELAN的基礎上,設計了擴增、隨機洗牌與合併分支等操作,在不破壞原本梯度路徑的前提下增強模型學習表徵的能力。`E-ELAN` 僅改變 computational block 架構,並沒有更動後面的 transition layer。
- expand cardinality
- 為了使模型的基本計算單元容易拓展縮放,將computational block 中每層 layer 都採相同的分組數量(cardinality/group)與channel倍數配置
- 參照group convolution方式擴展所有Computational block的channel
- shuffle cardinality
- 為了提升表徵學習能力、讓不同組間卷積模塊能彼此交流特徵訊息
- 參照Shuffled Grouped Convolution,將computational block以channel為單位進行洗牌重分配,依cardinality/group組數分組後再合併(concate)
- merge cardinality
- 最後以相加的操作將分組卷積層融合
##### 補充: 分組卷積 group convolution
- 分組卷積 group convolution
:::info
![](https://i.imgur.com/XP6PUmV.png =400x)
source : [CondenseNet: An Efficient DenseNet using Learned Group Convolutions](https://arxiv.org/abs/1711.09224)
- group convolution
- 最早在`AlexNet`中出現,由於當時的計算資源有限,訓練`AlexNet`時卷積操作不能全部放在同一個GPU處理,因此作者把feature maps分給多個GPU分別進行處理,最後把多個GPU的結果進行融合(分散式運算中的"模型設計"分散)。
![](https://i.imgur.com/srTBbdg.png =300x)
- cardinality
- 指分組的數量。`ResNeXt`承襲`AlexNet`分組與`Inception`的結構把分支的單園簡化為多個相同的卷積層。1.有助於多gpu模型分散運算、2.減少參數量、3.約束相鄰filter間的相關性避免模型過擬合
:::
##### 補充: 隨機分組卷積(Shuffled Grouped Convolution)
- 隨機分組卷積(Shuffled Grouped Convolution)
:::info
- 在`ShuffleNet`中提出,隨機分組卷積包括分組卷積和通道洗牌(channel shuffle)
- 由於分組進行卷積後,會阻止不同組間的通道channel訊息交流,因此再後面的步驟輔以混合通道的方式,允許訊息在通道間流動,加強表徵學習效果
- 通道洗牌(channel shuffle)
- 混合來自不同組filters的信息。在下圖中,在將第一個分組卷積GConv1與3個filters組應用後,我們得到了特徵圖。在將此特徵圖傳到第二組卷積之前,首先將每組中的通道劃分為幾個子組合,再將這些子組合混合在一起
![](https://i.imgur.com/tZpdjOO.png =400x)
channel shuffle.
:::
### 基於串聯的模型縮放 Model Scaling for Concatenation-based Models
模型縮放的主要目的是調整模型的一些屬性並生成不同尺度的模型 以滿足不同推理速度的需要. 例如,`EfficientNet`的縮放模型考慮了 的寬度、深度和分辨率。
至於`scaled-YOLOv4`,其縮放模型是調整階段的數量。在《Fast and accurate model scaling》中,分析了在進行寬度和深度縮放時,卷積和分組卷積(group convolution)對參數和計算量的影響,並以此設計了相應的模型縮放方法。
- 基於串聯的模型的縮放 Model scaling for concatenation-based models
![](https://i.imgur.com/I1yaw3w.png =500x)
- 從圖(a)到(b)觀察到,當對基於串聯的模型進行深度縮放時,計算模塊(computational block)的輸出寬度也會增加。這一現象將導致後續傳輸層的輸入寬度 後續傳輸層的輸入寬度增加。
![](https://i.imgur.com/Wds8NnN.png =500x)
- 因此,本文團隊提出基於串聯的複合縮放方案,圖(c ),即在對進行模型縮放時,還需要對計算模塊(computational block)的深度(輸出通道)進行縮放,而對過渡層(transmission layer)的其餘部分則進行相應的寬度縮放
## Trainable BoF (Bag of Freebies)
模型重參數化(model re-parameterized)與動態標籤技術( dynamic label assignment)是近年神經網路訓練與物件偵測的重要議題,論文中著重在這兩個主題的改進
### 模型重參數化 model re-parameterization
Planned re-parameterized convolution
#### 模型重參數化技術
RepConv Module 重參數化示意
![](https://i.imgur.com/R3dma1C.png =300x)
source : [Target Detection Network for Underwater Image Based on Adaptive Anchor Frame and Re-parameterization](https://iopscience.iop.org/article/10.1088/1742-6596/2363/1/012012/meta)
模型重參數化技術可以被視為一種集成技術(ensemble),分為兩類,即模塊等級的集成和模型等級的集成
1. 模型等級的集成(model-level ensemble)
- 一種是用不同的訓練數據訓練多個相同的模型,然後對多個訓練模型的權重進行平均。另一種是對不同迭代次數的模型的權重進行加權平均。
2. 模塊等級的集成(module-level ensemble)
- 模塊級的重新參數化是最近比較流行的研究問題。這類方法在訓練時將一個模塊分成多個相同或不同的模塊分支,在推理時將多個分支模塊整合成一個完全等價的模塊。
#### 重參數化模型 Planned re-parameterized model
- 圖4為將`RepConv`/`RepConvN`融合至單純的卷基網路(`PlainNet`)與殘差網路(`Resnet`)的示意圖(詳細量化數據見消融試驗的結果一節)
==簡單來說就是示意`identity connection`的結構會破壞模型表現==
![](https://i.imgur.com/t8Uimov.png =800x)
- (a)與(b),表示直接使用`RepConv`取代單純卷積進行重參數化,不影響模型表現
- (c )與(d),在有`identity connection`的殘差網路中使用`RepConv`則會降低模型表現
- (e)與(f),將`RepConv`置於殘差網路不同位置的試驗,發現如果`RepConv`置於前,由於沒有identity的連接,不影響模型表現
- (g)與(h),若以`RepConvN`取代`RepConv`,則可任意置於殘差網路中不影響表現
`RepVGG`中採用`RepConv`的設計進行模型結構重參數化取得很好的成果,可以在精度(AP)與計算效能間達到很好的平衡。但`RepConv`應用在`ResNet`(residual)與`DenseNet`(concatenation)時卻出現了模型預測表現下降的問題,經分析後,yolov7團隊認為是`RepConv`中的恒等連接(`identity connection`)破壞了上述網路,降低特徵圖的梯度多樣性,導致模型表現下降
因此yolov7團隊將`RepConv`內的恒等連接移除以`RepConvN`取代進行試驗
- `RepConv` 與 `RepConvN` 結構示意
- `RepConvN` = `RepConv`(~~identity~~)
![](https://i.imgur.com/aUkdkV2.png =250x)
##### :pencil2:補充: `RepVGG`與Re-parameterization
- RepVGG與Re-parameterization
:::info
yolov7內的模型結構重參數化(Re-parameterization)為借鏡`RepVGG`的作法。
將訓練階段模型的參數映射到推理用模型,透過把多個運算模塊合併為一,簡化分支與縮小參數以提升運算時的效能訓練完捨棄原模型,只保存和部署轉換完(重參數化)的模型,而不是每次推理(inference)完都要轉換。
> 首先構造一系列結構(一般用於訓練),並將其參數等價轉換為另一組參數(一般用於推理),從而將這一系列結構等價轉換為另一系列結構。在現實場景中,訓練資源一般是相對豐富的,我們更在意推理時的開銷和性能,因此我們想要訓練時的結構較大,具備好的某種性質(更高的精度或其他有用的性質,如稀疏性),轉換得到的推理時結構較小且保留這種性質(相同的精度或其他有用的性質)。換句話說,“結構重參數化”這個詞的本意就是:用一個結構的一組參數轉換為另一組參數,並用轉換得到的參數來參數化(parameterize)另一個結構。只要參數的轉換是等價的,這兩個結構的替換就是等價的。
Re-parameterization可以視為模型壓縮的一種方法。其他常見的模型壓縮方法還包含模型剪裁(Pruning)、參數量化(Parameter Quantization)、知識蒸餾(Knowledge Distillation)等
![](https://i.imgur.com/vgASyT8.png =400x)
圖(B)為`RepVGG`訓練時的多分支架構,圖C為推理時的無分支架構。
透過參數重構(Re-parameterization)的設計,將訓練階段的多分支模型等架轉換為無分支模型
![image](https://hackmd.io/_uploads/Bk-no2Rrp.png =400x)
> ResNet的shortcut雖然不占計算量,卻增加了一倍的顯存占用
將1x1 conv與identity單位矩陣拓展為等效的3x3矩陣後,與3x3 conv直接相加達成多分枝合併為單支的實作
![image](https://hackmd.io/_uploads/S18l22ArT.png =400x)
- [2021.09.丁霄汉.RepVGG:极简架构,SOTA性能,让VGG式模型再次伟大(CVPR-2021)](https://zhuanlan.zhihu.com/p/344324470)
- [2021.04.丁霄汉结构重参数化:利用参数转换解耦训练和推理结构](https://zhuanlan.zhihu.com/p/361090497)
- [2022.12.Jack Sigmoid.深度解读:RepVGG](https://zhuanlan.zhihu.com/p/353697121)
:::
### 動態標籤分配策略 dynamic label assignment : Coarse for auxiliary and Fine for lead loss
#### 標籤分配 Label Assignment
標籤分配是物件偵測演算法的核心課題,指的是如何提供適當的正負樣本供神經網路學習,使其輸出正確期望的目標,在物件偵測任務中的樣本主要指的是物件位置(BBox)。
具體來說我們希望模型產出的預測框可以精準的框在目標物上,這時分配的正樣本標籤為1,如果完全沒有框住物體則給予負標籤0,但如果預測框有偏移僅包含部分目標區域則如何判定為正負樣本呢? 除此之外,目標物件通常只占畫面一小部分,容易造成正負樣本比例失衡,以上幾點是近年標籤分配演算法改善重點
- :pencil2:近年標籤分配策略發展方向
:::spoiler
- 從硬標籤(Hard Label。離散的0或1)->軟標籤(soft label。連續的機率分布)
- 硬標籤:根據預測框與真實(GT)框比較結果區分正負樣本,非正(1)即負(0)
- 軟標籤:類似softmax輸出,讓標籤在0-1之間的機率分布範圍內,允許標籤存在一定程度的不確定性與雜訊,更能傳遞預測結果與真實資料間的分佈及相關性,讓網路對預測結果不要太過信心避免過擬合。與近年Label Smoothing的概念有異曲同工之處
- 靜態(Static)->動態(Dynamic)
- 硬標籤根據正負樣本閥值是否會動態變化進一步區分
- 閥值判定依據: 基於先驗機率(prior)或預測結果(predict)
- 硬標籤根據先驗機率(prior)
- 基於距離、IOU等設置固定閥值判定正負樣本
- 軟標籤根據预测结果(predict)
- 根據預測結果與真實(GT)框計算軟標籤機率和正負權重,在候選正樣本(一般是與真實框有重疊)的基礎上,根據正負權重重新分配樣本並計算損失,在訓練過程動態調整軟標籤與正負權重
:::
#### 深度/中繼監督 Deep/Intermediate Supervision
- 深層監督示意圖
![](https://i.imgur.com/ObABIHx.png =350x)
圖5(a)為一般的網路、(b)為在中間層加入輔助頭(分類器)進行深層深度的網路
Deep supervision 深層/中間監督技術常見於訓練深層神經網路。主要概念是在神經網路的中間層抽取的特徵後面接上分類器(也就是輔助頭 auxiliary head),並計算Loss來評估中間層提取出的特徵品質,優化中間層的特徵學習能力。為了讓最後的輸出頭(淺層網路)主導最後訓練表現與方向,通常會設計不同的權重讓其維持主導地位
#### volov7的動態標籤分配與深層監督策略
:::success
釐清論文中使用的幾個名詞定義
- 主導頭(Lead head):負責最終預測結果的分類器
- 輔助頭(Auxiliary head):用於協助訓練的分類器。位於神經網路中間層
- 標籤分配器(Label assigner):將模型預測框與真實框同時考慮進行最佳化,然後分配軟標籤的機制
:::
- 圖5 Coarse for auxiliary and fine for lead head label assigner
![](https://i.imgur.com/qLwlDur.png =600x)
如何分配標籤給主導頭與輔助頭? 圖5(c )是目前多數演算法採用的方式,兩者間的標籤分配是獨立進行沒有關聯。
yolov7提出一種新的標籤分配方法,讓主導頭的預測結果同時指引輔導頭和主導頭的標籤分配。使用主導頭的預測結產生從粗到細的分層標籤,這些標籤被用於分別用於輔助頭和主導頭的學習。依序是Lead head guided label assigner與Coarse-to-fine lead head guided label assigner,圖5(d)與圖5(e)
##### Lead head guided label assigner 圖5(d)
- 根據主導頭預測框和真實框進行計算,並通過優化過程生成軟標籤。這組軟標籤將被用作輔助頭和主導頭的目標訓練模型
- 由於主導頭有相對較強的學習能力,所以由它生成的軟標籤 應該更能代表源數據和目標數據之間的分佈和相關性。此外,可以把這種學習看作是一種廣義的殘差學習。
- 通過讓輔助頭直接學習主導頭已經學到的信息,主導頭將能更專注於學習尚未學到的殘餘信息
- [code具體實現](https://link.zhihu.com/?target=https%3A//github.com/WongKinYiu/yolov7/blob/main/utils/loss.py%23L1205)
```python=
# Lead head
## loss of bounding box
lbox += (1.0 - iou).mean()
## loss of classification
lcls += self.BCEcls(ps[:, 5:], t)
# Aux head: weight=0.25
lbox += 0.25 * (1.0 - iou_aux).mean()
lcls += 0.25 * self.BCEcls(ps_aux[:, 5:], t_aux)
```
##### Coarse-to-fine lead head guided label assigner 圖5(e)
- 同上,只是產生的軟標籤按網路深淺分為兩組,即粗標籤(網路中間層)和細標籤(最後輸出層)
- fine label for lead head
- 細標籤的可優化的上界總是高於粗標籤(例如,給予Auxiliary head loss較小的權重,研究中是給0.25),讓主導頭的學習表現處於領導地位
- 從從高精度(Precision)的預測結果中,篩選高召回率(Recall)的結果作為最終輸出
- 物件檢測任務中常有正負樣本不平衡+低召回率的問題,這裡透過依序對Precision與Recall進行排序,選擇前topk的預測框來分配正負樣本,解決低召回率的問題
:::info
- 精度(Precision):在所有預測為正樣本中(現實世界可以完整取樣的,例如快篩陽性),確實為真實正樣本的比例。$TP / (TP +FP)$
- 召回率(Recall):在所有真實正樣本中(現實世界往往無法取得,例如所有真正染疫人數),被模型正確識別出的比例。$TP / (TP +FN)$
:::
- Coarse label for auxiliary head
![](https://i.imgur.com/MutZgBx.png =500x)
- 放鬆正樣本分配過程的約束,允許更多的網格被視為正樣本。從而產生較粗略的候選正樣本
- 為避免粗糙標籤的額外權重與精細標籤的權重太過接近導致較差的學習表現,作者在解碼器中設置了限制,降低額外的粗網格正樣本影響力
- demo code
實際code在[`yolov7/utils
/loss.py/def build_targets()`](https://link.zhihu.com/?target=https%3A//github.com/WongKinYiu/yolov7/blob/main/utils/loss.py%23L638)
```python=
def find_n_positive(n, anchors, targets):
"""
This function finds the top `n` anchors that are closest to each target
and considers them as positive samples.
"""
positive_indices = []
for target in targets:
# Calculate some distance metric between target and all anchors
distances = calculate_distances(target, anchors)
# Find indices of anchors with the top `n` smallest distances
top_n_indices = distances.argsort()[:n]
# Append these indices to the list of positive samples
positive_indices.append(top_n_indices)
return positive_indices
# Example usage
anchors = [...] # Define your anchors here
targets = [...] # Define your targets here
positive_samples_3nn = find_n_positive(3, anchors, targets)
positive_samples_5nn = find_n_positive(5, anchors, targets)
```
:::info
- Hard negative mining
這裡是在解決深度學習經典的困難負樣本挖掘(hard negative mining)問題
- Hard Negative
- 即不容易與正樣本分辨的模糊樣本,在物件檢測任務當中,可以理解為容易被當成有目標物件存在但實際是背景的負樣本、
- Easy Negative
- 容易被正確判定是沒有目標物件的負樣本(背景)。
物件檢測任中,模型在隨機產出候選框(anchor-based)或預測的關鍵點(anchor-free)時,特別是對於很小的物體會因背景佔多數而得到大量負樣本,導致正負樣本比例失衡問題,因此,需要特別選擇難以分辨的負樣本(hard negative)加入負樣本集,才能讓模型得到得到比較好的判別效果。
在YOLOv7採用的困難負樣本挖掘方法是,**訓練模型利用中間網路層(深層監督)產出的特徵圖學習初步分類,放寬對正樣本的限制來增加模型的判斷困難度**,對應前文所說不同階層的粗、細(Coarse-to-fine)概念。其中,輔助頭(分類器)得到的軟標籤(正負樣本判定數值),是根據導引頭(最後輸出的分類器)的預測結果優化得來(前文所說的guided label)
:::
ps: 在正負樣本分配上,yolov7使用了yoloX的`SimOTA`分配方法,與yolov5的分配方法進行融合。也就是simOTA中的第一步“使用中心先驗”替換成“yolov5中的策略”,提供了更加精確的先驗知識
- **SimOTA**
:::info
SimOTA 是由 YOLOX 提出的,其主要想法不僅在分配正樣本時考慮到 IoU,還會參考分類的結果。即根據 Classification Loss、Regression Loss 和 IoU Loss 進行 topK來進行前 K 名( topK)的標籤分配。
:::
- 圖8顯示了由不同的方法預測的 objectness map
![](https://i.imgur.com/eqhZ4cL.png =900x)
左邊的(b)與(c )是主導頭與輔助頭獨立運作、右邊的(d)與(e)是Lead head guided的結果。如果輔助頭學習了主導頭的軟標籤,它確實會幫助主導頭更能提取出未學習到的殘差訊息(residual information)
### Other Bag-of-Freebies tricks
- Batch normalization in conv-bn-activation topology
- Implicit knowledge in YOLOR combined with convolution feature map in addition and multiplication manner
- EMA model
## 其他附加功能
### 影像分割 yolo-mask(instance segmentation)
![](https://i.imgur.com/cH93VrJ.png =600x)
:::spoiler
- 整合BlendMask實現影像分割功能
- 使用 MS COCO 影像分割資料集訓練 30 epochs
![](https://i.imgur.com/OpBfp5Q.png =300x)
:::
### 人體姿態/骨架辨識 YOLO POSE(2D skeleton/pose estimation)
- 方法源自[arXiv:2204.06806。YOLO-Pose: Enhancing YOLO for Multi Person Pose Estimation Using Object Keypoint Similarity Loss](https://arxiv.org/abs/2204.06806)
![](https://i.imgur.com/Cvd3qBU.png =600x)
:::spoiler
- 整合YOLO-Pose實現影像人體姿態辨識功能
- 使用MS COCO keypoint detection資料集進行微調(YOLOv7-W6)
![](https://i.imgur.com/5aK10nm.png =200x)
:::
#### Label
- 人體關鍵點keypoints
人體關鍵點17個,每個點位包含{$x,y,conf$},其中conf為0、1或2,分別代表"不存在"、"存在但被遮擋"或"存在且不被遮擋",故和人體有關的label一個人包含17x3(3代表x、y、conf)=51個元素,bbox預測的label含有6個元素(x,y,w,h,box_conf,cls_conf),共51+6=57個元素,表達如下:
$$ P_{v} = \{C_{x}, C_{y}, W, H, box_{conf}, class_{conf}, K_{x}^{1}, K_{y}^{1}, K_{conf}^{1}, \cdots, K_{x}^{n}, K_{y}^{n}, K_{conf}^{n}\} $$
---
## 參考資料
### YOLOv7
#### [2023.03。【YOLOv7成功關鍵:技術篇】關鍵人物親自揭露三大突破,下一步攻多任務與解釋性](https://www.ithome.com.tw/news/156081)
針對技術改進部分有提供直白解釋
#### [圖解yolov7 architecture (1/2)](https://www.youtube.com/watch?v=Ot__47ItjDs)
- [圖解 YOLOv7 loss (2/2)](https://www.youtube.com/watch?v=EhXwABGhBrw)
- 詳盡清楚的影片教學。其他物件偵測相關的教學影片也值得看
- 補充了物件檢測標籤分配的重要概念OTA - Optimal Transport Assignmen等,如果要深入理解object detection演算法的話推薦看
![image](https://hackmd.io/_uploads/r1cNyblLT.png)
#### [YOLO系列目标检测算法-YOLOv7](https://blog.csdn.net/qq_39707285/article/details/126827583)
#### [YOLOv7 Object Detection Paper Explanation & Inference](https://learnopencv.com/yolov7-object-detection-paper-explanation-and-inference/)
- learnopencv.com 有一系列非常好的教學影片、圖文與demo code
- 物件偵測基本評估 [Mean Average Precision (mAP) in Object Detection](https://learnopencv.com/mean-average-precision-map-object-detection-model-evaluation-metric/)
#### [YOLOv7を完全に理解した(YOLOv7の論文を読んでみた)](https://dev.classmethod.jp/articles/yolov7-architecture-overall/#toc-11)
雖然是日文 但介紹的滿簡潔,另外有很清楚的模型架構圖
#### [YOLO家族系列模型的演变:从v1到v8](https://cloud.tencent.com/developer/article/2212232?areaSource=104001.4&traceId=bTXJdiCqPM48qF63XTtFY)
### Object Detection
- [Object Detection in 20 Years: A Survey](https://arxiv.org/abs/1905.05055)
有整理不錯的重要課題與技術演進
![](https://i.imgur.com/SkYtkg1.png =600x)
#### Re-parameterizing
- [RepVGG: Making VGGstyle convnets great again](https://arxiv.org/abs/2101.03697)
- [結構重參數化:利用參數轉換解耦訓練和推理結構](https://zhuanlan.zhihu.com/p/361090497)
#### Hard Negative Mining
- [Hard Negative Mining/OHEM](https://zhuanlan.zhihu.com/p/78837273)
#### Label Assignment
- [YOLOX Explanation — SimOTA For Dynamic Label Assignment](https://medium.com/mlearning-ai/yolox-explanation-simota-for-dynamic-label-assignment-8fa5ae397f76)
- [Bridging the Gap Between Anchor-based and Anchor-free Detection via Adaptive Training Sample Selection](https://arxiv.org/abs/1912.02424)
- [Label Assign:提升目标检测上限](https://zhuanlan.zhihu.com/p/160991530)
- [一文看懂Label Assignment--标签分配最新论文总结](https://zhuanlan.zhihu.com/p/395386669)
#### others
- [A Comprehensive Introduction to Different Types of Convolutions in Deep Learning](https://towardsdatascience.com/a-comprehensive-introduction-to-different-types-of-convolutions-in-deep-learning-669281e58215)
- [中文參考](https://www.zhihu.com/question/280728799)
## Deep Learning相關筆記
### Self-supervised Learning
- [[Self-supervised] Self-supervised Learning 與 Vision Transformer重點筆記與近期發展](https://hackmd.io/7t35ALztT56STzItxo3UiA)
- [[Time Series] - TS2Vec(Towards Universal Representation of Time Series) 論文筆記](https://hackmd.io/OE9u1T9ETbSdiSzM1eMkqA)
### Object Detection
- [[Object Detection_YOLO] YOLOv7 論文筆記](https://hackmd.io/xhLeIsoSToW0jL61QRWDcQ)
### ViT與Transformer相關
- [[Transformer_CV] Vision Transformer(ViT)重點筆記](https://hackmd.io/tMw0oZM6T860zHJ2jkmLAA)
- [[Transformer] Self-Attention與Transformer](https://hackmd.io/fmJx3K4ySAO-zA0GEr0Clw)
- [[Explainable AI] Transformer Interpretability Beyond Attention Visualization。Transformer可解釋性與視覺化](https://hackmd.io/SdKCrj2RTySHxLevJkIrZQ)
- [[Transformer_CV] Masked Autoencoders(MAE)論文筆記](https://hackmd.io/lTqNcOmQQLiwzkAwVySh8Q)
### Autoencoder相關
- [[Autoencoder] Variational Sparse Coding (VSC)論文筆記](https://hackmd.io/MXxa8zesRhym4ahu7OJEfQ)
- [[Transformer_CV] Masked Autoencoders(MAE)論文筆記](https://hackmd.io/lTqNcOmQQLiwzkAwVySh8Q)