Hayami Kaito Web
~/tech

物体検出 AI のしくみ:R-CNN・YOLO から DETR まで

published

物体検出 AI は、写真を受け取って「ここに猫(92%)、ここに犬(88%)」のように、写っている物体を四角い枠(バウンディングボックス)で囲み、それぞれに種類と確率を付けて返すプログラムです。自動運転の歩行者検出、スマートフォンのカメラの顔検出、工場の検品などで使われています。

この記事は 画像分類 AI のしくみ の続きです。畳み込み・ソフトマックス・学習のしくみはそちらで説明したので、この記事では「画像分類から何が増えると物体検出になるのか」に絞って説明します。

結論を先に書くと、物体検出のモデルは画像分類のモデルに次の 3 つを足したものです。

  • 枠の位置を数値で出す部分: 種類の確率に加えて、枠の座標(中心・幅・高さ)を回帰で出す
  • たくさんの候補から選ぶしくみ: 画像中のあちこちに枠の候補を出し、重なった候補を NMS で 1 つにまとめる
  • 枠の当たり具合を測る物差し: 予測の枠と正解の枠の重なりを IoU で測り、学習と評価に使う

説明の途中に出てくる計算例は、Python と NumPy で実際に動かした結果です。

環境

計算例を動かした環境です。

項目バージョン
Python3.13
NumPy2.5

物体検出とは:「何が」に「どこに」を加える

画像を扱うタスクは、答えの細かさによって次のように分けられます。

タスク答え例
画像分類画像全体に 1 つのラベル「猫の写真」
物体検出物体ごとに枠と種類「(50, 50)〜(150, 150) に猫、(200, 80)〜(300, 200) に犬」
セグメンテーション画素ごとに種類「この画素は猫、この画素は背景」

物体検出が画像分類より難しいのは、次の 2 点です。

  • 物体の数が画像ごとに違う: 0 個のこともあれば 50 個のこともあり、出力の数が決まっていない
  • 位置と大きさも当てる必要がある: 種類(分類)だけでなく、枠の座標という連続した数値(回帰)も出す

この記事で紹介する手法は、どれもこの 2 点をどう解くかの工夫です。

枠の表し方:左上と右下、または中心と幅・高さ

バウンディングボックスは、4 つの数値で表します。よく使われる表し方は 2 つあります。

左上・右下の座標:    [x1, y1, x2, y2]  例: [50, 50, 150, 150]
中心・幅・高さ:      [cx, cy, w, h]    例: [100, 100, 100, 100]

どちらも同じ枠を表していて、互いに変換できます。画像の座標は左上が原点で、x は右向き、y は下向きに増えます。

IoU:予測の枠がどれだけ当たっているかを測る

予測の枠が正解の枠とどれだけ合っているかは、IoU(Intersection over Union)で測ります。2 つの枠の「重なった部分の面積」を「どちらかに含まれる部分の面積」で割った値です。

IoU = 重なった部分の面積 ÷ (枠 A の面積 + 枠 B の面積 − 重なった部分の面積)

ぴったり同じなら 1、まったく重ならなければ 0 になります。

import numpy as np

def iou(a, b):
    # a, b: [x1, y1, x2, y2]
    ix1, iy1 = max(a[0], b[0]), max(a[1], b[1])
    ix2, iy2 = min(a[2], b[2]), min(a[3], b[3])
    inter = max(ix2 - ix1, 0) * max(iy2 - iy1, 0)
    area_a = (a[2] - a[0]) * (a[3] - a[1])
    area_b = (b[2] - b[0]) * (b[3] - b[1])
    return inter / (area_a + area_b - inter)

gt = [50, 50, 150, 150]  # 正解の枠(100 × 100)
print(round(iou(gt, [60, 60, 160, 160]), 3))    # 右下に 10 ずれた枠
print(round(iou(gt, [100, 100, 200, 200]), 3))  # 右下に 50 ずれた枠
print(round(iou(gt, [200, 200, 300, 300]), 3))  # 重ならない枠

実行結果:

0.681
0.143
0.0

縦横に 10 ずれただけで IoU は 0.681 まで下がり、半分ずれると 0.143 です。IoU は見た目の印象より厳しい物差しだと分かります。

物体検出では「IoU が 0.5 以上なら当たり」のように、しきい値を決めて使うのが一般的です。IoU は、このあと出てくる学習時の正解の割り当て・NMS・評価のすべてで使います。

