stMind

about Tech, Computer vision and Machine learning

BLIP-2の論文メモとゼロショットのimage-to-text生成のお試し

この論文では、事前学習済みの画像エンコーダーと大規模言語モデルを利用し、軽量なQuerying Transformer(Q-former)で視覚と言語のモダリティギャップを埋める、 汎用的で効率的な新しい事前学習戦略であるBLIP-2を提案しています。 BLIP-2は、既存手法より少ないパラメータで様々なVision LanguageタスクでState-of-the-artな性能を達成していて、例えばゼロショットVQAv2ではFlamingo80Bよりも54倍少ないパラメータで8.7%の性能改善を示しました。また、自然言語の指示に従ったゼロショットのimage-to-text 生成という、このモデルの新しい能力も紹介しています。

arxiv.org

イントロダクション

  • Vision Language Pre-training(VLP)研究では、様々な後続タスクで高い精度を達成するため、より大規模なモデルが提案されている。大規模なモデルと大規模なデータセットで事前学習するため、計算コストが非常に大きい。
  • この論文では、学習済みの視覚モデルと言語モデルを使って、汎用的で計算効率の高いVLP手法を提案する。事前学習においては、計算コストの削減と、破滅的忘却を防ぐために、視覚と言語の事前学習済みモデルはパラメータを固定する。
  • パラメータを固定したユニモーダルモデルをVLPで使う際には、視覚と言語の間でクロスモーダルなアラインメントが重要になる。特に、LLMは事前学習で画像を用いていないため、これは非常にチャレンジングで、また既存手法は画像から言語への生成ロスを使っていて、これでは不十分。
  • BLIP-2では、 このアラインメントを実現するためのQ-formerを提案する。Q-formerは、学習可能なクエリ埋め込みを使って画像エンコーダーから視覚特徴を抽出する軽量なTransformer。画像エンコーダーとLLMの間の情報ボトルネックとして機能し、LLMがテキストを出力するのに最も有用な視覚特徴を抽出する。
  • Q-formerは二段階の事前学習を行う。最初のステージで、視覚言語表現学習を行い、テキストに最も関連する視覚表現を学習させる。次のステージでは、視覚から言語の生成学習を行う。

提案手法

Q-formerのアーキテクチャ

  • Q-formerは2つのTransformerで構成される。
  • image transformerに入力する固定数のクエリ埋め込みを作成する
    • self attentionでクエリ埋め込み同士の関係を計算する
    • image encoderの出力特徴とcross attentionで関係を計算する
    • self attentionでクエリ埋め込みとテキスト埋め込みの関係を計算する
  • Q-formerはBert-baseの重みで初期化する。Cross attention層はランダム初期化する。
    • クエリもモデルのパラメータとし、トータルで188Mパラメータ
  • 実験では、32個のクエリを使用し、各クエリ埋め込みは768次元とする。
    • Zを出力のサイズとすると、Z(32 x 768)はfreezeしたimage encoderの出力次元よりも遥かに小さい(ViT-Lで257 x 1024)。
  • このボトルネックアーキテクチャと事前学習の目的を組み合わせることで、クエリがテキストと最も関連する視覚特徴を抽出するよう促す

事前学習

表現学習ステージ

  • 表現学習段階では、Q-formerは画像エンコーダーを組み合わせて使用し、画像とテキストのペアを用いて事前学習を行う。
  • この学習では、クエリとテキストの相互作用を制御するために、異なるアテンションマスクを適用し、3つの事前学習目的を共同で最適化する。

Image Text Contrastive Learning

  • Image-Text Contrastive Learningでは、画像とテキストの相互情報量が最大になるように、モデルは画像とテキスト表現のアラインメントを学習する
  • このために、画像とテキストのポジティブペアの類似度を、ネガティブペアの類似度と対比させる
  • 画像エンコーダーからの出力クエリー表現Zは、テキスト変換器からのテキスト表現tとアラインメントする。tはCLSトークンの出力埋め込みで、Zは複数の埋め込みを含む(クエリごとに一つ)ため、それぞれをtと比較し、最も高い類似度を選択する。
  • 事前にクエリとテキストが互いに見えないように(情報漏洩を防ぐために)、単一モーダルのアテンションマスクを使用する

