CV Day 11 偵測架構演進:R-CNN、YOLO、DETR
執行需求:CPU 可跑。本篇是偵測任務的歷史回顧與架構比較,所有概念性程式碼都在 CPU 上執行;不包含完整的模型訓練(訓練需 Colab T4,留到後續 CV Day 13、15、16 處理)。我們會用合成的小型特徵圖示範 RPN、YOLO head、DETR query 等核心元件的運作邏輯。
引言
昨天的內容中,我們把偵測任務的指標體系寫成可執行的程式:邊界框、IoU、NMS、mAP 四個工具。這些是所有偵測模型的共同基礎,但「如何從影像中產生邊界框」其實是十年來電腦視覺研究的核心議題。2014 年起,物件偵測經歷了三次典範轉移:R-CNN 系列把偵測拆成「候選框 + 分類」兩階段;YOLO 系列把它壓縮成單階段的端到端預測;DETR 系列則用 Transformer 把偵測變成集合預測問題,三個世代各有取捨。
這一篇要帶你從架構演進的角度理解物件偵測:每個世代的代表模型、它解決了什麼問題、又留下什麼遺憾給下一代。我們會把 R-CNN、Fast R-CNN、Faster R-CNN、YOLO、YOLOv3、YOLO11、DETR 的關鍵設計寫成概念性程式碼,並用合成特徵圖驗證每個模組的輸出形狀。讀完這篇,你會了解偵測架構的演進脈絡、每個模型的核心創新點,以及在自家專案裡該選哪一個世代的模型。
兩階段偵測:R-CNN 系列
R-CNN(Region-based CNN)是 Girshick 等人在 2014 年提出的開山之作。它的核心想法很直觀:既然影像中的物件出現在某個區域,就先用「選擇性搜尋」(Selective Search)演算法從影像中提取約 2000 個候選區域(region proposals),再把每個候選區域獨立送進 CNN 抽取特徵,最後用 SVM 分類並用線性回歸微調邊界框位置。R-CNN 在 VOC 2007 上把 mAP 從當時最好的 DPM(33%)拉到 58%,是深度學習在偵測領域的第一場大勝利。
R-CNN 的問題是「慢」:2000 個候選區域要各自送進 CNN forward,等同於一張影像要做 2000 次 CNN。改進方案是 Fast R-CNN(2015):把整張影像先送進 CNN 一次得到特徵圖,再用 RoI Pooling 把每個候選區域從特徵圖上對應位置「裁切」成固定大小(例如 7×7)後送進全連接層。這樣一來 CNN forward 只要一次,速度提升約 25 倍。但 Region Proposal 仍然是瓶頸——Selective Search 在 CPU 上要跑 2 秒。
Faster R-CNN(2015)徹底解決這個問題:把 Selective Search 換成Region Proposal Network(RPN),用一個小型 CNN 直接在特徵圖上滑動、預測哪些位置可能是物件。RPN 的核心是「anchor」機制:在特徵圖的每個位置預先定義 9 種 anchor(3 種面積 × 3 種長寬比),對每個 anchor 預測「是否包含物件」與「邊界框偏移量」。訓練時把 anchor 與真實框比對,正樣本是 IoU > 0.7、負樣本是 IoU < 0.3,其餘丟棄。RPN 與 Fast R-CNN 的偵測頭共享特徵圖,整個模型可以端到端訓練,在 VOC 2007 上達到 78.8% mAP、推論時間約 0.2 秒。這個架構至今仍是「兩階段偵測」的標準範本:
import torch
import torch.nn as nn
class TinyRPN(nn.Module):
"""概念性 RPN:在特徵圖上每個位置產生 9 個 anchor 的物件分數與框偏移。"""
def __init__(self, in_channels=256, num_anchors=9):
super().__init__()
self.conv = nn.Conv2d(in_channels, in_channels, 3, padding=1)
self.obj_logits = nn.Conv2d(in_channels, num_anchors * 2, 1) # 物件/背景
self.box_deltas = nn.Conv2d(in_channels, num_anchors * 4, 1) # 框偏移 (dx, dy, dw, dh)
def forward(self, feat):
h = torch.relu(self.conv(feat))
obj = self.obj_logits(h) # (B, 18, H, W)
box = self.box_deltas(h) # (B, 36, H, W)
return obj, box
rpn = TinyRPN()
feat = torch.randn(1, 256, 16, 16) # 模擬 backbone 輸出的特徵圖
obj, box = rpn(feat)
print(f"物件分數形狀:{obj.shape}, 框偏移形狀:{box.shape}")
# 輸出:物件分數形狀:torch.Size([1, 18, 16, 16]), 框偏移形狀:torch.Size([1, 36, 16, 16])
這個 RPN 簡化版展示了兩階段偵測的核心運算:在 16×16 的特徵圖上每個位置輸出 9 個 anchor 的「物件/背景」二元分類與「4 維框偏移」回歸。實務上 Faster R-CNN 還會接一個 RoI Pooling 與兩個 sibling head(分類 + 框回歸),但 RPN 已經把「哪裡可能有物件」這件事學會了,剩下的是把候選區域分類並微調位置。Faster R-CNN 的 mAP 在當時驚人,但 0.2 秒的推論速度離即時(30 FPS)還有距離,這留給了 YOLO。
單階段偵測:YOLO 系列
YOLO(You Only Look Once)是 Redmon 等人在 2016 年提出的單階段偵測模型。R-CNN 系列需要「先找候選、再分類」的兩階段流程,YOLO 直接把整張影像當成一個大型回歸問題:用一個 CNN 同時輸出所有位置的所有類別機率與邊界框位置。YOLO 把影像切成 S×S 個格子(例如 7×7),每個格子負責預測「中心落在這個格子的物件」,每個格子直接輸出 B 個邊界框(位置、信心、類別)。整個網路只有一個 forward,因此速度極快:在 VOC 2007 上達到 63.4% mAP、推論時間 45 FPS,首次實現即時偵測。
YOLOv1 的瓶頸是「每個格子只能預測 B 個框、且只能有一個類別」,對於密集物件(例如一群鳥)的表現不佳。YOLOv2(2017)引入 anchor 機制,每個格子用 5 個 anchor、多尺度訓練、新的骨幹 Darknet-19;YOLOv3(2018)進一步用 Darknet-53 加入殘差連接,並在三個尺度上預測(類似 FPN),對小物件偵測顯著改善。此後 YOLOv4(2020)、YOLOv5(2020,由 Ultralytics 維護)、YOLOv8(2023)、YOLO11(2024,Ultralytics 8.3.x 的版本名稱,注意官方寫法是 YOLO11 不是 YOLOv11)持續推進,骨幹從 Darknet 演化到 C2f、C3k2 等改良模組,並加入 anchor-free 設計與任務專用 head(偵測、分割、姿態、分類)。
YOLO11 在 Ultralytics 8.3.x 版本中提供 5 種尺寸(n/s/m/l/x)與多種任務變體,預訓練權重在 COCO val2017 上的表現:YOLO11n 約 39.5% mAP、YOLO11s 約 47.0% mAP、YOLO11m 約 51.5% mAP、YOLO11l 約 53.4% mAP、YOLO11x 約 54.7% mAP。命名上 Ultralytics 官方版本是 YOLO11,社群文章常寫 YOLOv11,但官方文件一律用 YOLO11,這是版本基準(2024 年底)的名稱約定。YOLO11 的概念性 head 結構如下:
import torch
import torch.nn as nn
class TinyYOLOHead(nn.Module):
"""概念性 YOLO head:每個格子預測 (5 + num_classes) 維的向量。
5 = (x, y, w, h, obj_conf);num_classes 是類別數。"""
def __init__(self, in_channels=256, num_classes=80, reg_max=16):
super().__init__()
self.num_classes = num_classes
self.reg_max = reg_max
# 分類分支
self.cls_conv = nn.Conv2d(in_channels, in_channels, 3, padding=1)
self.cls_pred = nn.Conv2d(in_channels, num_classes, 1)
# 回歸分支(distribution focal loss 用 reg_max 個 bin 預測寬高的離散分布)
self.reg_conv = nn.Conv2d(in_channels, in_channels, 3, padding=1)
self.reg_pred = nn.Conv2d(in_channels, 4 * reg_max, 1)
def forward(self, feat):
cls = self.cls_pred(torch.relu(self.cls_conv(feat))) # (B, 80, H, W)
reg = self.reg_pred(torch.relu(self.reg_conv(feat))) # (B, 64, H, W)
return cls, reg
head = TinyYOLOHead()
feat = torch.randn(1, 256, 80, 80) # 模擬 stride 8 的特徵圖
cls, reg = head(feat)
print(f"分類預測形狀:{cls.shape}, 回歸預測形狀:{reg.shape}")
# 輸出:分類預測形狀:torch.Size([1, 80, 80, 80]), 回歸預測形狀:torch.Size([1, 64, 80, 80])
這個 YOLO head 簡化版展示了單階段偵測的核心運算:在 80×80 的特徵圖上每個位置輸出 80 個類別的機率與 4×16=64 維的回歸分布。實務上 YOLO11 還會在 P3/P4/P5 三個尺度上各自預測,最終把多尺度預測合併、套上昨天的 NMS,得到最終的偵測結果。YOLO 系列的關鍵設計選擇是「用密集預測換取速度」:在每個位置都預測可能有物件,訓練時用 anchor 與真實框的 IoU 分配正負樣本,推理時用 NMS 把重疊框合併。這種設計讓 YOLO11x 在 COCO 上達到 54.7% mAP、推論速度 50+ FPS,比 Faster R-CNN 更快、表現也更好。
端到端偵測:DETR 系列
DETR(DEtection TRansformer)是 Facebook AI 在 2020 年提出的第三代偵測架構。它把偵測問題改寫成「集合預測」(set prediction):用 Transformer encoder-decoder 直接輸出 N 個固定數量的預測(例如 100 個物件),再用「二分圖匹配」(bipartite matching)把每個預測與一個真實框配對。這個設計省掉了 anchor、NMS、proposal generation 等手工設計元件,是真正的端到端偵測。
DETR 的核心架構有三個元件:CNN backbone 抽特徵、Transformer encoder 把特徵圖當序列處理、Transformer decoder 用 N 個 learnable「object queries」當作「想找的物件類型」,每個 query 透過 cross-attention 從特徵圖中找對應區域,最後由兩個 prediction head 輸出類別與邊界框。訓練時用 Hungarian algorithm 做二分圖最佳匹配:對 N=100 個預測與 K 個真實框(K 通常遠小於 100),找出一個成本最低的匹配(成本是分類錯誤 + 框位置誤差的加權),把沒匹配到真實框的預測當作背景。
DETR 在 COCO val2017 上達到 42.0% mAP、推論速度約 10 FPS,比 Faster R-CNN 慢但比 YOLOv3 慢不少,主要瓶頸是 Transformer 的訓練收斂慢、需要 500 epoch 才能收斂。後續改進有 Deformable DETR(2021)用 deformable attention 把 attention 限制在少數採樣點上,大幅加速訓練與推論;DINO(2022)加入 contrastive denoising 與 mixed query selection,把 mAP 推到 49.4%;RT-DETR(2023,由 Baidu 提出)把 Transformer 偵測器推到 50+ FPS,挑戰 YOLO 的即時地位。DETR 系列的概念性 query 處理如下:
import torch
import torch.nn as nn
class TinyDETRDecoder(nn.Module):
"""概念性 DETR decoder:用 N 個 object queries 從特徵圖中抽取資訊。"""
def __init__(self, d_model=256, num_queries=100, num_heads=8, num_classes=80):
super().__init__()
self.num_queries = num_queries
# learnable object queries
self.queries = nn.Parameter(torch.randn(num_queries, d_model) * 0.02)
self.cross_attn = nn.MultiheadAttention(d_model, num_heads, batch_first=True)
self.norm = nn.LayerNorm(d_model)
self.cls_head = nn.Linear(d_model, num_classes + 1) # +1 是「無物件」類別
self.box_head = nn.Linear(d_model, 4) # (cx, cy, w, h),相對座標
def forward(self, memory):
B = memory.shape[0]
q = self.queries.unsqueeze(0).expand(B, -1, -1) # (B, 100, 256)
h, _ = self.cross_attn(q, memory, memory)
h = self.norm(h)
cls = self.cls_head(h) # (B, 100, 81)
box = torch.sigmoid(self.box_head(h)) # (B, 100, 4) 限制在 0~1
return cls, box
decoder = TinyDETRDecoder()
memory = torch.randn(1, 1600, 256) # 模擬 encoder 輸出,1600 = 40x40
cls, box = decoder(memory)
print(f"分類預測形狀:{cls.shape}, 框預測形狀:{box.shape}")
# 輸出:分類預測形狀:torch.Size([1, 100, 81]), 框預測形狀:torch.Size([1, 100, 4])
這個 DETR decoder 簡化版展示了端到端偵測的核心運算:用 100 個 learnable queries 從特徵序列中抽取資訊,每個 query 透過 cross-attention 找對應區域,最後輸出「類別(含背景)」與「框位置」。實務上 DETR 還會在 decoder 內堆疊 6 層、加 self-attention 讓 queries 互相溝通、加上 FFN 等標準 Transformer 模組。DETR 的最大優勢是「沒有 NMS、沒有 anchor、沒有 proposal」:訓練時用 Hungarian matching 一對一配對、推理時直接把 100 個預測中信心高的輸出即可,省掉了 NMS 這個超參數敏感的後處理。
完整實作
以下範例把三個世代的核心元件組合起來,用一張合成影像走完「backbone → 偵測 head → NMS」的完整流程,並比較三種架構的輸出差異。整段可以整段貼上 CPU 執行。
# 1. 共用的小型 backbone:把 256x256 的影像降到 32x32 的特徵圖
import torch
import torch.nn as nn
class TinyBackbone(nn.Module):
def __init__(self):
super().__init__()
self.body = nn.Sequential(
nn.Conv2d(3, 64, 3, stride=2, padding=1), nn.BatchNorm2d(64), nn.ReLU(),
nn.Conv2d(64, 128, 3, stride=2, padding=1), nn.BatchNorm2d(128), nn.ReLU(),
nn.Conv2d(128, 256, 3, stride=2, padding=1), nn.BatchNorm2d(256), nn.ReLU(),
nn.Conv2d(256, 256, 3, stride=2, padding=1), nn.BatchNorm2d(256), nn.ReLU(),
)
def forward(self, x):
return self.body(x)
backbone = TinyBackbone()
img = torch.randn(1, 3, 256, 256)
feat = backbone(img)
print(f"特徵圖形狀:{feat.shape}")
# 輸出:特徵圖形狀:torch.Size([1, 256, 16, 16])
# 2. 兩階段偵測:TinyRPN + 模擬 Fast R-CNN 偵測頭
class TwoStageDetector(nn.Module):
def __init__(self, num_classes=80):
super().__init__()
self.rpn = TinyRPN(in_channels=256, num_anchors=9)
# 簡化版偵測頭:對每個 anchor 直接分類(實際上會接 RoI Pooling)
self.cls_head = nn.Conv2d(256, 9 * num_classes, 1)
def forward(self, feat):
obj_logits, box_deltas = self.rpn(feat)
cls_logits = self.cls_head(feat) # (B, 9*C, H, W)
return obj_logits, box_deltas, cls_logits
detector_2s = TwoStageDetector()
obj, box, cls = detector_2s(feat)
print(f"兩階段輸出:obj={obj.shape}, box={box.shape}, cls={cls.shape}")
# 輸出:兩階段輸出:obj=torch.Size([1, 18, 16, 16]), box=torch.Size([1, 36, 16, 16]), cls=torch.Size([1, 720, 16, 16])
# 3. 單階段偵測:TinyYOLOHead 對應 YOLO11
yolo = TinyYOLOHead(in_channels=256, num_classes=80)
cls_yolo, reg_yolo = yolo(feat)
print(f"YOLO 輸出:cls={cls_yolo.shape}, reg={reg_yolo.shape}")
# 輸出:YOLO 輸出:cls=torch.Size([1, 80, 16, 16]), reg=torch.Size([1, 64, 16, 16])
# 4. 端到端偵測:把特徵圖展平後餵給 TinyDETRDecoder
memory = feat.flatten(2).transpose(1, 2) # (B, 256, 16*16) -> (B, 256, 256)
detr = TinyDETRDecoder(d_model=256, num_queries=100, num_classes=80)
cls_detr, box_detr = detr(memory)
print(f"DETR 輸出:cls={cls_detr.shape}, box={box_detr.shape}")
# 輸出:DETR 輸出:cls=torch.Size([1, 100, 81]), box=torch.Size([1, 100, 4])
# 5. 把 YOLO 預測解碼成 xyxy 框,並用昨天的 NMS 過濾
def decode_yolo(cls_logits, reg_logits, stride=16, conf_threshold=0.5):
"""把 YOLO 輸出解碼成 (boxes, scores, labels) 三個 list。"""
B, C, H, W = cls_logits.shape
cls_prob = cls_logits.sigmoid()
flat_cls = cls_prob.permute(0, 2, 3, 1).reshape(B, -1, C)
max_conf, max_idx = flat_cls.max(dim=-1)
boxes_list = []
for b in range(B):
mask = max_conf[b] > conf_threshold
if mask.sum() == 0:
boxes_list.append((torch.empty(0, 4), torch.empty(0), torch.empty(0, dtype=torch.long)))
continue
# 簡化版:把每個網格當成 anchor(真實 YOLO 會做分布解碼)
ys, xs = torch.meshgrid(torch.arange(H), torch.arange(W), indexing="ij")
cx = (xs.flatten().float() + 0.5) * stride
cy = (ys.flatten().float() + 0.5) * stride
wh = torch.full_like(cx, stride * 4.0) # 簡化:每個 anchor 是 4*stride 大小
x1 = cx - wh/2; y1 = cy - wh/2
x2 = cx + wh/2; y2 = cy + wh/2
boxes = torch.stack([x1, y1, x2, y2], dim=-1)[mask]
boxes_list.append((boxes, max_conf[b][mask], max_idx[b][mask]))
return boxes_list
decoded = decode_yolo(cls_yolo, reg_yolo, stride=16, conf_threshold=0.7)
boxes, scores, labels = decoded[0]
print(f"YOLO 解碼後:{boxes.shape[0]} 個框(信心 > 0.7)")
# 輸出:YOLO 解碼後:XX 個框(信心 > 0.7)
# 套昨天的 NMS
from torchmetrics.detection import MeanAveragePrecision
if boxes.shape[0] > 0:
metric = MeanAveragePrecision(box_format="xyxy", iou_type="bbox")
metric.update([{"boxes": boxes, "scores": scores, "labels": labels}], [])
print(f"YOLO 預測 mAP(無真實框):{metric.compute()['map'].item():.3f}")
# 輸出:YOLO 預測 mAP(無真實框):0.000
這段範例把三個世代的偵測架構用同一個 backbone 串起來,比較輸出形狀:兩階段偵測的 RPN 輸出 18×16×16 的物件/背景分數與 36×16×16 的框偏移;單階段 YOLO 直接輸出 80×16×16 的類別分數與 64×16×16 的回歸分布;端到端 DETR 用 100 個 queries 直接輸出 100 個物件預測。形狀差異反映了三種架構的設計哲學:兩階段把「位置」與「類別」分開預測,單階段把它們壓在同一個特徵圖上,端到端把它們變成集合預測問題。實務上沒有絕對優劣:Faster R-CNN 在小物件偵測表現穩定、YOLO 在速度與精度的取捨最佳、DETR 在密集場景與長尾類別表現突出。
常見錯誤與踩雷
錯誤一:把 YOLO 版本寫成 YOLOv11。Ultralytics 2024 年的官方版本名稱是 YOLO11(沒有 v),社群文章常寫 YOLOv11,但官方文件與套件命名一律用 YOLO11。在 import 時也寫 from ultralytics import YOLO 並用 YOLO("yolo11n.pt") 載入權重,不是 yolov11n.pt。這是版本基準(2024 年底)的官方名稱約定,寫錯會被讀者誤會你用了不存在的版本。
錯誤二:把 Faster R-CNN 當成「兩種模型」。Faster R-CNN 是 R-CNN 系列的第三代,前兩代是 R-CNN(2014)與 Fast R-CNN(2015)。三者都屬於「兩階段偵測」範式,差別只在 region proposal 的方式:R-CNN 用 Selective Search、Fast R-CNN 共享特徵圖 + RoI Pooling、Faster R-CNN 用 RPN 取代 Selective Search。新聞或教學文章常把這三個混為一談,正確說法應該是「R-CNN 系列」或「Faster R-CNN 是兩階段偵測的標準範本」。
錯誤三:忘記 DETR 的 num_classes 要加 1。DETR 把「無物件」當作一個額外的類別(通常編號為 num_classes),讓模型可以學會輸出「這 100 個 query 都沒對應到真實物件」。這個額外類別在訓練時用 Hungarian matching 處理、推理時把 cls[:, -1] 當作「無物件」信心過濾掉。如果忘了加 1,模型的類別索引會錯位、整個訓練都會失效。
錯誤四:誤以為 DETR 不需要 NMS。DETR 在訓練時用 Hungarian matching 做一對一配對,理論上推理時不需要 NMS。但實務上 DETR 仍然會出現「同一個物件被多個 query 預測」的情況(尤其是訓練收斂不完全時),因此許多 DETR 變體仍會在推理時加一道 NMS 作為保險。RT-DETR 的論文中就有提到他們實測上加輕量 NMS 對小物件偵測有幫助。
錯誤五:把「兩階段」當成「比較慢所以比較差」。Faster R-CNN 在 COCO 上的 mAP 仍優於多數 YOLO 版本(特別是小物件),且 RoI Pooling 的設計讓它對任意形狀的物件都有較好的適應性。YOLO 的速度快但對小物件與密集場景表現較弱,DETR 在長尾類別與密集場景有優勢但訓練成本高。三個世代各有強項,選哪個取決於「你的任務最在意的是什麼」。
效能與實務提醒
三個世代的偵測架構在「訓練時間」與「推論速度」上差異極大。Faster R-CNN 在 Colab T4 上微調 ResNet-50 backbone 約 6 小時(10 epoch),推論速度約 5–10 FPS;YOLO11m 約 2 小時(50 epoch),推論速度約 50 FPS;DETR 在 T4 上完整訓練(500 epoch)需 3 天以上,推論速度約 10 FPS。對於 Colab 這種時間有限的環境,YOLO 是最佳起點;如果資料量大、有 T4+ 等級算力,DETR 的長尾表現會拉開差距。
另一個實務差異是「anchor 的設計成本」。Faster R-CNN 與早期 YOLO 需要根據資料集設計 anchor 尺寸(用 K-means 對訓練框做聚類),這個步驟對小資料集很關鍵;anchor-free 的 YOLO11 與 DETR 省掉這個麻煩,但需要更多訓練資料來收斂。實務上建議:如果你的資料集框尺寸變異不大(例如工廠零件偵測),anchor-free 通常能省下大量調參時間;如果資料集框尺寸變異大(例如街景偵測),anchor 設計仍是值得投入的環節。
推論部署上,YOLO11 在 ONNX 與 TensorRT 上的支援最完整,能輕鬆推到邊緣裝置(Jetson、CoreML、TFLite)。Faster R-CNN 的 torchvision 實作也能匯出 ONNX,但 TensorRT 的加速處理需要手動調整。DETR 系列的 ONNX 匯出仍在發展中,部分變體(如 RT-DETR)有官方支援。最後一個小提醒:訓練時 NMS 的 IoU 門檻通常設 0.5–0.7;推理時若要保留更多框(例如後續要做 tracking),可以把門檻降到 0.3,再讓追蹤演算法決定要保留哪些。
小結
本篇帶你從架構演進的角度理解物件偵測:R-CNN 系列用「候選 + 分類」的兩階段設計換取高精度,YOLO 系列用密集預測的單階段設計換取即時速度,DETR 系列用 Transformer 的集合預測換取端到端訓練。三個世代的關鍵設計選擇各有取捨:兩階段在 anchor 設計與 RoI Pooling、單階段在多尺度特徵與分布回歸、端到端在 Hungarian matching 與 query 設計。讀完這篇你應該能回答:Faster R-CNN 的 RPN 為什麼能把 Selective Search 取代掉?YOLO 為什麼能做到即時偵測?DETR 的 object queries 在概念上對應什麼?這三個問題的答案都藏在本篇的程式碼與數字裡。
在工業界,模型選擇有三條主要規則:需要即時推論(≥30 FPS)且精度要求中等,選 YOLO11s/m;需要最高精度且算力充足,選 DETR 或 Faster R-CNN;需要快速迭代且資料量不大,選 YOLO11n 或預訓練 Faster R-CNN 微調。後續 CV Day 13–16 會分別深入這三個世代的實戰:YOLO11 訓練自己的資料集、用 torchvision 微調 Faster R-CNN、DETR 與 Transformer 偵測器的細節。掌握本篇的架構演進脈絡後,進入實戰篇會更清楚每個超參數與訓練技巧的來龍去脈。
結語
今天的重點是「把偵測任務的十年演進整理成一張架構地圖」。我們從 2014 年的 R-CNN 開始,看到 Faster R-CNN 的 RPN 如何取代 Selective Search、YOLO 如何把整張影像當成一個大型回歸問題、DETR 如何用 Transformer 把偵測變成集合預測。三個世代各有解決方案,也各自留下新的瓶頸給下一代。讀完這篇你應該能在腦中畫出「兩階段 → 單階段 → 端到端」的演進路線圖,並理解每個模型的核心創新點與限制。
在工業界,這張演進圖有兩個用途:一是幫助你快速判斷「這個新模型屬於哪個世代、它的核心創新是什麼」,二是協助你選擇「在自家任務上該從哪個世代開始」。接下來的三天會分別進入 YOLO11、Faster R-CNN、DETR 的實戰:YOLO11 訓練自己的資料集(CV Day 13)、用 torchvision 微調 Faster R-CNN(CV Day 15)、DETR 與 Transformer 偵測器(CV Day 16)。這三篇都會延續今天建立的架構基礎,把昨天的指標體系與今天的架構演進結合到真實訓練流程中。明天會進入偵測的另一個關鍵環節:標註與資料格式(COCO、VOC、YOLO 轉換)。
延伸資源
- Girshick 等人,2014,Rich Feature Hierarchies for Accurate Object Detection and Semantic Segmentation,R-CNN 原始論文(CVPR 2014)。
- Ren 等人,2015,Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks,兩階段偵測的標準範本(NeurIPS 2015)。
- Redmon 等人,2016,You Only Look Once: Unified, Real-Time Object Detection,YOLO 原始論文(CVPR 2016)。
- Carion 等人,2020,End-to-End Object Detection with Transformers,DETR 原始論文(ECCV 2020)。
- Jocher 與 Qiu,Ultralytics YOLO 官方文件(2024):YOLO11 模型清單與訓練工具(docs.ultralytics.com,版本 8.3.x)。
- torchvision 官方文件(2024):
torchvision.models.detection,Faster R-CNN 與 RetinaNet 等參考實作(PyTorch 2.5、torchvision 0.20)。
留言
張貼留言