LLMを使ったオープンボキャブラリー物体検出「LLMDet」を試す
ここで見つけた
そういえばRedditにもスレがあった。(ところで題材がなぁ・・・)
「LLMDet: Learning Strong Open-Vocabulary Object Detectors under the Supervision of Large Language Models」を試してみたところ、その面白い結果に思わず共有したくなりました!LLMDet は、大規模言語モデル(LLM)の力を活用して、トレーニング中に見たことのない任意のオブジェクトカテゴリも検出できる、オープンボキャブラリーオブジェクト検出のための高度なシステムです。
HuggingFace Spaceのデモ
GitHubレポジトリ。学習用コードもある様子。
モデルはTiny / Base / Large の3つ
ライセンスはコードもモデルもApache-2.0のようだけど、いろいろ記載されている学習データなどはどうなのかしら。
お試し程度に動かすだけなら、レポジトリ内のhf_model
ディレクトリの中にあるコードだけでいけそう。Colaboratory T4で。
レポジトリクローン
!git clone https://github.com/iSEE-Laboratory/LLMDet
%cd LLMDet
hf_model
Directoryに移動
%cd hf_model
demo_hf.py
が実行スクリプトになっていて、中でmodeling_grounding_dino.py
を読んでいるみたい。demo_hf.py
の内容をセル内に貼って、結果をそのまま表示するようにした。
import requests
import torch
from PIL import Image, ImageDraw, ImageFont
from transformers import GroundingDinoProcessor
from modeling_grounding_dino import GroundingDinoForObjectDetection
def draw_boxes(image, boxes, labels):
"""
画像に境界ボックスとラベルを描画し、変更した画像を返す。
:param image: PIL Imageオブジェクト
:param boxes: Tensor またはリスト、形式は [[x_min, y_min, x_max, y_max], ...]
:param labels: ラベルのリスト、形式は [label1, label2, ...]
:return: 変更後の PIL Image オブジェクト
"""
# 画像を編集可能な形式に変換
draw = ImageDraw.Draw(image)
# 文字のフォントとサイズを選択
font = ImageFont.load_default()
for box, label in zip(boxes, labels):
x_min, y_min, x_max, y_max = box
# 境界ボックスの描画
draw.rectangle([x_min, y_min, x_max, y_max], outline="red", width=2)
# ラベルの描画
draw.text((x_min, y_min - 10), label, fill="red", font=font)
return image
model_id = "fushh7/llmdet_swin_tiny_hf"
device = "cuda" if torch.cuda.is_available() else "cpu"
processor = GroundingDinoProcessor.from_pretrained(model_id)
model = GroundingDinoForObjectDetection.from_pretrained(model_id).to(device)
image_url = "http://images.cocodataset.org/val2017/000000039769.jpg"
image = Image.open(requests.get(image_url, stream=True).raw)
# ネコとリモコンをチェックする
# 超重要: クエリのテキストは、全部小文字、かつ、最後はドット(".") で終わる必要がある
text = "a cat. a remote control."
inputs = processor(images=image, text=text, return_tensors="pt").to(device)
with torch.no_grad():
outputs = model(**inputs)
results = processor.post_process_grounded_object_detection(
outputs,
inputs.input_ids,
box_threshold=0.4,
text_threshold=0.3,
target_sizes=[image.size[::-1]]
)
print(results)
output_image = draw_boxes(image.copy(), results[0]['boxes'].cpu().numpy(), results[0]['labels'])
display(output_image)
結果
[{'scores': tensor([0.5353, 0.4704, 0.5342], device='cuda:0'), 'boxes': tensor([[342.0378, 22.5324, 637.2928, 374.8930],
[ 10.8925, 51.2270, 317.8449, 470.8001],
[ 37.7837, 69.6901, 177.3081, 118.6619]], device='cuda:0'), 'text_labels': ['a cat', 'a cat', 'a remote control'], 'labels': ['a cat', 'a cat', 'a remote control']}]
自分の手持ちの画像でもやってみた。
神戸の風景
(snip)
image_url = "https://storage.googleapis.com/zenn-user-upload/82968d23b6c5-20250228.jpg"
image = Image.open(requests.get(image_url, stream=True).raw)
text = "sky. sea. building. mountain. boat."
(snip)
[{'scores': tensor([0.8184, 0.8414, 0.6508, 0.6151, 0.7214, 0.6171, 0.4473, 0.5161, 0.4073,
0.4998], device='cuda:0'), 'boxes': tensor([[6.7393e+02, 2.5327e+02, 7.5859e+02, 4.6846e+02],
[6.9305e-01, 6.9351e-01, 1.0234e+03, 4.6487e+02],
[8.7451e+02, 4.4858e+02, 1.0236e+03, 5.1966e+02],
[1.6732e+02, 3.2025e+02, 3.7676e+02, 4.6387e+02],
[1.0167e+02, 3.2238e+02, 1.6380e+02, 4.1626e+02],
[1.0550e+00, 5.0082e+02, 1.0230e+03, 7.6615e+02],
[7.9681e+02, 3.8835e+02, 8.5243e+02, 4.3930e+02],
[3.3995e-01, 3.6557e+02, 1.0453e+02, 4.1574e+02],
[8.6709e+02, 3.7127e+02, 8.9994e+02, 4.2465e+02],
[3.6860e+02, 4.0170e+02, 5.3075e+02, 4.4575e+02]], device='cuda:0'), 'text_labels': ['building', 'sky', 'boat', 'building', 'building', 'sea', 'building', 'mountain', 'building', 'mountain'], 'labels': ['building', 'sky', 'boat', 'building', 'building', 'sea', 'building', 'mountain', 'building', 'mountain']}]
今回は Tiny を使用したが、VRAM消費はこんな感じ。
Tue Jul 22 00:50:31 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.54.15 Driver Version: 550.54.15 CUDA Version: 12.4 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 Tesla T4 Off | 00000000:00:04.0 Off | 0 |
| N/A 76C P0 35W / 70W | 2420MiB / 15360MiB | 0% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
そういえばGeminiでもできる
自分は物体検出みたいな領域はほとんど触れていないので、この凄さを正しく理解できていないと思う。いや、すごいのはすごいのだけど、既存のものと比べて「どう」すごいのか?がわかっていない。
alphaXivで聞いてみた
これすごいのはすごいと思うのですが、既存のソリューションと比較した場合の利点が知りたいです。
ご質問ありがとうございます。この論文が提案する「LLMDet」の既存研究に対する主な利点は、大規模言語モデル(LLM)を用いて「画像全体に関する詳細なキャプション」を生成し、これを物体検出器の学習に利用する点にあります。
このアプローチにより、以下のようないくつかの重要な利点が生まれます。
よりリッチな表現学習: 従来の手法では、物体ごとの短いキャプション(例:「椅子」「犬」)や、単純な説明文を学習に用いることが一般的でした。しかしLLMDetは、画像全体を物語るような長いキャプション(物体の種類、色、質感、動作、位置関係などを含む)を利用します。これにより、個々の物体だけでなく、物体間の関係性や背景を含めたシーン全体の文脈をモデルが深く理解できるようになり、よりリッチで高品質な視覚表現を獲得できます。
優れた汎化性能と希少クラスの認識向上: 既存の強力なLLMが持つ広範な言語知識を「教師」として活用することで、検出器はその汎化能力を大きく引き継ぎます。論文中の実験(Table 2など)では、特に学習データに少ししか現れない「希少クラス(rare classes)」の検出精度がベースラインモデル(MM-GDINO)から大幅に向上していることが示されています。これは、詳細なキャプションによって、未知の物体や状況に対する頑健性が高まるためです。
高い転移能力とデータ効率: LLMDetは、LVIS、ODinW、COCO-Oといった多様なベンチマークにおいて、非常に高いゼロショット性能(学習時に見ていないデータセットに対する性能)を達成しています。これは、特定のデータセットに過剰適合することなく、幅広いドメインに適応できる能力を持っていることを意味します。また、論文では、他のSOTA(State-of-the-art)モデルよりも少ない学習データで同等以上の性能を達成している点も強みとして挙げられています(Table 2のキャプション参照)。
相乗効果(Mutual Benefits): この研究の興味深い点は、LLMの知識で強化された物体検出器(LLMDet)が、今度は逆により高性能な大規模マルチモーダルモデル(LMM)を構築するための強力な視覚基盤モデルとして機能することを示した点です。つまり、LLMが検出器を賢くし、その賢くなった検出器がさらにLMMを進化させるという、相互に利益のあるサイクルを生み出せる可能性を秘めています。
まとめると、LLMDetは単に物体を検出するだけでなく、**LLMの力を借りて「画像の内容をより深く、文脈的に理解する」**ことで、既存のオープンボキャブラリー物体検出の性能を大きく超えることに成功した、という点が最大の利点です。
既存のソリューションはどのようなものですか?
はい、LLMDetが登場する以前の、既存のオープンボキャブラリー物体検出(OVD)の代表的なソリューションには、主に以下のようなアプローチがありました。LLMDetはこれらのアプローチの課題を解決、あるいは発展させたものと位置づけられます。
既存の主要なアプローチ
Vision-Language Model (CLIPなど)の知識を活用するアプローチ
- 概要: 画像全体とテキスト全体のマッチングが得意なCLIPのような大規模な視覚言語モデル(VLM)をベースにする方法です。CLIPは「この画像は猫の写真です」といった文章と画像の関連性を学習していますが、物体の「位置」を特定するようには設計されていません。
- 手法: このアプローチでは、CLIPが持つ豊富な単語と画像の知識を、物体検出器に「蒸留(distillation)」したり、CLIPのアーキテクチャを物体検出タスクに適用したりします。
- 代表的なモデル: OWL-ViT、F-VLMなど。
- 課題: 画像レベルで学習しているため、物体の正確な位置特定や、複数の物体が複雑に絡み合うシーンの理解には限界がありました。
物体検出とフレーズグラウンディングを統合するアプローチ
- 概要: 「物体検出」と「フレーズグラウンディング」(文中の「赤い帽子をかぶった男性」といった特定の語句が画像のどの領域に対応するかを当てるタスク)を、一つの統一されたフレームワークで学習させるアプローチです。
- 手法: 物体領域とその領域を説明するテキスト(名詞句)を直接関連付けて学習します。これにより、モデルはテキストで指定された任意の物体を検出する能力を獲得します。
- 代表的なモデル: この分野の先駆けとなったGLIP (https://arxiv.org/abs/2112.03857) や、その後継で非常に強力なGrounding DINO (https://arxiv.org/abs/2303.05499) が有名です。LLMDetのベースラインとしても、このGrounding DINO系統のモデル(MM-GDINO)が使われています。
- 課題: テキストはあくまで物体を指し示すための「句」が中心であり、画像全体の文脈や物体間の関係性をリッチに表現するには至っていませんでした。
領域ごとの短いキャプション生成と同時に学習するアプローチ
- 概要: 検出した各物体の領域(バウンディングボックス)に対して、「青い車」「走っている犬」のような短いキャプションを生成するタスクを、物体検出と同時に学習させるアプローチです。
- 手法: これにより、検出器は単に物体を見つけるだけでなく、その物体が何であるかを言語化する能力も同時に獲得し、表現力を高めようとします。
- 代表的なモデル: CapDet (https://arxiv.org/abs/2303.09712) や DetCLIPv3 (https://arxiv.org/abs/2311.16912) などが挙げられます。
- 課題: 生成されるキャプションが各領域に閉じた「短い」ものであるため、画像全体にわたる複雑な関係性や、より詳細な属性(例:「レンガの壁に取り付けられた木製の棚」)の学習には限界がありました。
アプローチの比較まとめ
アプローチ 主な手法 テキストデータの粒度 代表的なモデル 1. VLM活用 CLIPなどの知識を物体検出器に蒸留・応用 画像全体 OWL-ViT 2. グラウンディング統合 物体領域と対応する名詞句を直接学習 物体領域ごとの「句」 GLIP, Grounding DINO 3. 領域キャプション生成 物体領域ごとに短い説明文を生成 物体領域ごとの「短い文」 CapDet, DetCLIPv3 LLMDet (本研究) LLMに詳細な画像全体のキャプションを生成させ、それを学習に利用 画像全体の「詳細な長文」 LLMDet これらの既存ソリューションに対して、LLMDetが新しいのは、特定の領域ごとではなく、画像全体に対する、非常に詳細で長いキャプションを大規模言語モデル(LLM)に生成させ、そのリッチな情報を直接検出器の学習に利用する点です。これにより、既存手法では捉えきれなかった、より大局的な文脈や、細かな属性、物体間の関係性までを学習することが可能になり、性能を大きく向上させることができたのです。
YOLOとかも既存のソリューションと言えますかね
はい、その通りです。YOLO (You Only Look Once)は、物体検出における非常に重要で代表的な「既存のソリューション」です。
ただし、LLMDetが解決しようとしている課題の文脈で考えると、両者は目指す方向性が異なっており、その違いを理解することが重要です。
YOLOの位置づけ:クローズドセット物体検出
YOLOが属するのは 「クローズドセット(Closed-Set)物体検出」 と呼ばれるカテゴリです。
- 仕組み: YOLOは、あらかじめ決められたカテゴリのリスト(例:COCOデータセットの「人」「車」「犬」「猫」など80種類)を学習します。学習時に使われたデータセットに含まれる物体しか検出することができません。
- 強み: その最大の強みは、圧倒的な処理速度です。名前の通り、画像を一度見るだけで物体の位置と種類を特定できるため、リアルタイムでの動画解析や自動運転のような、速度が求められるアプリケーションで絶大な人気を誇ります。
- 弱み: 学習していない未知の物体(例:「ユニコーンのぬいぐるみ」「特定のロゴが入ったカップ」など)を検出することはできません。新しい物体を検出させたければ、その物体を含むデータセットを大量に用意して、モデルを再学習またはファインチューニングする必要があります。
LLMDetの位置づけ:オープンボキャブラリー物体検出
一方で、LLMDetやその前身であるGLIP、Grounding DINOなどが属するのは**「オープンボキャブラリー(Open-Vocabulary)物体検出」または「オープンワールド(Open-World)物体検出」**と呼ばれるカテゴリです。
- 仕組み: こちらは、**自由なテキスト記述(自然言語)**によって、学習時に見たことのない物体でも検出しようとします。画像と単語の一般的な関係性を学習しているため、カテゴリリストに縛られません。
- 強み: 圧倒的な柔軟性と汎化性能です。「赤い帽子をかぶった男性」や「芝生の上にある青いボール」といった具体的な指示で物体を探し出すことができます。再学習なしで、未知の物体に対応できるのが最大の利点です。
- 弱み: 一般的に、クローズドセットのモデルであるYOLOと比較すると、推論速度が遅い傾向にあります。
関係性のまとめ
分かりやすく言えば、以下のような違いになります。
特徴 従来のYOLO(クローズドセット) LLMDetなど(オープンボキャブラリー) 検出対象 事前に定義されたカテゴリのリスト 自由なテキストで記述された任意の物体 柔軟性 低い(未知の物体は検出不可) 非常に高い(未知の物体も検出可能) 学習 新しい物体には再学習が必要 再学習は不要 主な用途 リアルタイム性が重要なアプリケーション 検索、インタラクティブな分析、ロボットの指示など 最新動向:YOLOの進化
非常に興味深いことに、この「クローズドセット」と「オープンボキャブラリー」の境界線は、最近なくなりつつあります。
YOLOのアーキテクチャの速さを活かしつつ、オープンボキャブラリーの能力を持たせようという研究が活発に行われています。その代表例がYOLO-World (https://arxiv.org/abs/2401.17270) です。このモデルは、YOLOの高速な検出能力と、CLIPのような視覚言語モデルの知識を組み合わせることで、リアルタイムでのオープンボキャブラリー物体検出を目指しています。
したがって、ご質問への回答をまとめると、
- はい、YOLOは物体検出の既存ソリューションの代表格です。
- しかし、それは主に「クローズドセット」というカテゴリに属し、LLMDetが目指す「オープンボキャブラリー」とは異なるアプローチでした。
- 現在では、YOLO自身も進化し、オープンボキャブラリーの能力を取り込もうとしており、両者の技術は融合しつつあります。
なるほど。逆に既存のソリューションがまだ優れている点ってありますか?
はい、もちろんです。非常に鋭いご質問です。どのような新技術もトレードオフを伴うもので、LLMDetが全ての面で優れているわけではありません。既存のソリューションが依然として優れている、あるいは特定の状況下でより適している点は明確に存在します。
主に以下の点が挙げられます。
1. 推論速度 (Inference Speed)
まだ優れているソリューション: YOLOファミリー
これは既存ソリューションの最大の利点です。YOLOのようなモデルは、アーキテクチャそのものが超高速な処理のために徹底的に最適化されています。
- 理由: LLMDetは、推論時にはLLM部分を切り離すとはいえ、その基盤となる視覚モデル(Vision Backbone)はSwin Transformerのような大規模で複雑なものを使用しています。一方、YOLOはリアルタイム処理を念頭に置いた、より軽量で効率的なアーキテクチャを持っています。
- 適した用途: 自動運転の周辺認識、防犯カメラのリアルタイム解析、工場のラインでの製品検査など、1秒間に何十フレームも処理する必要があるアプリケーションでは、YOLOの速度が不可欠です。
2. 特定タスクにおける精度と安定性 (Accuracy and Stability on Specific Tasks)
まだ優れているソリューション: 特定のデータセットでファインチューニングされたクローズドセットモデル(例: カスタム学習させたYOLOやFaster R-CNNなど)
もし検出したい物体の種類が限定されており、その物体の画像データを大量に集められる場合、そのデータだけで学習させた専門モデルの方が高い性能を発揮することがあります。
- 理由: オープンボキャブラリーモデルは非常に幅広い知識を持つがゆえに、予期せぬ誤検出(見た目が似ている別の物体と混同するなど)をすることがあり得ます。一方、例えば「ボルト、ナット、ワッシャーの3種類だけを確実に検出したい」というタスクでは、その3種類に特化したモデルを学習させる方が、ノイズが少なく安定した結果を出しやすくなります。
- 適した用途: 工場の品質管理、特定の医療画像からの病変検出など、決まった種類の物体を、最高の精度と信頼性で検出したい場合。
3. 計算資源(メモリとハードウェア要件)
まだ優れているソリューション: YOLOの軽量版(YOLOv8nなど)やその他の軽量モデル
LLMDetの学習・推論には、それなりの計算能力(特にVRAM容量の大きいGPU)が要求されます。
- 理由: LLMDetの学習プロセスは、画像データと詳細なキャプションを扱うため非常に複雑で、多くの計算資源を必要とします。推論時でも、ベースとなるモデルが大きいため、スマートフォンや安価なエッジデバイスのようなリソースが限られた環境で動かすのは困難です。一方、YOLOには組み込み機器向けの軽量版が存在し、より幅広いハードウェアで動作させることができます。
- 適した用途: スマートフォンアプリ、IoTカメラ、ドローンなどのエッジコンピューティング環境。
4. モデルの成熟度とエコシステム
まだ優れているソリューション: YOLO、Faster R-CNNなど
YOLOは長年の歴史があり、世界中の開発者によって使われてきました。
- 理由: その結果、ドキュメント、チュートリアル、コミュニティによるサポート、学習済みモデル、簡単な実装ライブラリ(Ultralyticsなど)が非常に充実しています。何か問題が起きても、解決策を見つけやすいです。LLMDetはまだ研究段階の新しいモデルであり、誰もが簡単に利用したり、商用システムに組み込んだりするにはハードルが高いと言えます。
- 適した用途: 迅速に開発を進めたい場合や、物体検出モデルの運用実績が重要なプロジェクト。
まとめ
観点 既存ソリューション (特にYOLO) の利点 LLMDetの利点 速度 ◎ 非常に高速 ◯/△ 比較的遅い 特定タスク精度 ◎ 安定して高精度 ◯ 汎用的だが時に不安定 計算資源 ◎ 軽量で省リソース △ 多くの資源が必要 エコシステム ◎ 非常に成熟 △ 発展途上 柔軟性 × 事前定義されたカテゴリのみ ◎ 任意のテキストで検出可能 結論として、「最高のソリューション」は存在せず、 「何がしたいか(What)」 と 「どのような環境で動かしたいか(Where)」 によって最適な選択は変わります。
- 速度と効率性が最優先なら、依然としてYOLOが王様です。
- 未知の物体を柔軟に扱いたいという要求が最優先なら、LLMDetのようなオープンボキャブラリーモデルが最適です。