素朴な方法:画像分類をあちこちで実行する

画像分類のモデルがあるなら、いちばん素直な物体検出の方法は「画像を小さな窓で切り出し、窓ごとに分類する」ことです。窓を少しずつずらしながら画像全体をなめるので、スライディングウィンドウと呼ばれます。

しかし、この方法には次の問題があります。

  • 窓の数が膨大になる: 物体の大きさも縦横比もさまざまなので、位置 × 大きさ × 縦横比の組み合わせだけ窓が必要になる
  • 窓の位置でしか枠を出せない: 窓をずらす間隔より細かい位置は表せない

ここから、「分類する場所の候補をどう減らすか」「枠の位置をどう細かく合わせるか」という 2 つの方向で改良が進みました。

二段階の検出器:R-CNN から Faster R-CNN へ

最初に大きな成果を上げたのは、「候補の領域を出す」と「候補ごとに分類する」の 2 段階に分ける方法です。

R-CNN:候補の領域を CNN で分類する

2014 年の R-CNN は、次の手順で物体を検出します。

  1. 色や模様の似た領域をまとめる従来の画像処理の手法(Selective Search)で、物体がありそうな候補の領域を約 2,000 個出す
  2. 候補の領域を 1 つずつ切り出し、決まった大きさに引き伸ばして CNN に入れ、特徴を取り出す
  3. 取り出した特徴から、種類を判定し、枠の位置を補正する

窓をしらみつぶしに試すかわりに「物体がありそうな場所」だけを調べるので、窓の数を大きく減らせます。R-CNN は、物体検出のベンチマーク PASCAL VOC 2012 で、それまでの最高の結果を mAP(後述)で 30% 以上(相対値)上回る 53.3% を出しました。

ただし、候補ごとに CNN を通すので、1 枚の画像で CNN を約 2,000 回実行することになり、とても遅いという問題がありました。

Fast R-CNN:CNN を 1 回で済ませる

2015 年の Fast R-CNN は、画像全体に CNN を 1 回だけかけて特徴マップを作り、候補の領域に当たる部分を特徴マップから切り出すようにしました。切り出した大きさのばらばらな部分を決まった大きさにそろえる処理を、RoI プーリング(RoI は Region of Interest、注目する領域)と呼びます。

CNN の計算を候補どうしで共有できるので、R-CNN より大幅に速くなりました。しかし、候補の領域を出す Selective Search はまだ CNN の外にあり、ここが遅さの原因として残りました。

Faster R-CNN:候補を出す部分もニューラルネットワークにする

2015 年の Faster R-CNN は、候補の領域を出す部分も CNN の特徴マップから出すようにしました。この部分を RPN(Region Proposal Network、領域提案ネットワーク)と呼びます。これで検出の全体が 1 つのニューラルネットワークになり、VGG-16 を使ったモデルで、GPU 上で全体として毎秒約 5 枚の処理速度になりました。

RPN の中心にあるのが、次に説明するアンカーという考え方です。

アンカー:あらかじめ置いた枠からのずれを学習する

特徴マップの各位置に、大きさと縦横比の違う枠を置く

アンカーは、特徴マップの各位置にあらかじめ置いておく、大きさと縦横比の違う枠のひな形です。Faster R-CNN では、各位置に 3 種類の大きさ × 3 種類の縦横比 = 9 個のアンカーを置きます。

モデルは各アンカーについて、次の 2 つを出します。

  • 物体らしさ(RPN)または種類ごとの確率(最終段): このアンカーの近くに物体があるか、あるなら何か
  • ずれ: アンカーを正解の枠に合わせるには、どれだけ動かし、どれだけ伸び縮みさせればよいか

学習のときは、正解の枠との IoU が大きいアンカーを「物体あり」、小さいアンカーを「背景」として扱います。

座標そのものではなく「ずれ」を出す理由

モデルに枠の座標そのもの(「x = 110」)を出させるより、アンカーからのずれ(「アンカーの幅の 0.1 倍だけ右」)を出させるほうが学習しやすくなります。ずれは 0 の近くの小さな値になり、画像の大きさや物体の大きさに左右されにくいためです。

Faster R-CNN では、アンカー(中心 xa, ya、幅 wa、高さ ha)と枠(中心 x, y、幅 w、高さ h)のずれを次の 4 つの値で表します。

