CLIPの上位互換? BLIPで画像のキャプションを生成する

2022年2月4日金曜日

Artificial Intelligence

本記事では、2022年1月にSalesforceより発表されたBLIPと呼ばれる機械学習手法を使って画像のキャプションを生成する方法を紹介します。

アイキャッチ

BLIP

概要

BLIPは、2022年1月にSalesforceより論文発表された、視覚言語理解と視覚言語生成の両方に柔軟に対応する新しいVision-Language Pre-training(VLP)フレームワークです。

入力された画像に対するキャプションの生成(image captioning)では、CIDErで+2.8%、画像に対する質問に答えるVQAでは、VQAスコアで+1.6%など幅広い視覚言語タスクで最先端の結果を示している手法です。またvideo QAなどビデオ言語タスクに転移することでゼロショットパフォーマンスを発揮します。

導入

従来のVLPには、下記2点の課題が存在します。

  1. 視覚言語理解と視覚言語生成の両方に未対応
    既存のVLPはエンコーダーベースモデルエンコーダー・デコーダーモデルを採用しています。エンコーダーベースモデルは、キャプション生成などの視覚言語生成への転移が困難であり、エンコーダー・デコーダーモデルは、画像とテキストの探索などの視覚言語理解へ上手く適用されていません。

  2. ノイズの多いWebテキスト
    CLIPなどはWebから収集された画像とテキストのペアを事前にトレーニングしています。しかし、BLIPの論文では、ノイズの多いWebテキストが視覚言語学習に最適ではないことを示しています。

BLIPでは、上記2点の課題を以下の方法で解決しています。

  1. Multimodal mixture of Encoder-Decoder(MED)
    MEDは、画像に基づいたエンコーダー・デコーダーとして動作し、視覚言語理解、視覚言語生成に対して柔軟な転移学習を可能にするアーキテクチャです。

  2. Captioning and Filtering (CapFilt)
    ノイズの多い画像とテキストのペアから学習するための新しいデータセットブーストラッピング法です。
    事前トレーニングされたMEDを2つのモジュールに微調整します。1つはWeb画像に基づいて合成キャプションを生成するキャプション作成者、
    もう1つは元のWebテキストと合成テキストの両方からノイズの多いキャプションを削除するフィルターです。
blip_arch
出典: BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation

上図はBLIPの概念図です。BLIPは下記3つの機能のいずれかで動作する統一されたモデルです。

  1. ユニモーダルエンコーダーは、視覚と言語表現を調整するために、image-text contrastive (ITC) lossでトレーニングされます。
  2. 画像に基づくテキストエンコーダー(Image-grounded text encoder)は、cross attentionレイヤーを使用して、視覚と言語の相互作用をモデル化し、image-text matching (ITM) lossでトレーニングされます。
  3. 画像に基づくテキストデコーダー(Image-grounded text decoder)は、 language modeling (LM) lossでトレーニングされ、画像に与えられたキャプションを生成します。

デモ(Colaboratory)

イメージが付きづらいと思いますので、実際に動かしながらBLIPができることを見ていきます。
ソースコードは本記事にも記載していますが、下記のGitHubでも取得可能です。
GitHub - Colaboratory demo

また、下記から直接Google Colaboratoryで開くこともできます。
Open In Colab

なお、このデモはPythonで実装しています。
Pythonの実装に不安がある方、Pythonを使った機械学習について詳しく勉強したい方は、以下の書籍やオンライン講座などがおすすめです。

環境セットアップ

それではセットアップしていきます。 Colaboratoryを開いたら下記を設定しGPUを使用するようにしてください。

「ランタイムのタイプを変更」→「ハードウェアアクセラレータ」をGPUに変更

次にライブラリのインストール及び、BLIPのソースコードをGitHubから取得します。

%cd /content/

import sys
if 'google.colab' in sys.modules:
    print('Running in Colab.')
    !pip3 install transformers==4.15.0 timm==0.4.12 fairscale==0.4.4
    !git clone https://github.com/salesforce/BLIP
    %cd BLIP

テスト画像のセットアップ

次に、BLIPのデモに使用するテスト画像をセットアップします。

from PIL import Image
import requests
import torch
from torchvision import transforms
from torchvision.transforms.functional import InterpolationMode
from google.colab import files

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

#@markdown sample or uploadを選択
image_type ='upload' #@param ['sample', 'upload']
if image_type == 'sample':
    img_url = 'https://storage.googleapis.com/sfr-vision-language-research/BLIP/demo.jpg' 
    raw_image = Image.open(requests.get(img_url, stream=True).raw).convert('RGB')
