Hard Negative Mining
ハードネガティブマイニングでは、モデルがポジティブと最も混同しやすいネガティブを見つけ、そこに学習を集中させます。これにより、検出や検索における誤検出を減らします。
ハードネガティブマイニングは、モデルが最も間違いやすい負例を見つけ、それらに学習を集中させるトレーニング戦略です。負例は対象クラスに属さない例であり、ハードネガティブとは、モデルが依然として正例のようなスコアを付ける例です。たとえば、検出器が物体として囲んでしまう背景パッチや、埋め込みモデルがクエリの近くに配置する無関係な画像などがあります。負例の大半は簡単で、モデルが正しく処理できるようになると学習シグナルにほとんど寄与しません。そのため、難しい負例を選ぶことで決定境界を明確にし、偽陽性を減らせます。
ハードネガティブマイニングの仕組み#
何をハードと見なすかは、タスクによって異なります。
- 物体検出では、検出器が物体としてスコアを付ける背景領域がハードネガティブです。
- 分類では、対象クラスの信頼度を高く付けられた誤クラスの例がハードネガティブです。
- 検索やレコメンデーションシステムでは、クエリに近い順位にランク付けされた無関係なアイテムを指し、スコアの高い負例は勾配に最も大きく影響します。
- メトリック学習では、対応する正例よりもアンカーに近い負例を指し、トリプレットマージン損失でペナルティーを与えます。
マイニングはオフラインまたはオンラインで行います。オフラインマイニングでは、トレーニング済みモデルを負例のみの大規模データに適用し、偽陽性を収集してトレーニングセットに追加し、再トレーニングします。従来のスライディングウィンドウ方式の歩行者検出器は、人が写っていない画像をスキャンして誤検出を集め、それらを使って再トレーニングしていました。オンラインマイニングでは、各トレーニングバッチ内で難しい例を選びます。SSDは、負のデフォルトボックスを分類損失で順位付けし、損失が最も大きいものだけを、正例1つにつき最大3つまで保持します。オンラインハードサンプルマイニング(OHEM)は、同じ考え方を2段階検出器の領域候補に適用します。SSDでの選択は数行で記述できます。
import torch
import torch.nn.functional as F
torch.manual_seed(0)
# Simulated objectness logits for 8,400 candidate boxes: 20 cover an object, the rest are background
logits = torch.randn(8400) - 3
labels = torch.zeros(8400)
labels[:20] = 1
loss = F.binary_cross_entropy_with_logits(logits, labels, reduction="none")
# Keep every positive plus only the highest-loss negatives, at most 3 per positive
positives = labels == 1
negative_loss = loss.masked_fill(positives, 0)
hard_negatives = negative_loss.topk(3 * int(positives.sum())).indices
kept = torch.cat([positives.nonzero().squeeze(1), hard_negatives])
print(f"boxes in the loss: {len(kept)} of {len(loss)}")
print(f"mean negative loss: all {loss[~positives].mean():.3f}, mined {loss[hard_negatives].mean():.3f}")損失計算では、8,400個のボックスのうち80個を使用します。正例20個と、モデルが物体らしいスコアを付けた負例60個です。マイニングされた負例60個の平均損失は0.648で、負例全体8,380個の平均損失0.075を上回ります。このため、勾配はモデルが実際に混同している背景に集中します。
ハードネガティブマイニングと関連手法との比較#
- 負例サンプリング: すべての負例から、ランダムに選ぶことが多い、扱いやすい数のサブセットを選びます。ハードネガティブマイニングでは、最も紛らわしい負例を選びます。
- Focal loss: すべての例を損失計算に含めたまま、正しく分類された例の重みを下げます。これにより、RetinaNetなどの1段階検出器は、明示的なサンプリングなしで候補ボックスすべてを使ってトレーニングできます。
- アクティブラーニング: 正例の可能性があるものも含め、人によるアノテーションの対象として、不確かな未ラベルの例を選びます。ハードネガティブマイニングの対象は、すでに負例と確認された例です。
- クラスの再均衡化: ダウンサンプリングと重みの増加によって、クラス頻度の偏りを補正します。頻度の高い負例クラスが、必ずしも難しいとは限りません。
- データ拡張: 既存サンプルのバリエーションを作成しますが、データセットに含まれていない紛らわしい物体を追加することはできません。
実際のアプリケーション#
- 倉庫の安全検出: フォークリフト検出器がパレットジャッキ、棚の反射、シザーリフトを繰り返し誤検出すると、誤警報によって作業者の信頼が損なわれます。こうした場面を負例画像として収集し、再トレーニングすると、類似機材とフォークリフトを区別する特徴を検出器に学習させられます。
- ビジュアル商品検索: 特定の黒いランニングシューズを検索したときに、別の商品ラインの類似シューズが高順位になりすぎる場合、それらの商品はハードネガティブになります。たとえば、Siameseネットワークのアンカー・正例・負例のトリプレットで負例としてトレーニングに使うと、ソールの形状、ロゴの配置、素材などの微妙な違いを埋め込みモデルに保持させることができます。
オフラインマイニングのワークフロー#
オフラインマイニングの各ラウンドでは、現在のモデルを実行し、モデルがフラグを付けた対象を確認して、確認済みの事例をトレーニングに戻します。
レビュー手順は重要です。「偽陽性」は、実際には存在する物体をアノテーターが見落としている場合があり、それを負例として追加すると、モデルに正しい検出を抑制するよう学習させてしまいます。Ultralytics YOLOは、ラベルファイルがない、または空のトレーニング画像を背景画像として扱います。そのため、画像上のすべてのアンカーポイントにゼロのターゲットスコアが割り当てられ、信頼度の高い予測にはペナルティーが与えられます。したがって、マイニングした負例をYOLO26のデータセットに追加するには、ラベルを付けずに画像をコピーするだけです。同じ再現率での適合率の向上を、テストセット全体とハードネガティブ専用のサブセットで追跡すると、進捗を確認できます。
最も難しい負例だけでトレーニングすると、逆効果になることがあります。FaceNetの顔埋め込みトレーニングでは、初期段階で最も難しい負例を選ぶと、すべての顔を同じ点に写像するようモデルが崩壊する可能性があります。そのため著者らは、正例よりアンカーから遠い一方で、トリプレットマージンの内側にあるセミハードネガティブを使ってトレーニングしました。