tx = (x − xa) ÷ wa       中心の横のずれ(アンカーの幅を 1 とした値)
ty = (y − ya) ÷ ha       中心の縦のずれ(アンカーの高さを 1 とした値)
tw = log(w ÷ wa)         幅の倍率の対数
th = log(h ÷ ha)         高さの倍率の対数

幅と高さに対数を使うのは、「2 倍に伸ばす」と「半分に縮める」を +0.693 と −0.693 のように対称に扱えるようにするためです。

中心 (100, 100)・100 × 100 のアンカーから、中心 (110, 90)・150 × 80 の枠へのずれを計算し、逆にずれから枠を復元してみます。

def encode(box, anchor):
    # box, anchor: [cx, cy, w, h]
    tx = (box[0] - anchor[0]) / anchor[2]
    ty = (box[1] - anchor[1]) / anchor[3]
    tw = np.log(box[2] / anchor[2])
    th = np.log(box[3] / anchor[3])
    return np.array([tx, ty, tw, th])

def decode(t, anchor):
    cx = anchor[0] + t[0] * anchor[2]
    cy = anchor[1] + t[1] * anchor[3]
    w = anchor[2] * np.exp(t[2])
    h = anchor[3] * np.exp(t[3])
    return np.array([cx, cy, w, h])

anchor = [100, 100, 100, 100]
box = [110, 90, 150, 80]
t = encode(box, anchor)
print(np.round(t, 3))
print(np.round(decode(t, anchor), 3))

実行結果:

[ 0.1   -0.1    0.405 -0.223]
[110.  90. 150.  80.]

学習では、モデルが出したずれと、正解の枠から計算したずれ [0.1, -0.1, 0.405, -0.223] との差を損失にします。推論のときは、モデルが出したずれを decode で枠に戻します。

損失は「種類の誤差」と「位置の誤差」の合計

物体検出の損失は、次の 2 つを足したものです。

損失 = 種類の損失(交差エントロピー誤差) + λ × 位置の損失(ずれの誤差)
  • 種類の損失: 画像分類と同じ交差エントロピー誤差。背景も 1 つの種類として扱う
  • 位置の損失: 予測したずれと正解のずれの差。Faster R-CNN では、差が大きいところで二乗ではなく絶対値のように振る舞う Smooth L1 損失を使う。背景のアンカーには位置の正解がないので、物体ありのアンカーだけで計算する
  • λ: 2 つの損失の釣り合いを取る係数

NMS:重なった候補を 1 つにまとめる

アンカーは特徴マップのすべての位置に置かれるので、1 匹の猫に対して、少しずつずれた枠がいくつも「猫」と判定されます。そのまま出すと、同じ猫に何重にも枠が付いてしまいます。

そこで最後に NMS(Non-Maximum Suppression、非最大値抑制)で重複を取り除きます。

  1. 確率(スコア)の高い順に枠を並べる
  2. いちばんスコアの高い枠を採用する
  3. 採用した枠との IoU がしきい値(例: 0.5)以上の枠を、同じ物体を指しているとみなして捨てる
  4. 残った枠で 2 に戻り、枠がなくなるまでくり返す

並んだ 2 匹の猫に、それぞれ少しずつずれた枠が出た例で試します。

def nms(boxes, scores, threshold=0.5):
    order = np.argsort(scores)[::-1]
    keep = []
    while len(order) > 0:
        best = order[0]
        keep.append(int(best))
        order = np.array([i for i in order[1:] if iou(boxes[best], boxes[i]) < threshold], dtype=int)
    return keep

boxes = [
    [50, 50, 150, 150],   # 0: 猫 A
    [55, 45, 155, 145],   # 1: 猫 A(少しずれ)
    [45, 60, 145, 160],   # 2: 猫 A(少しずれ)
    [140, 60, 240, 160],  # 3: 猫 B
    [150, 55, 250, 150],  # 4: 猫 B(少しずれ)
]
scores = [0.92, 0.85, 0.70, 0.88, 0.60]
print(nms(boxes, scores))
print(round(iou(boxes[0], boxes[3]), 3))

実行結果:

[0, 3]
0.047

5 個の枠が、猫 A の枠 0 と猫 B の枠 3 の 2 個にまとまりました。枠 0 と枠 3 は少し重なっていますが、IoU は 0.047 としきい値より小さいので、別の物体として両方残ります。

