JOVANA
Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

偵測與分割物體

分類告訴你影像裡有什麼;偵測與分割則告訴你它在哪裡、究竟是哪些像素。本指南從框講到遮罩——R-CNN、YOLO、語意分割與實例分割,以及悄悄支配著這一切的 IoU 指標。

從「是什麼」到「在哪裡」

在上一篇指南裡,你搭起了一個 影像分類器:餵進一張圖片,得到一個標籤——*貓*。這確實有用,但它只回答了一個問題。一輛自動駕駛汽車需要的不僅僅是知道畫面裡*某處存在*一個行人;它得知道在哪裡、有多大、畫面裡是三個行人還是一個。從「每張圖一個標籤」邁向*定位*物體,正是從分類跨向偵測分割的那一躍。

這裡有一道越來越精確的階梯。分類給整張圖一個標籤。物體偵測 在每個物體周圍畫一個 邊界框 並打上標籤——*這裡有隻貓,那裡有條狗*。語意分割更進一步,把每一個像素都按類別打標籤。實例分割最精細:它既給每個像素打標籤,*又*把這隻貓和那隻貓區分開。每升一級,模型都要承諾更多,訓練和評估也都更難。

框,以及我們如何給框打分:IoU

一個邊界框無非是四個數——通常是角點座標,或者中心點加寬高——再配上一個類別標籤和一個置信度分數。預測框把問題的一部分變成了*迴歸*:網路不再是從類別裡挑一個,而是輸出實數座標,並被訓練著把它們推向真實的框。但這引出一個尖銳的問題:如果模型預測了一個框,而真實標註是一個略有不同的框,那它*到底有多對*?你不能要求像素級的完全相等。

整個領域達成共識的答案是 [[intersection-over-union|交併比]],即 IoU。把預測框和真實框拿來;量出它們重疊的面積,再除以它們合在一起覆蓋的面積。如果兩個框完全重合,IoU 就是 1;如果它們根本不沾邊,就是 0。一個常用的規則是:只有當一個偵測框與某個真實框的 IoU 越過某個閾值(常常是 0.5)時,才算它「正確」。這一個比值無處不在——在訓練中、在判斷哪個預測對應哪個物體時、在排行榜指標裡都有它。

IoU = area(overlap) / area(union)

     true box        predicted box
     +--------+
     |   +----|-----+      overlap = the shared rectangle
     |   |    |     |      union   = both boxes combined
     +---|----+     |
         +----------+      IoU = overlap / union   (0 .. 1)
IoU 獎勵那些對齊得好的框。偵測器通常會為一個物體冒出許多重疊的框;隨後我們保留最自信的那個,並用 IoU 來判定什麼算重複,從而壓制掉其餘的框(非極大值抑制)。

由於 IoU 衡量的只是區域重疊,它並不專屬於框——同樣的這個比值也用來給分割遮罩打分,那時你比較的是預測像素和真實像素。請記住這一點:IoU 是貫穿本指南一切內容的連接組織。當一篇論文吹噓「0.5 下的 mAP」時,它是在用 0.5 的 IoU 閾值判定命中與失誤,再把各類別的偵測 精確率 平均起來。

兩條偵測路線:先找區域,還是一步到位

第一個真正好用的家族是 [[r-cnn|R-CNN]] 及其後代(Fast R-CNN、Faster R-CNN)。它的思路是一條兩階段流水線:先*提出*幾百個可能含有物體的區域,再對每個候選區域跑一個分類器,說出它是什麼並微調它的框。它很準確,因為第二階段能仔細地端詳每一個候選。代價是速度——對每張圖的幾百個區域都跑一遍分類器很沉重,這使得早期的 R-CNN 用在影片上慢得不像話。

第二個家族把設計顛倒了過來。[[yolo|YOLO]]——「你只看一次」(You Only Look Once)——在單次前向傳播中把一切搞定。它把影像切成一個網格,對每個格子直接預測框和類別機率。沒有單獨的候選階段;一個網路,看一眼。這讓它快到足以在即時影片上執行,也正因如此,YOLO 及其單階段同類支撐著你在現實裡見到的大多數即時偵測——攝影機、無人機、體育分析。

從框到像素:分割

框是個粗鈍的工具。一個框套住一條蜿蜒的道路、一隻蜷成一圈的貓、或一個張開雙臂的人,會框進許多它並不意指的背景。分割透過對每個像素分類來解決這個問題。在 [[semantic-segmentation-vision|語意分割]] 中,每個像素得到一個*類別*標籤——*道路*、*天空*、*汽車*——但所有汽車共用同一個標籤。它回答的是「這個像素是什麼?」,並不在意有多少個各自獨立的物體。

[[instance-segmentation|實例分割]] 補上了那處缺失的區分:它既給每個像素打標籤,*又*把一個物體和另一個區分開,於是一個場景裡的三輛車得到三張各自的遮罩。一種流行的做法是 Mask R-CNN,它乾脆把一個小小的遮罩預測頭螺接到 Faster R-CNN 偵測器上——先找到框,再塗出框內哪些像素屬於該物體。這清爽地說明了偵測與分割並非對手;像素遮罩常常是*建在*一個偵測出來的框*之上*的。

網路是怎麼輸出一張全解析度的標籤圖的呢?骨幹網路會把影像縮小成粗糙的 特徵圖,所以分割模型必須*上採樣*回原始尺寸。為此有一個優雅的設計——U-Net:一條收縮路徑用來捕捉上下文,一條對稱的擴張路徑用來恢復空間細節,再加上跳躍連接,把早期層裡細粒度的邊緣直接橫遞給後期的層。它最初是為生物醫學影像而造,其形狀如今在分割世界裡反覆出現。

要讓這套真正管用,需要什麼——又會在哪裡崩壞

這一切都不是魔法;它的代價是標註資料。一個分類樣本每張圖只需一個標籤。一個偵測樣本需要給*每一個*物體畫上框。一個實例分割樣本需要把*每一個*物體的輪廓手工描出來——這是費力、昂貴的 標註。這正是為什麼像 COCO 這樣、含有幾十萬個被仔細勾勒出輪廓的物體的基準資料集會是里程碑式的成就:模型的上限,是由這些標籤的品質與覆蓋面所定下的。

  1. 選定任務:框(偵測)、逐像素類別(語意)、還是逐像素加逐物體(實例)——每一種都要求不同的標籤格式和預算。
  2. 拿一個在大型影像資料集上預訓練好的骨幹網路來微調;你很少從零開始訓練。
  3. 用一個把分類、框迴歸、以及(對分割而言)逐像素項組合起來的損失函數來訓練。
  4. 用基於 IoU 的指標來評估,然後去看真實的錯誤——而不只是那個頭條數字。

要誠實地面對失效模式,因為在已部署的系統裡它們隨處可見。偵測器在微小、遙遠或嚴重重疊的物體上會吃力;它們可能在空無一物處自信地幻想出框,也可能在不尋常的光照下漏掉一個明顯的物體。一個在白天城市街道上訓練的模型,到了雪地或夜裡會急劇退化——這是一種 分佈偏移,你測試集上的 IoU 永遠不會就此向你示警。高高的基準分數衡量的是在「長得像訓練集」的資料上的表現,而不是面對亂糟糟現實世界的穩健性。

接下來去哪?同樣的「定位加打標籤」機制可以推廣:把這些框跨影片幀追蹤、把它們抬升到三維用於機器人、或者把卷積骨幹換成一個 視覺 Transformer——那正是下一篇指南的主題。你現在握住的核心觀念——框對遮罩、語意對實例、以及作為一切量尺的 IoU——會一路直通過去。