Image-Grounded Text Generation

  • ITG損失は、入力画像に基づいてQ-Formerモデルがテキストを生成するように学習される
  • Q-Formerでは、画像エンコーダーとテキストトークンは直接作用しないため、テキストを生成するためには、まずクエリによって必要な情報が抽出され、次にself attention層を介してテキストトークンに渡されなければならない
  • そのため、クエリはテキストのすべての情報を包含する視覚的特徴を抽出することを促される
  • クエリとテキストの相互作用を制御するために、multimodal causal self attentionマスクを採用している。
  • クエリー同士は相互作用することができるが、テキストトークンに注目することはできない。 一方、各テキストトークンはすべてのクエリーとその前のテキストトークンに対応することができる。

Image-Text Matching

  • ITMは、画像とテキストの表現間でfine-grainedなアラインメントを学習することが目的
  • これは、画像とテキストのペアがポジティブ(一致)かネガティブ(不一致)かを予測するバイナリ分類タスク
  • すべてのクエリとテキストが互いに注意を向けることができる双方向の自己注意マスクを使用して、これにより出力クエリ埋め込みZはマルチモーダルな情報を捉える
  • 各出力クエリ埋め込みを2クラスの線形分類器に入力してロジットを取得し、すべてのクエリのロジットを平均して出力マッチングスコアを得ます。

ゼロショットのimage-to-text生成

BLIP-2のゼロショットで画像からテキストを生成を試してみます。

github.com

対象となる画像は、自由の女神にしてみます。

import torch
from PIL import Image
import requests
from lavis.models import load_model_and_preprocess

img_url = 'https://github.com/Gladiator07/BLIP2-Report/blob/main/assets/vqa/statue-of-liberty.jpg?raw=true'
raw_image = Image.open(requests.get(img_url, stream=True).raw).convert('RGB')   
display(raw_image.resize((596, 437)))

アーキテクチャはblip2_t5を選択します。

# setup device to use
device = torch.device("cuda") if torch.cuda.is_available() else "cpu"

# we associate a model with its preprocessors to make it easier for inference.
model, vis_processors, _ = load_model_and_preprocess(
    name="blip2_t5", model_type="pretrain_flant5xxl", is_eval=True, device=device
)

image = vis_processors["eval"](raw_image).unsqueeze(0).to(device)

「どこの都市か?」を質問すると「ニューヨーク」と回答が得られる。

model.generate({"image": image, "prompt": "Question: which city is this? Answer:"})
# -> ['new york city']

続けて、「なぜそう思うか?」を質問すると、「自由の女神がある」と回答される。

model.generate({
    "image": image,
    "prompt": "Question: which city is this? Answer: new york city. Question: why do you think so?"})
# -> ['the statue of liberty is in the foreground']

さらに続けて「自由の女神の高さは?」と質問すると、305ft=約93mと回答が得られた。

context = [
    ("which city is this?", "singapore"),
    ("why do you think so?", "the statue of liberty is in the foreground"),
]
question = "How tall is the statue of liberty?"
template = "Question: {} Answer: {}."

prompt = " ".join([template.format(context[i][0], context[i][1]) for i in range(len(context))]) + " Question: " + question + " Answer:"

model.generate(
    {
    "image": image,
    "prompt": prompt
    },
    use_nucleus_sampling=False,
)

# -> ['305 ft']

まとめ

フリーズされた事前訓練済みの画像エンコーダーと大規模言語モデル(LLM)を活用した、汎用的で効率的なVLP手法であるBLIP-2のメモと、ゼロショットのimage-to-text生成を試してみた内容を紹介しました。今回はSalesforceのLAVISレポジトリのコードで試行しましたが、Huggingfaceにも移植されているので、そちらからも利用することができます。

参考