NMS はふつう種類ごとに行います。猫の枠と犬の枠が重なっていても、種類が違えば両方残します。また、人の群れのように同じ種類の物体が大きく重なっていると、本物の枠まで捨ててしまうことがあります。この弱点は、あとで紹介する DETR の動機の 1 つになりました。

一段階の検出器:YOLO と SSD

二段階の検出器は精度が高い一方で、「候補を出す → 候補ごとに分類する」の 2 段を通るぶん時間がかかります。そこで、候補を出さずに、1 回の計算で枠と種類を直接出す一段階の検出器が登場しました。

YOLO:画像をマス目に区切って一度に答える

2016 年の YOLO(You Only Look Once、一度見るだけ)は、画像を S × S のマス目に区切り、各マスが次のものを出します。

  • B 個の枠: それぞれ中心・幅・高さの 4 つの値と、「この枠に物体があり、正しく囲めている度合い」を表す信頼度(物体がある確率 × 正解との IoU を学習の目標にする)の、合わせて 5 つの値
  • C 種類の確率: このマスに物体があるとしたら、それが何か

物体の中心が入っているマスが、その物体を担当します。PASCAL VOC(20 種類)では S = 7、B = 2 なので、出力は 7 × 7 × (2 × 5 + 20) = 1,470 個の数値です。画像を 1 回 CNN に通すだけで、この 1,470 個がまとめて出てきます。

YOLO は Titan X の GPU 上で毎秒 45 枚を処理でき、動画にリアルタイムで使える速さを示しました。一方で、1 マスが担当できる物体の数が限られるため、鳥の群れのように小さな物体が密集していると取りこぼしやすく、枠の位置の誤差も二段階の検出器より大きいという弱点がありました。

SSD:大きさの違う特徴マップで大小の物体を拾う

2016 年の SSD(Single Shot MultiBox Detector)も一段階の検出器ですが、YOLO と違って次の 2 つを取り入れました。

  • アンカー(SSD ではデフォルトボックスと呼ぶ)を使い、そこからのずれを出す
  • 複数の層の特徴マップから検出する。解像度の高い浅い層で小さな物体を、解像度の低い深い層で大きな物体を担当させる

画像分類の記事 で説明したとおり、深い層ほど広い範囲を見ているので、大きな物体を捉えるのに向いています。この「層ごとに大きさを分担する」考え方は、2017 年の FPN(Feature Pyramid Network)で、深い層の情報を浅い層に戻して組み合わせる形に発展し、今の多くの検出器で使われています。

背景だらけ問題とフォーカルロス

一段階の検出器には、学習のときに背景のアンカーが圧倒的に多いという問題があります。1 枚の画像に何万個もアンカーを置いても、物体があるのは数個〜数十個です。そのまま学習すると、「簡単な背景」の損失の合計が大きくなりすぎて、肝心の物体の学習が進みません。

2017 年の RetinaNet は、フォーカルロス(Focal Loss)でこれを解きました。モデルがすでに自信を持って正解している例(大半の背景)の損失を小さく割り引き、間違えやすい例に学習を集中させる損失関数です。これにより、一段階の検出器でも二段階の検出器に並ぶ精度が出せるようになりました。

二段階と一段階の比較

二段階(Faster R-CNN など)一段階(YOLO・SSD・RetinaNet など)
流れ候補を出す → 候補ごとに分類・補正1 回の計算で枠と種類を直接出す
速さ遅め速い
精度高い(とくに初期)当初は低めだったが、改良で並んだ
向いている用途精度を優先する解析動画・スマートフォンなどのリアルタイム処理

YOLO はその後も改良が続けられ、多くの版が公開されています。

評価のしかた:適合率・再現率と mAP

物体検出の性能は、画像分類の「正解率」のように 1 つの割合では測れません。物体を見落とすこともあれば、何もないところに枠を出すこともあるからです。

当たり・外れ・見落としを数える

検出した枠を、正解の枠と IoU で突き合わせて、次のように数えます。

結果意味
当たり(TP)同じ種類の正解と IoU がしきい値以上(1 つの正解には 1 つの検出だけ)
外れ(FP)当てはまる正解がない、または同じ正解を別の検出がすでに当てている
見落とし(FN)どの検出にも当てられなかった正解

ここから次の 2 つを計算します。

適合率(precision) = 当たり ÷ 検出した数     出した枠のうち、正しかった割合
再現率(recall)    = 当たり ÷ 正解の数       正解のうち、見つけられた割合

