こんにちは、CCCMKホールディングス TECH LAB三浦です。
12月なのにとても暖かくなったり、12月らしい寒さになったり、最近気候が安定していない感じがします。気候が安定しないと身体も疲れやすくなりますね。年齢を重ねるにつれ、体調の変化に敏感になってきました。疲れたな、と思ったときは、ストレッチをしたり休憩したりして自分の体調を気遣うようになりました。
前回Jetson AGX Orin開発者キットをセットアップし、生成AIを動かしてみた話をご紹介しました。
前回の段階ではオープンソースのLLMを動作させることは出来たのですが、NanoOWLという物体検出系のプロジェクトを動かすことが出来ませんでした。
その後Jetpackのバージョンの修正などを行い、なんとか動かすことが出来るようになりました。実際に動かしてみると、ベースになっているOWL-ViTという手法に興味が湧き、提案論文を読んでどんな手法なのかを調べてみました。今回は調べた内容についてまとめてみたいと思います。
Jetson AGX Orin開発者キットでNanoOWLが動いた時の情報
最初に前回は動かすことが出来なかったNanoOWLを、Jetson AGX Orin開発者キットで動かせた時の情報について、記載します。
以下がJetson AGX Orin開発者キットでNanoOWLが動いた時のjetson-statsで確認出来た情報です。
特に重要な箇所がL4TとJetpackのバージョンで、もしjetson-containerに含まれるプロジェクトで動作しないものがあれば、ここが古いバージョンになっていないかを確認すると良いと思いました。
NanoOwlが動いている様子
JetsonにUSBカメラを取り付け、dockerコンテナを起動してプログラムを実行すると、ブラウザで以下のような画面を表示させることが出来ます。
テキストボックスに認識したい任意の物体の名称や説明文を入力すると、カメラの画像から該当する物体を検出することが出来ます。例えば先の画像の様に"human hand"と入力すれば手全体を検出しますが、次の画像の様に"human finger"と入力すれば、指を検出するようになります。
Open-Vocabulary Object Detection(OVD)
これまでの物体検出は与えられた有限個のクラスラベルに属する物体が画像のどこに映っているのかを検出するタスクでした。それに対しNanoOWLでは検出した物体を任意のテキストで指定することが出来ています。
このように任意のテキストで指定された物体を画像から検出するタスクは"Open-Vocabulary Object Detection(OVD)"と呼ばれています。
OWL-ViT
NanoOWLはOWL-ViTをJetsonでリアルタイムで稼働させることを目的としたプロジェクトで、OWL-ViTという手法がベースになっています。OWL-ViTはOVDを実現するための手法の一つで、次の論文で提案されています。
- Title: Simple Open-Vocabulary Object Detection with Vision Transformers
- Authors: Matthias Minderer, Alexey Gritsenko, Austin Stone, Maxim Neumann, Dirk Weissenborn, Alexey Dosovitskiy, Aravindh Mahendran, Anurag Arnab, Mostafa Dehghani, Zhuoran Shen, Xiao Wang, Xiaohua Zhai, Thomas Kipf, Neil Houlsby
- Submitted: 12 May 2022 (v1), last revised 20 Jul 2022
- arXivURL:https://arxiv.org/abs/2205.06230
OWL-ViTに興味が湧き、この論文を読んで調べてみました。以降この論文の内容を元に、OWL-ViTについて調べたことをまとめていこうと思います。
OWL-ViTのモデル構造
OWL-ViTのモデルは2つのTransformer構造で構成されています。一つはテキスト情報を取り扱うTansformerで、もう一つが画像を扱うTransformer(Vision Transformer: ViT)です。両方ともTransformerのEncoderのみを使用しています。
テキストを入力するTransformerは、検出対象を表すテキスト(物体名や説明情報)を入力し、埋め込み表現を獲得するために使用します。複数の検出対象が与えられた場合は、それぞれのテキストごとに埋め込み表現を出力します。
一方ViTの方は画像を格子(パッチ)状に分割し、それぞれに対して埋め込み表現を獲得するために使用します。
OWL-ViTの推論では、画像のパッチごとに画像の埋め込み表現と物体テキストの埋め込み表現を用いて、その画像の箇所に対応する物体が存在するかどうかの度合いを計算します(おそらく内積計算をしていると思います)。さらに物体の位置を表すバウンディングボックスの位置と大きさも計算します。
OWL-ViTでは画像パッチごとに物体検知を行うため、一度に検出できる物体の数はパッチの数(ViTのトークン数)が上限になります。実際はどれくらいの数になるかというと、ViT-B/32という縦横32個のパッチに画像を分割して使用するViTに768x768の画像を入力した場合は576になります。この値は現在公開されている物体検出データセットに含まれる画像に含まれている物体数の最大値が294であることを考えると、十分に大きな値であると言えます。
OWL-ViTの事前学習
OWL-ViTがシンプルな構造でありながら高い精度を出すことが出来る要因として事前学習の過程があります。事前学習の段階ではCLIPなどと同様に画像とテキストのペアを使って対照学習を行います。CLIPについては以前こちらの記事でまとめています。
事前学習後、ViTの最後のToken poolingとprojectionレイヤを取り除き、代わりにLinear projectionとMLP headを追加して物体検出用のデータセットを用いてFine-Tuningを行います。
Linear projectionは画像のパッチごとの埋め込み表現を獲得するためのレイヤで、物体テキストの埋め込み表現と組み合わせて物体の種類判定に使用されます。MLP headはバウンディングボックス推定用に使用されます。
小数のサンプル画像例示による物体検出
OWL-ViTでは検出したい物体をテキストでなく、少数のサンプル画像を使って指定することが可能です。
手順は、まず例となる画像(クエリ画像と呼びます)とそこに含まれている検出したい物体位置を示すバウンディングボックスの情報をOWL-ViTのモデルに入力し推論処理を行い、画像パッチごとの埋め込み表現と物体位置を表すバウンディングボックスの推計結果を得ます。次に出力されたバウンディングボックスの推計結果と検出対象の物体位置を表すバウンディングボックスの重なり具合が高い画像パッチを選びます。最後に選ばれた画像パッチの中で、他と類似しない埋め込み表現を持つ画像パッチを選択し、その埋め込み表現をクエリ画像に対するクエリとして使用します。抽出されたクエリ(埋め込み表現)をテキストの埋め込み表現の代わりに使用することで、検出したい物体をサンプル画像で指定することが可能になります。
以下に論文のAppendixに掲載されている図を掲載します。
Fine-Tuningの精度向上に関するトピック
OWL-ViTのFine-Tuningにおいて精度を向上させるためのトピックがいくつか述べられています。その中でこれはすぐに試してみよう、と思ったトピックを以下にリストアップしてみます。
Text Encoderのlearning rateを小さくする
Fine-Tuningの際は画像のEncoder側のlearning rateよりもテキストのEncoder側のlearning rateを100倍程度小さくとると良いそうです。テキスト側のlearning rateを大きく取ってしまうと、事前学習で大量のテキストで学んだ情報をFine-Tuningによって破壊してしまうことが要因として挙げられています。ただしテキストのEncoderをFine-Tuningの際に学習対象にしない場合も精度が出ないそうです。複数の画像をタイル状に並べる
これもとても面白いな、と思ったAugmentationに関するトピックです。OWL-ViTのFine-Tuningでは画像をランダムに切り取る"random cropping"がAugmentationとして使用されています。この時アスペクト比を0.75から1.33の間になるようにし、元の画像の33%から100%の部分を切り取るという制限が設けられています。また、この処理でバウンディングボックスが削られてしまう場合がありますが、元のバウンディングボックスの60%以上が保たれているもののみ残すようにしています。その後灰色のエリアを画像の下部と右部に追加して正方形になるようにします。 そして学習画像としてこの正方形の画像1枚を使うだけでなく、4枚の画像を選んで2X2に並べて使ったり9枚の画像を選んで3x3に並べて使ったりします。それぞれ0.5, 0.33, 0.17の確率で発生するようにするそうです。
- テキストに対するAugmentation
物体を指定するテキストは"a photo of a {物体名}"のようなテンプレートを使用して生成しています。OWL-ViTのFine-Tuningではこのテンプレートを80個用意し、ランダムに使用しているそうです。ただし1つの画像の中で同じ物体(カテゴリ)に対しては同じテンプレートを使用する制限を設けているとのことです。
まとめ
ということで、Jetson AGX Orin開発者キットで動かしてみて興味を持ったOWL-ViTについて、どんな手法なのかを提案論文を読み、調べてみた内容をまとめてみました。任意のテキストで検出対象の物体を指定することが出来るだけでなく、サンプル画像を用いて物体を指定することが出来ることを知り、応用範囲がとても広そうだと感じました。今度はまだ実際に試したことがないサンプル画像による物体検出も試してみたいと思います。