CLIP モデルの理解と画像検索への応用
CLIP とは - テキストと画像を結ぶマルチモーダル AI
CLIP (Contrastive Language-Image Pre-training) は OpenAI が 2021 年に発表したマルチモーダルモデルで、テキストと画像を同一のベクトル空間に埋め込むことで、両者の意味的な関連性を計算可能にします。インターネットから収集した 4 億組のテキスト-画像ペアで訓練され、従来の ImageNet 事前学習モデルを大幅に上回る汎化性能を示しました。特筆すべきは、特定のタスクに特化した訓練を行わずとも、多様な視覚認識タスクで高い性能を発揮する点です。
従来手法との違い:
従来の画像分類モデルは固定されたクラスラベル (例: ImageNet の 1000 クラス) に対して訓練されるため、新しいカテゴリへの対応にはファインチューニングが必要でした。CLIP は自然言語でクラスを記述できるため、追加訓練なしで任意のカテゴリを認識するゼロショット分類が可能です。これにより、ラベル付きデータセットの準備コストを大幅に削減できます。
応用範囲:
- ゼロショット画像分類: 任意のテキストラベルで画像を分類
- 画像検索: テキストクエリで画像データベースを意味的に検索
- 画像生成の条件付け: Stable Diffusion のテキストエンコーダとして使用
- コンテンツモデレーション: 不適切画像の自動検出とフィルタリング
- マルチモーダル RAG: 画像とテキストを統合した検索拡張生成
コントラスト学習の仕組み - 対照損失による埋め込み学習
CLIP の訓練はコントラスト学習 (Contrastive Learning) に基づきます。バッチ内の N 組のテキスト-画像ペアに対し、正しいペアの類似度を最大化し、不正なペアの類似度を最小化する対照損失を使用します。バッチサイズ 32,768 という大規模バッチで訓練され、多様なネガティブサンプルにより高品質な埋め込み空間を学習します。この手法は SimCLR や MoCo などの自己教師あり学習の発展形です。
損失関数の詳細:
N 個の画像埋め込み I1...IN と N 個のテキスト埋め込み T1...TN に対し、コサイン類似度行列 S(i,j) = Ii ・ Tj / (||Ii|| * ||Tj||) を計算します。対角要素 (正しいペア) の類似度を最大化し、非対角要素 (不正ペア) を最小化する InfoNCE 損失を画像→テキスト方向とテキスト→画像方向の両方で計算し、平均を取ります。温度パラメータ τ (学習可能、初期値 0.07) でスケーリングし、ソフトマックスの鋭さを制御します。
大規模バッチの重要性:
バッチサイズ 32,768 は N^2 - N = 約 10 億のネガティブペアを 1 バッチで生成します。この大量のネガティブサンプルが、細かい意味の違いを区別できる高品質な埋め込み空間の学習に不可欠です。小さいバッチでは類似概念の区別が困難になり、「犬」と「猫」は区別できても「ゴールデンレトリバー」と「ラブラドール」の区別が曖昧になります。
モデルアーキテクチャ - 画像エンコーダとテキストエンコーダ
CLIP は画像エンコーダとテキストエンコーダの 2 つの独立したネットワークで構成されます。それぞれが入力を固定長のベクトル (512 次元または 768 次元) に変換し、同一の埋め込み空間に射影します。
画像エンコーダ:
ResNet-50 または Vision Transformer (ViT) が使用されます。ViT-B/32 は 32x32 パッチに分割して処理し、ViT-L/14 は 14x14 パッチでより高精度な特徴抽出を行います。ViT-L/14@336px が最高精度で、336 × 336の入力解像度で 768 次元の埋め込みを出力します。画像は 224 × 224(または 336 × 336) にリサイズされ、パッチ分割後に Transformer エンコーダで処理されます。
テキストエンコーダ:
GPT-2 ベースの Transformer (12 層、512 次元、8 ヘッド) を使用します。最大 77 トークンのテキストを処理し、[EOS] トークンの出力を最終的なテキスト埋め込みとして使用します。BPE (Byte Pair Encoding) トークナイザで 49,152 語彙のサブワード分割を行います。
射影層:
各エンコーダの出力は線形射影層を通じて共通の埋め込み空間 (512 次元) にマッピングされます。この射影により、異なるモダリティの表現が直接比較可能になります。
ゼロショット分類の実装 - プロンプトエンジニアリング
CLIP のゼロショット分類は、クラスラベルをテキストプロンプトに変換し、画像との類似度を計算することで実現します。プロンプトの設計が分類精度に大きく影響するため、適切なプロンプトエンジニアリングが重要です。
基本的な分類手順:
分類したいクラス名 (例: "cat", "dog", "bird") をテキストテンプレート "a photo of a {class}" に埋め込み、各クラスのテキスト埋め込みを事前計算します。入力画像の埋め込みと各クラスのテキスト埋め込みのコサイン類似度を計算し、最も類似度の高いクラスを予測結果とします。
プロンプトエンジニアリング:
単純なクラス名よりもテンプレートを使用した方が精度が向上します。OpenAI は 80 種類のテンプレート ("a photo of a {}", "a drawing of a {}", "a close-up of a {}" など) のアンサンブルを推奨しています。ImageNet では単一テンプレートの 68.3% から 80 テンプレートアンサンブルで 75.5% に精度が向上します。
Python 実装例:
import torch, clip; model, preprocess = clip.load("ViT-B/32") でモデルをロードし、clip.tokenize(["a photo of a cat", "a photo of a dog"]) でテキストをトークン化します。画像とテキストの埋め込みを計算し、torch.cosine_similarity で類似度を算出します。
画像検索システムの構築 - ベクトルデータベースとの連携
CLIP の埋め込みを活用した画像検索システムは、テキストクエリで大規模画像データベースを意味的に検索できます。従来のタグベース検索と異なり、画像にメタデータを付与する必要がなく、自然言語で直感的に検索可能です。
システム構成:
画像データベースの全画像を事前に CLIP 画像エンコーダで埋め込みベクトルに変換し、ベクトルデータベース (Faiss、Milvus、Pinecone など) に格納します。検索時はテキストクエリを CLIP テキストエンコーダで埋め込み、最近傍探索 (ANN) で類似画像を取得します。100 万枚規模でも数ミリ秒で検索可能です。
Faiss によるインデックス構築:
Facebook AI の Faiss ライブラリは高速な近似最近傍探索を提供します。IVF (Inverted File Index) + PQ (Product Quantization) の組み合わせで、メモリ効率と検索速度を両立します。512 次元ベクトル 100 万件を約 500MB のインデックスに圧縮し、top-10 検索を 1ms 以下で実行できます。
ハイブリッド検索:
テキスト→画像検索に加え、画像→画像検索 (類似画像検索) も同じインフラで実現できます。クエリ画像の埋め込みで検索するだけで、視覚的に類似した画像を取得できます。テキストと画像のクエリを組み合わせたハイブリッド検索も可能です。
CLIP の発展と限界 - OpenCLIP, SigLIP, 実用上の注意点
CLIP の成功以降、多数の改良版や派生モデルが登場しています。実用上の限界を理解し、適切なモデル選択と対策を行うことが重要です。
OpenCLIP:
LAION が公開したオープンソース実装で、LAION-5B (50 億ペア) で訓練されたモデルを提供します。ViT-G/14 は元の CLIP を上回る性能を達成し、商用利用も可能です。Hugging Face の transformers ライブラリから簡単に利用できます。
SigLIP (Sigmoid Loss for Language-Image Pre-training):
Google が提案した改良版で、ソフトマックスベースの InfoNCE 損失をシグモイド損失に置き換えます。バッチ内の全ペアを独立に二値分類として扱うため、大規模バッチへの依存が軽減されます。同じ計算量でより高い精度を達成し、特に小規模データセットでの性能が向上します。
実用上の限界:
- 空間的理解の弱さ: 「左にある猫」と「右にある猫」の区別が困難
- 数量の認識: 「3 匹の犬」と「5 匹の犬」の正確な区別が苦手
- 否定の理解: 「猫がいない画像」のような否定表現の処理が不正確
- テキスト読み取り: 画像内のテキスト (OCR) は得意ではない
これらの限界を補うため、BLIP-2 や LLaVA などの Vision-Language Model が登場し、より高度な画像理解を実現しています。