スコアのしきい値を下げてたくさん枠を出すと、再現率は上がりますが外れも増えて適合率が下がります。この取り合いをまとめて評価するのが AP です。

AP:しきい値を変えたときの適合率と再現率をまとめる

AP(Average Precision)は、検出をスコアの高い順に 1 つずつ数えていったときの「再現率と適合率の曲線」の下の面積です。

正解が 4 個ある画像で、6 個の検出があった例で計算します(1 が当たり、0 が外れ)。

tp = np.array([1, 1, 0, 1, 0, 1])  # スコアの高い順に並べた検出の当たり・外れ
scores = [0.95, 0.90, 0.80, 0.70, 0.60, 0.50]
n_gt = 4  # 正解の数
ctp = np.cumsum(tp); cfp = np.cumsum(1 - tp)
precision = ctp / (ctp + cfp)
recall = ctp / n_gt
for s, t_, p, r in zip(scores, tp, precision, recall):
    print(s, t_, round(p, 3), round(r, 3))

# 各再現率で「それ以降の最大の適合率」を取って曲線をならし、面積を求める
mrec = np.concatenate([[0], recall, [1]])
mpre = np.concatenate([[0], precision, [0]])
for i in range(len(mpre) - 2, -1, -1):
    mpre[i] = max(mpre[i], mpre[i + 1])
idx = np.where(mrec[1:] != mrec[:-1])[0]
ap = np.sum((mrec[idx + 1] - mrec[idx]) * mpre[idx + 1])
print("AP", round(ap, 3))

実行結果:

0.95 1 1.0 0.25
0.9 1 1.0 0.5
0.8 0 0.667 0.5
0.7 1 0.75 0.75
0.6 0 0.6 0.75
0.5 1 0.667 1.0
AP 0.854

表にすると次のとおりです。

スコア結果適合率再現率
0.95当たり1.0000.25
0.90当たり1.0000.50
0.80外れ0.6670.50
0.70当たり0.7500.75
0.60外れ0.6000.75
0.50当たり0.6671.00

再現率 0〜0.5 の区間は適合率 1.0、0.5〜0.75 は 0.75、0.75〜1.0 は 0.667 として面積を取ると、0.5 × 1.0 + 0.25 × 0.75 + 0.25 × 0.667 ≒ 0.854 です。高いスコアの検出ほど当たっていれば、AP は 1 に近づきます。

mAP:種類と IoU のしきい値で平均する

AP は種類ごとに計算し、その平均を mAP(mean Average Precision)と呼びます。データセットによって、平均の取り方が少し違います。

データセット種類の数主な指標
PASCAL VOC20IoU 0.5 をしきい値にした mAP
COCO80IoU のしきい値を 0.50〜0.95 まで 0.05 刻みで変えた mAP の平均

COCO の指標は、IoU 0.95 のような厳しいしきい値も含むので、「だいたい合っている」だけでなく「枠がぴったり合っている」ことまで評価されます。

DETR:Transformer で「集合」を直接出す

ここまでの検出器は、アンカーや NMS など、人が設計した部品に頼っていました。アンカーの大きさや NMS のしきい値は、データに合わせて人が調整する必要があります。

2020 年の DETR(DEtection TRansformer)は、物体検出を「物体の集合を直接当てる問題」として捉え直し、アンカーと NMS をなくしました。

決まった数の「問い合わせ」で物体を出す

DETR の流れは次のとおりです。

  1. CNN で画像の特徴マップを作る
  2. Transformer のエンコーダーで、特徴マップの各位置どうしの関係を計算する(画像分類の記事 の ViT と同じ自己注意)
  3. デコーダーに、学習で決まる決まった数(COCO では 100 個)のオブジェクトクエリを入れる。各クエリが「物体を 1 つ探して報告する係」になり、枠と種類を出す
  4. 物体が 100 個より少なければ、余ったクエリは「物体なし」という種類を出す

クエリどうしも自己注意で互いの出力を参照できるので、「その物体はほかのクエリが担当している」と分かり、同じ物体を二重に出さないように学習されます。そのため NMS が要りません。

予測と正解を 1 対 1 で組み合わせて学習する

学習のときには、「100 個の予測のどれを、どの正解と比べるか」を決める必要があります。DETR では、予測と正解の組み合わせのうち、種類と位置の誤差の合計(コスト)が最小になる 1 対 1 の組み合わせを探し、組になった予測と正解で損失を計算します。組にならなかった予測は「物体なし」が正解になります。