else:
    uploaded = files.upload()
    uploaded = list(uploaded.keys())
    file_name = uploaded[0]
    raw_image = Image.open(file_name).convert('RGB')


w,h = raw_image.size
display(raw_image.resize((w//5,h//5)))

本記事では、ぱくたそ様の下記の画像を使用させていただきます。
レモンを持ったスムージー女子の写真素材

テスト画像

Image Captioningのセットアップ

上記テスト画像を入力として、BLIPにキャプションを予測させてみます。
始めに事前学習済みモデルをロードします。

from models.blip import blip_decoder

image_size = 384
transform = transforms.Compose([
    transforms.Resize((image_size,image_size),interpolation=InterpolationMode.BICUBIC),
    transforms.ToTensor(),
    transforms.Normalize((0.48145466, 0.4578275, 0.40821073), (0.26862954, 0.26130258, 0.27577711))
    ]) 
image = transform(raw_image).unsqueeze(0).to(device)     

model_url = 'https://storage.googleapis.com/sfr-vision-language-research/BLIP/models/model*_base_caption.pth'
    
model = blip_decoder(pretrained=model_url, image_size=384, vit='base')
model.eval()
model = model.to(device)

Image Captioning

それでは、キャプションを生成させてみます。

with torch.no_grad():
    caption = model.generate(image, sample=False, num_beams=3, max_length=20, min_length=5)
    print('caption: '+caption[0])

キャプションの出力結果は以下の通りです。

caption: a woman sitting at a table with fruits and vegetables

女性がテーブルの前に座っていること、フルーツや野菜が置いてあることなどが表現されていますね。

Visual question answering(VQA)のセットアップ

続いて、画像に対するQandAに答えるVQAのために学習済みモデルをロードします。

from models.blip_vqa import blip_vqa

image_size = 480
transform = transforms.Compose([
    transforms.Resize((image_size,image_size),interpolation=InterpolationMode.BICUBIC),
    transforms.ToTensor(),
    transforms.Normalize((0.48145466, 0.4578275, 0.40821073), (0.26862954, 0.26130258, 0.27577711))
    ]) 
image = transform(raw_image).unsqueeze(0).to(device)        

model_url = 'https://storage.googleapis.com/sfr-vision-language-research/BLIP/models/model*_vqa.pth'
    
model = blip_vqa(pretrained=model_url, image_size=480, vit='base')
model.eval()
model = model.to(device)

Visual question answering(VQA)

それでは、VQAを実施します。

#@title Question設定
#@markdown 画像に対する質問を英語で記載してください。
question = 'where is the woman sitting?' #@param {type:"string"}

with torch.no_grad():
    answer = model(image, question, train=False, inference='generate') 
    print('answer: '+answer[0])

上記では'where is the woman sitting?'と質問しています。
回答は以下の通りです。

answer: at table

このほかにも様々な質問を試してみました。

question: Who is sitting?
answer: at table

question: What do women have?
answer: answer: fruits and vegetables

question: What are dogs doing?
answer: no dogs

question: Is this woman beautiful?
answer: yes

question: How old is this woman?
answer: young

question: What does a woman have in her right hand?
answer: lemon

question: What kind of impression do you have when you see this photo?
answer: still life

question: What does the woman in this photo think?
answer: hungry

非常に妥当性の高い答えが返ってきています。
画像中に犬がいないことを理解した上で「no dogs」と返答したり、右手と左手を理解した上で「lemon」と返答しています。
この写真を見てどう思う?のような抽象的な質問に対しては、静物画(花、果実など動かないモノを主体的に描いた絵画)であるとそっけない返答をされていますが、概ね間違った回答ではありません。

そのままでも、実務に適用できてしまうのではと思わされるほどの性能です。

まとめ

本記事では、BLIPを使って画像のキャプション生成、VQAを行う方法を紹介しました。
CLIP同様テキストから画像生成など様々な用途に応用されていくことが見込まれます。今後の動向にも注視したい技術です。

また本記事では、機械学習を動かすことにフォーカスしてご紹介しました。
もう少し学術的に体系立てて学びたいという方には以下の書籍などがお勧めです。ぜひご一読下さい。


また動かせるだけから理解して応用できるエンジニアの足掛かりに下記のUdemyなどもお勧めです。

参考文献

1.  論文 - BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation

2. GitHub - salesforce/blip

AIで副業ならココから!

まずは無料会員登録

プロフィール

メーカーで研究開発を行う現役エンジニア
組み込み機器開発や機会学習モデル開発に従事しています

本ブログでは最新AI技術を中心にソースコード付きでご紹介します


Twitter

カテゴリ

このブログを検索

ブログ アーカイブ

TeDokology