10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

画像認識 AI モデルを試してみた

Last updated at Posted at 2024-07-05

はじめに

以前に、Transformers 、Gemma 、Diffusers などを使って、生成 AI プログラミングを試してみました。

生成 AI プログラムを試してみた #AI - Qiita

文章の入力に対して文章や画像を生成して出力できました。

これに対して、OpenAI の ChatGPT や Google の Gemini などのサービスでは、画像を入力して文章を出力することができます。

生成 AI プログラムは、モデルを参照して入力内容から出力内容を生成します。モデルは、どんな入力内容に対して、どんな出力内容を生成するか、学習させたものです。

説明1.png

上記のサービスで利用している AI モデルは、画像の入力と文章の出力を学習させているのですね。

同様のモデルを使えば、自分でも画像から文章を生成するプログラムが書けるはずです。

画像認識 AI モデルを試してみる

画像を認識する AI プログラムを試してみます。

以下の記事を参考にしました。

実行環境を用意する

以前と同様に Google Colab を使ってみます。別の環境でも構いません。

参考:生成 AI プログラムを試してみた #LLM - Qiita

以下のコード例は、Google Colab あるいは Jupyter Notebook で実行するものです。

ライブラリをインストールする

Transformers ライブラリを使うのでインストールします。

! pip install transformers accelerate

モデルを用意する

モデルはリポジトリサービスから入手します。以前と同様に Hugging Face を使用します。

参考:生成 AI プログラムを試してみた #LLM - Qiita

LLaVA 、PaliGemma を使ってみる

画像を入力して文章を生成できるモデルに、LLaVA があります。画像のエンコーダと LLM の LLaMA を合わせたモデルとのことです。
これを使ってみます。

参考:画像分析機能を持つオープンソースLLM『LLaVA-1.5』登場 | AIDB

LLaVA だけでなく別のモデル PaliGemma も使えそうです。Google の PaLI から着想して、画像のエンコーダと LLM の Gemma を合わせたモデルとのことです。

参考:Googleがオープンソースのビジュアル言語モデル「PaliGemma」を公開 - GIGAZINE

画像データを準備する

Hugging Face でチュートリアルのために用意された画像データを使ってみます。

これを参照して画像オブジェクトにします。↓

import requests
import PIL

# 画像を参照
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/ai2d-demo.jpg"
image = PIL.Image.open(requests.get(url, stream=True).raw)

モデルとプロセッサで処理する

モデルをダウンロードしてプロセッサを準備します。

import transformers
import torch

# モデルとプロセッサの準備
model = transformers.LlavaForConditionalGeneration.from_pretrained(
    "llava-hf/llava-1.5-7b-hf",
    device_map="auto",
    torch_dtype=torch.float16, low_cpu_mem_usage=True,
)
processor = transformers.AutoProcessor.from_pretrained(
    "llava-hf/llava-1.5-7b-hf",
)

画像データとプロンプトを入力内容にして推論させて結果を作成させます。

prompt = "これは何の画像ですか。"

# プロセッサとモデルで推論
inputs = processor(
    "USER: <image>\n" + prompt + "\nASSISTANT:\n",
    image,
    return_tensors="pt"
).to(model.device)

outputs = model.generate(
    **inputs,
    max_new_tokens=200, 
    do_sample=False
)

作成された結果を出力します。

output = processor.decode(
    outputs[0][1:], 
    skip_special_tokens=True
)
print(output)

結果の例です。↓

この画像は、地質学的な地図であり、地層や地下水の流れなどの情報が表示されています。地図には、地下水の流れや地層の層序、地下の洞窟、地下の溶岩などが含まれており、地質学的な知識を持つ人々にとって有益な情報源となっています。

パイプラインで処理する

上記と同じことをパイプラインで処理してみます。

# パイプラインの準備
pipe = transformers.pipeline(
    "image-to-text",
    model="llava-hf/llava-1.5-7b-hf"
)

