# YOLO series comparsion [TOC] ## intro 先大致介紹一下 YOLO 的辨識流程,我們如果訓練好 model 後就可以透過輸入照片、影片 (e.g., 車前方的道路狀況等) 與這個模型 (權重) 做計算將特徵提取出來後,最終去預測 (e.g., 車輛控制信號)。那資料送入這個模型後的整理流程如下: ``` 影像輸入 ↓ [ Backbone ] ← 特徵抽取 (Feature Extraction) ↓ [ Neck ] ← 特徵融合 (Feature Fusion / Aggregation) ↓ [ Head ] ← 邊界框與分類預測 (Detection Output) ↓ 輸出目標框與分類結果 ``` - Backbone (主幹): ``` e.g., input: 640 * 640 * 3 之 RGB 圖片 output: 多尺寸輸出 80 * 80 * 256 & 40 * 40 * 512 ... ``` - 提取特徵,也就是卷積層 - 會用到的運算: - Conv2D - BatchNorm: 對每一層的輸入做 normalization - pros: 可以減緩梯度消失的問題發生 - Activation Funt.: ReLU, LeakyReLU, Sigmoid - Downsampling (下採樣): 縮小圖,放大語義 - pros: 減少卷積計算量 - e.g., pooling, stride conv - Neck ``` e.g., input: 多尺寸輸入 80 * 80 * 256 & 40 * 40 * 512 ... output: 多尺寸融合特徵輸出 80 * 80 * 256 & 40 * 40 * 512 ... ``` - 把在主幹中得到的很多 channel 的資訊融合、提取不同層級的特徵圖 - 會用到的運算: - Downsampling - Upsampling (上採樣): 放大圖 - e.g., 雙線性插值 - Concat: 通道疊在一起 - 卷積融合: 疊完通道或是加完可以做的卷積,用來讓組合是非線性的 - Head: ``` e.g., input: 多尺寸特徵 output: 預測張量 (bounding box 座標 (框出物件的框框), 預測機率等) ``` - 把在 Neck 拿到的資訊做成預測的邊框 - 會用到的運算: - Conv - Sigmoid/Softmax: 分類 for YOLO: 最後 head 得到的 tensor 會再通過 Non-Maximum Supperssion (NMS) 這個 post-processing 可以想成就是我在 head 那邊拿到很多框框還有很多機率。 (假設圖片角落有一隻狗且有被辨識出來) 那對於圖片角落裡的那隻狗來說到底哪一個框框才是最大的把它框住的框? 不決定這件事的話可能會導致好幾個框重疊,最後要統計物件種類個數時會計算錯誤。 ## 硬體友善度 gen. by ChatGPT 因為我們需要透過 RTL 實作出整體網路架構,因此我先針對實作的複雜度進行篩選,因此接下來會比較 v5 and v6。 ![image](https://hackmd.io/_uploads/rkAormzRlx.png) ## YOLO v5 arch:![image](https://hackmd.io/_uploads/Hya5RQf0gx.png) ### focus layer 進入 Backbone 前,對圖片進行切片操作,具體操作是將圖像相鄰的四個位置進行堆疊,類似於鄰近下採樣,這樣就拿到了四張圖片,四張圖片互補,長的差不多,但是沒有信息丟失,將 W 和 H 信息就集中到了通道空間,輸入通變成了原本的 4 倍,即拼接起來的圖片相對於原先的 RGB 三通道模式變成了 12 個通道,最後將得到的新圖片再經過卷積操作,最終得到了沒有信息丟失情況下的二倍下採樣特徵圖,如下圖所示。 ![image](https://hackmd.io/_uploads/HksUJVfCle.png) ### Conv: 卷積 + BatchNorm + SiLU (圖片好像誤植成 HardSwish) - SiLU v.s. HardSwish ![image](https://hackmd.io/_uploads/Bk8-L4GRel.png) ![image](https://hackmd.io/_uploads/r14X84GAeg.png) 但實作起來 HardSwish 會比較好做,sigmoid 需要 LUT or approximation ### Cross Stage Partial Network (CSP) 有兩種 CSP 結構,看圖的話可以看他有沒有 bottleneck,若為 true 則加上 residual (output = 計算完的 output + input) residual pros: 避免因為加深而帶來的梯度消失 ### Spatial Pyramid Pooling (SPP) 解決「輸入尺寸固定」的問題 (原始目的) 在 fully connect layer 之前把任意尺寸的特徵圖變成固定長度的特徵向量 就是在做 max pooling ### FPN + PAN FPN (Feature Pyramid Network):實現自上而下 (Top-down) 的路徑,將語義信息(深層特徵)傳遞給淺層特徵。 Path Aggregation Network (PANet):在 FPN 之後,新增一條自下而上 (Bottom-up) 的路徑,將定位信息(淺層特徵)傳遞給深層特徵。 作用: 這種雙向的特徵融合(FPN + PANet)讓網路可以同時擁有準確的物體定位能力 (來自淺層) 和豐富的物體語義信息 (來自深層),是提升小物體檢測性能的關鍵。 Upsample (上採樣層):用於 Neck 結構中,將低解析度的特徵圖恢復到高解析度,以便與淺層特徵圖進行拼接融合。 ## YOLO v6 arch: ![image](https://hackmd.io/_uploads/SyMLa4z0ee.png) ### EfficientRep Backbone ![image](https://hackmd.io/_uploads/Hkx5sNzRee.png) 其核心是「RepVGG-style 重參化結構」。 優點: - 推理時結構更簡單(加速友好) - 保留訓練時的特徵融合能力 - 更容易在 FPGA / ASIC 上 mapping 為單一卷積模組 關鍵模組: - RepBlock: 類似 CSP Block,但在推論階段可合併成單層卷積 - SimConv: 一般 Conv + BN + SiLU,用於特徵轉換 - ReLU6 / SiLU / HardSwish 可依版本不同使用(n/s/b 版本略有差異) ### Rep-PAN YOLOv6 的 Neck 採用改良過的 PAN 結構,稱為 Rep-PAN。 與 YOLOv5 的 FPN+PAN 類似,但所有卷積層都改成 RepConv(重參化卷積),以提升硬體部署效能。 特點: - 雙向特徵融合(top-down + bottom-up)仍保留 - 全部卷積模組可在推理時合併(減少運算開銷) - 適合 FPGA pipeline 實現,branch-less 結構有助於 timing closure ### Decoupled Head YOLOv6 最大的變化之一是 Decoupled Head。 傳統 YOLO(含 v5)在 head 階段共用同一個卷積分支來預測: - 類別(classification) - 邊界框(bbox regression) - 置信度(objectness) 而 YOLOv6 拆成兩個分支: - 分類分支 (cls head):專注於類別分類 - 定位分支 (reg head):專注於框位置回歸 優點: - 減少任務之間的干擾,訓練更穩定 - 精度提升約 1~2% mAP - 適合硬體中平行化實作(兩路 pipeline) 預設使用 SiLU (Sigmoid Linear Unit),但在 Nano / Small 版本中可切換成 ReLU / Hard-Swish 以減少計算負擔。 ## Model comparsion | Model | Size<br><sup>(pixels) | mAP<sup>val<br>50-95 | mAP<sup>val<br>50 | Speed<br><sup>CPU b1<br>(ms) | Speed<br><sup>V100 b1<br>(ms) | Speed<br><sup>V100 b32<br>(ms) | Params<br><sup>(M) | FLOPs<br><sup>@640 (B) | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------- | -------------------- | ----------------- | ---------------------------- | ----------------------------- | ------------------------------ | ------------------ | ---------------------- | | [YOLOv5n](https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5n.pt) | 640 | 28.0 | 45.7 | **45** | **6.3** | **0.6** | **1.9** | **4.5** | | [YOLOv5s](https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5s.pt) | 640 | 37.4 | 56.8 | 98 | 6.4 | 0.9 | 7.2 | 16.5 | | [YOLOv5m](https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5m.pt) | 640 | 45.4 | 64.1 | 224 | 8.2 | 1.7 | 21.2 | 49.0 | | [YOLOv5l](https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5l.pt) | 640 | 49.0 | 67.3 | 430 | 10.1 | 2.7 | 46.5 | 109.1 | | [YOLOv5x](https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5x.pt) | 640 | 50.7 | 68.9 | 766 | 12.1 | 4.8 | 86.7 | 205.7 | | Model | Size | mAP<sup>val<br/>0.5:0.95 | Speed<sup>T4<br/>trt fp16 b1 <br/>(fps) | Speed<sup>T4<br/>trt fp16 b32 <br/>(fps) | Params<br/><sup> (M) | FLOPs<br/><sup> (G) | | :----------------------------------------------------------- | ---- | :----------------------- | --------------------------------------- | ---------------------------------------- | -------------------- | ------------------- | | [**YOLOv6-N**](https://github.com/meituan/YOLOv6/releases/download/0.4.0/yolov6n.pt) | 640 | 37.5 | 779 | 1187 | 4.7 | 11.4 | | [**YOLOv6-S**](https://github.com/meituan/YOLOv6/releases/download/0.4.0/yolov6s.pt) | 640 | 45.0 | 339 | 484 | 18.5 | 45.3 | | [**YOLOv6-M**](https://github.com/meituan/YOLOv6/releases/download/0.4.0/yolov6m.pt) | 640 | 50.0 | 175 | 226 | 34.9 | 85.8 | | [**YOLOv6-L**](https://github.com/meituan/YOLOv6/releases/download/0.4.0/yolov6l.pt) | 640 | 52.8 | 98 | 116 | 59.6 | 150.7 | 可能要推算一下 fps KPI 然後對應上一張照片的 FLOPs 去抓我們的加速器要能夠用上多快的速度去算卷積,以及推算一下 memory size,params * int8 (1Byte) 是預計會使用到的 memory space for weight and bias