予測 3 個・正解 2 個の小さな例で、すべての組み合わせを試して最小のものを探します。

from itertools import permutations

# 予測 3 個 × 正解 2 個のコスト(小さいほど良い組)
cost = np.array([
    [0.9, 0.2],
    [0.1, 0.8],
    [0.7, 0.6],
])
best = None
for perm in permutations(range(3), 2):  # 正解 j に予測 perm[j] を割り当てる
    c = sum(cost[perm[j], j] for j in range(2))
    if best is None or c < best[0]:
        best = (round(c, 3), perm)
print(best)

実行結果:

(np.float64(0.3), (1, 0))

正解 0 には予測 1、正解 1 には予測 0 が割り当てられ、コストの合計は 0.3 です。残った予測 2 は「物体なし」として学習されます。

ここでは分かりやすさのためにすべての組み合わせを試しましたが、組み合わせの数は予測と正解が増えると爆発的に増えます。DETR では、この最適な割り当てを効率よく求めるハンガリアン法を使います。

DETR の長所と弱点

長所弱点
アンカーや NMS がなく、全体の構成が単純学習が収束するまでに時間がかかる
COCO で、よく調整された Faster R-CNN と同等の精度小さな物体の検出が苦手

この弱点は、その後の Deformable DETR などの改良で大きく改善され、Transformer を使った検出器は今の主流の 1 つになっています。

物体検出の手法の流れ

この記事で紹介した手法を年代順に並べます。

年手法ポイント
2014R-CNN候補の領域を CNN で分類する二段階の方式
2015Fast R-CNN画像全体に CNN を 1 回かけ、候補の特徴を切り出す(RoI プーリング)
2015Faster R-CNN候補を出す部分も RPN として CNN に組み込み、アンカーを導入
2016YOLOマス目ごとに枠と種類を直接出す一段階の方式でリアルタイム化
2016SSD複数の大きさの特徴マップとアンカーで、大小の物体を一段階で検出
2017FPN・RetinaNet特徴のピラミッドと、背景だらけ問題を解くフォーカルロス
2020DETRTransformer で物体の集合を直接出し、アンカーと NMS をなくす

まとめ

  • 物体検出は、画像の中の物体ごとに「枠(位置と大きさ)」と「種類」を出すタスクで、物体の数が画像ごとに違う点と、位置も当てる点が画像分類より難しい
  • 枠の当たり具合は IoU(重なり ÷ 合わせた面積)で測り、学習・NMS・評価のすべてで使う
  • 二段階の検出器は「候補を出す → 候補ごとに分類」で、R-CNN → Fast R-CNN → Faster R-CNN と、CNN の計算を共有しながら全体をニューラルネットワーク化してきた
  • アンカーは各位置に置いた枠のひな形で、モデルは座標そのものではなくアンカーからのずれを学習する
  • 同じ物体への重複した枠は、NMS でスコアの高いものだけ残してまとめる
  • 一段階の検出器(YOLO・SSD・RetinaNet)は 1 回の計算で枠と種類を出し、リアルタイムの用途に向いている
  • 性能は、種類ごとの AP(再現率と適合率の曲線の面積)を平均した mAP で評価する
  • DETR は Transformer と 1 対 1 の組み合わせによる学習で、アンカーと NMS をなくした

参考

  • R. Girshick et al., "Rich feature hierarchies for accurate object detection and semantic segmentation", CVPR 2014(arXiv:1311.2524)
  • R. Girshick, "Fast R-CNN", ICCV 2015(arXiv:1504.08083)
  • S. Ren et al., "Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks", NeurIPS 2015(arXiv:1506.01497)
  • J. Redmon et al., "You Only Look Once: Unified, Real-Time Object Detection", CVPR 2016(arXiv:1506.02640)
  • W. Liu et al., "SSD: Single Shot MultiBox Detector", ECCV 2016(arXiv:1512.02325)
  • T.-Y. Lin et al., "Feature Pyramid Networks for Object Detection", CVPR 2017(arXiv:1612.03144)
  • T.-Y. Lin et al., "Focal Loss for Dense Object Detection", ICCV 2017(arXiv:1708.02002)
  • N. Carion et al., "End-to-End Object Detection with Transformers", ECCV 2020(arXiv:2005.12872)