Non-Maximum Suppression (NMS)
非極大値抑制(NMS)は、重複するボックスを取り除き、各物体に1つの検出結果を割り当てます。仕組み、調整方法、NMS不要のモデルを解説します。
非最大値抑制(NMS)は、検出器の未処理で重なり合った予測結果を、物体ごとに1つのボックスへまとめる後処理です。高密度の物体検出モデルは、画像ごとに数千個の候補バウンディングボックスをスコアリングします。通常、複数の近接した候補が、位置とスコアを少しずつ変えながら同じ物体に対して反応します。NMSは、重なり合う各クラスターから最も高い信頼度のボックスを残し、残りを抑制します。ボックスの重なりが重複と見なされるほど大きいかどうかは、交差領域の和(IoU)を使って判断します。
Non-Maximum Suppressionの仕組み#
標準的な方式である貪欲NMSは、まず信頼度しきい値未満の候補を除外し、残りをスコア順に並べます。次に最上位のボックスを残し、それとのIoUがIoUしきい値を超える残りのボックスをすべて削除します。残った候補がなくなるまで、次にスコアの高いボックスを選んでこの処理を繰り返します。検出器は通常、クラスごとにNMSを1回実行するため、人のボックスが重なった自転車のボックスを抑制することはありません。
torchvisionのnmsは、1つのクラスに対して貪欲NMSを実行し、スコア順に並べた、残すボックスのインデックスを返します。
import torch
from torchvision.ops import nms
# 候補ボックスは[x1, y1, x2, y2]で表し、それぞれに信頼度スコアを1つずつ付与します
boxes = torch.tensor(
[
[100, 100, 200, 200], # A
[105, 105, 195, 195], # B: Aとほぼ重複(IoU 0.81)
[300, 300, 400, 400], # C: 別の物体
],
dtype=torch.float32,
)
scores = torch.tensor([0.90, 0.80, 0.95])
# スコアの高い残存ボックスとのIoUが0.5を超えるボックスを抑制します
keep = nms(boxes, scores, iou_threshold=0.5)
print(keep.tolist())出力は[2, 0]です。最もスコアの高いボックスCが最初に残り、Cとは重ならないボックスAも残ります。ボックスBは、AとのIoUが0.81であるため削除されます。
しきい値の調整#
信頼度しきい値は、抑制の開始前に信頼度の低い候補を除外します。IoUしきい値は、どの程度の重なりを重複と見なすかを決めます。しきい値が低すぎると、人混みの中の人々のように近くに立つ実際の物体が1つの検出にまとめられ、再現率が低下します。高すぎると、重複するボックスが残り、適合率が低下します。クラス非依存NMSでは、クラスにかかわらず任意のボックスが他のボックスを抑制できます。これにより、モデルが1つの物体に「car」と「truck」のような似たクラスを2つ割り当てた場合に、二重ラベルを取り除けます。
NMSの限界#
- 混雑したシーン: 固定されたIoUしきい値だけでは、重複ボックスと、最初の物体に実際に重なっている別の物体を区別できません。そのため、激しくオクルージョンされた物体が抑制されます。
- 固定されたヒューリスティック: しきい値は手動で決められ、トレーニング済みネットワークの外部にあり、データから学習されません。
- レイテンシとデプロイ: 貪欲ループはネットワークの実行後に動作し、候補数が増えるほど処理コストも増加するため、推論レイテンシが追加されます。NMSをモデルグラフに組み込めないエクスポート形式では、候補が未処理のまま出力されるため、アプリケーション側でNMSを実行する必要があります。
NMSの派生手法とNMSフリー検出#
Soft-NMSは、重なり合うボックスを削除せず、重なりの度合いに応じてスコアを下げるため、混雑した環境でより多くの物体を検出できます。Distance-IoU損失とともに提案されたDIoU-NMSは、ボックス中心間の距離も考慮するため、中心が離れた2つのボックスは抑制されにくくなります。
エンドツーエンド検出器は、そのステップ自体を省略します。DETRは、予測とラベルを一対一で対応付けるハンガリー法によるマッチングで学習されるため、各オブジェクトには予測が必ず1つだけ割り当てられ、YOLOv10はリアルタイムYOLOモデルに一対一ヘッドを導入しました。YOLO26は2種類のヘッドをどちらも学習し、YOLO26nでは一対多ヘッドが40.9対40.1のmAP50-95をCOCOで記録してわずかに高いスコアとなるため、デフォルトでNMSを適用します。nms=Falseを渡すと一対一ヘッドが選択され、エンドツーエンド検出ガイドで推論とエクスポートについて説明されているとおり、NMS処理なしで画像あたり最大300個の最終ボックスを出力します。