prompt = "これは何の画像ですか。"

# パイプラインで推論
outputs = pipe(
    image,
    prompt="USER: <image>\n" + prompt + "\nASSISTANT:\n",
    generate_kwargs={"max_new_tokens": 200}
)

作成された結果を出力します。

print(outputs[0]["generated_text"])

結果の例です。↓

この画像は、地質学的な地図であり、地層や地下水の流れなどの情報が表示されています。地図には、地下水の流れや地層の層序、地下の洞窟、地下の溶岩などが含まれており、地質学的な知識を持つ人々にとって有益な情報源となっています。

モデルを替えてみる

モデルを LLaVa から PaliGemma に替えてみます。

# モデルとプロセッサの準備
model = transformers.PaliGemmaForConditionalGeneration.from_pretrained(
    "google/paligemma-3b-mix-224",
    device_map="auto",
    torch_dtype=torch.float16, low_cpu_mem_usage=True,
)
processor = transformers.AutoProcessor.from_pretrained(
    "google/paligemma-3b-mix-224",
)

あるいは

# パイプラインの準備
pipe = transformers.pipeline(
    "image-to-text",
    model="google/paligemma-3b-mix-224"
)

推論させて結果を出力するプログラムは同じです。出力すると↓

火山 の さまざま な 部分 の 図 。

実行環境を変更してみる

Google Colab は実行環境の GPU/TPU を選択できます。現在は以下のタイプが選択できました。それぞれスペックを確認しました。

CPU TPU v2 T4 GPU L4 GPU A100 GPU
システム RAM 13GB 334GB 13GB 53GB 84GB
GPU RAM なし なし 15GB 22GB 40GB
ディスク 108GB 225GB 78GB 78GB 78GB
ユニット使用率 約0.07/時 約1.76 約1.76 約4.82 約11.77

前述のプログラムをそれぞれの環境で実行するとどうなるでしょうか。

CPU TPU v2 T4 GPU L4 GPU A100 GPU
モデルとプロセッサで処理 終了しない クラッシュした
パイプラインで処理 クラッシュ クラッシュ

モデル LLaVaPaliGemma どちらも同じでした。別のサイズの大きいモデルを使うと結果が違うかも知れません。
モデルとプロセッサで処理したときとパイプラインで処理したときで結果が違うのは、前者が torch_dtype=torch.float16, low_cpu_mem_usage=True のような指定していて後者は指定がないからでしょうか。

UniDiffusers を使ってみる

文章を入力して画像を生成して出力するのに、以前に Stable Diffusion のモデルと Diffusers ライブラリを使いました。
このライブラリに含まれる UniDiffusers を使うと、文章から画像を生成するだけでなく、画像から文章を生成できるようです。

diffusers v0.17.0 の UniDiffuser を使ってみる - ジャコ Lab

ライブラリをインストールする

Transformers に加えて、Diffusers ライブラリを使うのでインストールします。

! pip install diffusers

画像データを準備する

Hugging Face でチュートリアルのために用意された画像データを使ってみます。

これを参照して画像オブジェクトにします。↓

# 画像を参照
url = "https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/unidiffuser/unidiffuser_example_image.jpg"
image = diffusers.utils.load_image(url).resize((512, 512))

パイプラインで処理する

パイプラインを準備して処理します。

import diffusers
import torch

# パイプラインの準備
pipe = diffusers.UniDiffuserPipeline.from_pretrained(
    "thu-ml/unidiffuser-v1",
    torch_dtype=torch.float16, low_cpu_mem_usage=True
).to("cuda")

# パイプラインで推論
output = pipe(
    image=image,
    # prompt="この画像は何ですか。",
    num_inference_steps=20, guidance_scale=7.5
)

このパイプラインは文章のプロンプトは受付けないようです。↑

# 結果を出力
print(output.text[0])

結果の例です。↓

An image of an astronaut flying in space over the earth
10
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?