
CLIP(Contrastive Language-Image Pre-training)は、画像と文章をそれぞれvectorへ変換し、意味の近さを同じEmbedding空間で比較できるmodelです。画像と対応する文章は近づけ、対応しない組み合わせは離すContrastive Learning(対照学習)によって、この対応関係を学びます。
CLIPが面白いのは、学習済みの固定classだけを出力する画像分類器ではない点です。「犬の写真」「猫の写真」のような候補文を用意すれば、追加のclassifier学習なしで画像との類似度を比較できます。これがzero-shot画像分類の基本です。
ただし、CLIP単体は画像の説明文を生成するmodelでも、物体の位置を囲むdetectorでもありません。何を入力し、どこまで出力できるmodelなのかを、学習時と推論時に分けて理解する必要があります。
3行で分かるCLIP
- Image EncoderとText Encoderは別々のnetworkですが、出力を同じ次元の共有Embedding空間へ写します。
- batch内の正しいimage-text pairのsimilarityを上げ、他の組み合わせを下げる対称的なContrastive Lossで学習します。
- 推論時はclass名を自然文promptへ変換し、そのtext embeddingを比較対象にすることでzero-shot分類できます。
この記事では、CLIP原論文、OpenAI公式解説、公式model cardをもとに、二つのencoder、N×N similarity matrix、zero-shot分類、限界まで順番に説明します。
CLIPは何を変えたのか
従来の教師あり画像分類では、画像ごとにdog、cat、carのようなclass IDを付けます。modelは定義済みclassのどれに当たるかを学びます。精度を評価しやすい一方、class体系を増やすたびにlabel設計とannotationが必要です。
CLIPは、Web上に存在する画像と文章のpairを自然言語教師として使いました。原論文は、インターネットから収集した400 million組のimage-text pairで構成するWebImageText(WIT)を作り、どの文章がどの画像と対応するかを学習しました。
| 観点 | 固定labelの画像分類 | CLIPの自然言語教師 |
|---|---|---|
| 教師 | 人が定義したclass ID | 画像に対応する自然言語text |
| 出力空間 | 学習時に固定したclass | textで指定した候補を比較可能 |
| class追加 | label付きdataと再学習が必要 | 候補promptを追加できる。ただし事前学習で獲得した表現の範囲に依存する |
| 学ぶ情報 | class境界に必要な特徴 | textに現れる物体、属性、動作、場面の対応 |
| 主な弱点 | class設計とannotation cost | Web dataのnoise、bias、prompt依存 |

ここで「自然言語を教師にする」は、文章を一語ずつ正確に生成することではありません。原論文は当初、画像からcaptionを予測する生成目的も検討しましたが、scaling効率が課題でした。そこで「この画像と本当に組になっていた文章はどれか」という比較問題へ変えています。
この変更により、文章の語順や細部を完全に再現する負担を避け、画像と文章の意味的な対応へ計算を集中できます。
CLIPのarchitecture:二つのencoderを共有空間へ接続する
CLIPは大きく四段階で構成されます。
- Image Encoderが画像を画像特徴へ変換する。
- Text Encoderが文章をtext特徴へ変換する。
- それぞれをlinear projectionで同じ次元へ写す。
- L2 normalizationで長さ1のvectorにそろえ、内積でcosine similarityを計算する。

batch sizeを\(N\)、共有Embeddingの次元を\(d\)とします。Image Encoderの出力を\(H_I\)、Text Encoderの出力を\(H_T\)、projection matrixを\(W_I\)と\(W_T\)とすると、共有空間のvectorは次のように書けます。
正規化後は各rowのnormが1なので、内積がcosine similarityになります。
重要なのは、Image EncoderとText Encoderが同じparameterを共有するわけではないことです。画像はpixel配列、textはtoken列なので、入力処理もnetworkも別です。共有するのは最終的な比較座標系です。
原論文ではImage Encoderに改変ResNetまたはVision Transformer、Text EncoderにTransformerを使いました。Text EncoderはBPE token列を処理し、最終層の[EOS]位置の表現をprojectionします。Vision Transformerのpatch処理は次回の記事で詳しく扱います。
Embeddingの基本とcosine similarityを先に確認したい場合は、Embeddingとは?LLMが単語や文章をベクトルで表す仕組みも参照してください。
Contrastive LearningはN×Nの対応問題を解く
4組の正しいpairを例にします。
| index | Image | Text |
|---|---|---|
| 0 | 柴犬の写真 | 「芝生を走る柴犬」 |
| 1 | 赤い自動車 | 「道路に停まる赤い車」 |
| 2 | 海辺の夕景 | 「海に沈む夕日」 |
| 3 | ラーメン | 「丼に入ったラーメン」 |
Image EncoderとText Encoderから4本ずつvectorが出ると、すべての組み合わせを比較した\(4\times4\) matrixを作れます。たとえばcosine similarityが次の値だったとします。
| Image \ Text | 柴犬 | 赤い車 | 海の夕日 | ラーメン |
|---|---|---|---|---|
| 柴犬 | 0.82 | 0.11 | 0.08 | 0.02 |
| 赤い車 | 0.15 | 0.76 | 0.12 | 0.04 |
| 海辺 | 0.07 | 0.10 | 0.88 | 0.05 |
| ラーメン | 0.03 | 0.09 | 0.06 | 0.79 |
正しいpairは対角成分です。学習は対角成分を各row・各columnの最大値へ近づけます。
logit matrixはtemperature \(\tau\)でscaleします。
image-to-text方向では、各画像\(i\)について正しい文章\(i\)を当てます。
text-to-image方向では、各文章\(j\)について正しい画像\(j\)を当てます。
最終lossは二方向の平均です。
一方向だけなら「画像から文章を選ぶ」には強くても、「文章から画像を探す」配置が十分に整うとは限りません。row方向とcolumn方向の両方で分類することで、二つのmodality(情報形式)を相互検索できる空間にします。

Temperatureは順位ではなく確率の鋭さを変える
\(\tau\)はsimilarityをsoftmaxへ入れる前のscaleです。\(\tau\)が小さいほどlogit差が拡大し、確率分布が鋭くなります。
ある画像に対する二つの候補textのcosine similarityを\(0.8\)と\(0.7\)とします。
- \(\tau=1.0\)ならlogitは
0.8, 0.7で、softmaxはおよそ52.5%, 47.5%です。 - \(\tau=0.1\)ならlogitは
8, 7で、およそ73.1%, 26.9%になります。

similarityの順位は同じでも、lossが受け取る誤差とgradientの強さが変わります。原論文ではtemperature相当のlogit scaleを学習対象とし、学習不安定を避けるため上限を設けました。
temperatureはaccuracyを自動的に上げるつまみではありません。小さすぎれば誤った高similarityにも過度に確信し、大きすぎれば候補差を学びにくくなります。
batch内negativeは大量の比較を作る
batchに\(N\)組のpairがあれば、追加でnegativeを収集しなくても、各画像に対する他の\(N-1\)文章をnegative候補として使えます。全体では\(N^2-N\)件です。
原論文が使ったminibatch sizeは32,768です。大きなbatchは一度に多くの候補を比較できますが、memory、分散通信、実効batchの再現が難しくなります。
また、非対応pairが必ず意味的に誤りとは限りません。batch内に犬の写真が2枚あれば、片方の説明文がもう片方にも当てはまる可能性があります。dataset上のpairではないためnegativeとして扱われても、意味としてはfalse negativeです。
したがってContrastive Learningは「すべての概念に唯一の正解文を与える」学習ではありません。収集dataとbatch構成が定めた対応関係を使い、相対的な配置を学びます。
Dense Retrievalのdual encoderもqueryとdocumentを別々にencodeし、vector間の近さで候補を取得します。構造上の共通点はありますが、CLIPはmodalityの異なる画像とtextを対応付ける点が特徴です。詳しくはEmbedding検索とは?Dense Retrievalの仕組みで解説しています。
zero-shot画像分類はtextからclassifierを作る
学習後のCLIPには、画像と文章のsimilarityを比較する能力があります。zero-shot分類では、この能力を次の手順でclassifierとして使います。
- 分類したいclass名を決める。例:
dog、cat、car。 - 各classを
A photo of a {label}.のような自然文へ埋め込む。 - Text Encoderで各promptをtext embeddingへ変換する。
- 入力画像をImage Encoderでimage embeddingへ変換する。
- image embeddingと全text embeddingのcosine similarityを計算する。
- temperature scalingとsoftmaxを適用し、最も高いclassを選ぶ。

class \(k\)のtext embeddingを\(w_k\)、入力画像のembeddingを\(z\)とすると、確率は次のように書けます。
\(w_k\)は人がlabel付き画像から学習した固定weightではなく、Text Encoderがclassの自然言語表現から作ったvectorです。原論文はこの構成を、L2 normalized inputとweight、biasなし、temperature scalingを持つmultinomial logistic regressionとして解釈しています。
「zero-shot」は、CLIPがその概念を学習dataで一度も見ていないと保証する言葉ではありません。対象datasetのlabel付きexampleでclassifierを追加学習せず、自然言語でtaskを指定して評価するという意味です。Web scaleのpre-training dataに類似概念が含まれる可能性は残ります。
なぜclass名だけでなくpromptが必要なのか
boxerという一語には、犬種と競技者の両方の意味があります。craneも鳥と建設機械を指します。class名だけではText Encoderがどの意味を使うべきか判断できません。
そこで文脈を追加します。
| 候補text | 得られる文脈 |
|---|---|
boxer |
犬種か競技者か不明 |
a photo of a boxer dog |
犬種であることを指定 |
a photo of a boxer athlete |
人物・競技であることを指定 |
a satellite photo of farmland |
衛星画像という撮影domainを指定 |

原論文では、class名だけよりA photo of a {label}.を使う方がImageNet top-1 accuracyを1.3 point改善しました。さらにtaskに合わせた複数promptのembeddingを平均するprompt ensemblingを使い、ImageNetでは80種類のcontext promptによりdefault promptから3.5 point改善したと報告しています。
この結果は、promptを長くすれば必ず良くなるという意味ではありません。training dataで画像と共に現れやすかった表現、対象domain、class間で一貫したtemplateかどうかが影響します。
実務では次を分けて評価します。
- labelのみ
- 共通template
- domainを明示したtemplate
- 複数templateのembedding平均
- 日本語promptと英語prompt
特にoriginal CLIPは英語中心のtext dataで学習されています。日本語の自然さだけでpromptを決めず、使うmodelの学習言語と対象dataで確認します。
CLIPでできること・CLIP単体ではしないこと
共有Embeddingを使う代表的な処理は次のとおりです。
| 処理 | Query | Candidate | CLIPの役割 |
|---|---|---|---|
| zero-shot画像分類 | 画像 | class prompt | 最も近いtext候補を選ぶ |
| text-to-image検索 | text | 画像集合 | text vectorに近い画像をrankingする |
| image-to-text検索 | 画像 | caption集合 | 画像vectorに近いtextをrankingする |
| 重複・類似画像探索 | 画像 | 画像集合 | image feature同士を比較する応用が可能 |
| 生成modelの条件付け | text | 生成model内部 | text表現や評価signalとして別modelへ渡す |
一方、CLIP単体の出力は基本的にvectorとsimilarityです。
| Modelの種類 | 主な出力 | CLIPとの違い |
|---|---|---|
| 固定class画像分類器 | 学習済みclassの確率 | CLIPはclass promptを差し替えられる |
| Image Captioning | 自由形式の説明文 | CLIPは文章を自己回帰生成しない |
| Object Detection | box、class、score | CLIP単体は位置を出力しない |
| VLM(Vision-Language Model) | text応答や複数stepの生成 | VLMは視覚特徴を言語生成modelへ接続する |
| Diffusion Model | 画像 | CLIPはnoiseから画像を生成しない |

CLIPを使う画像生成systemがあっても、生成を担当するのはDiffusion Modelなど別のcomponentです。「CLIPが画像を生成する」とまとめると、Embedding modelとgeneratorの責任を混同します。
論文のzero-shot結果をどう読むか
原論文は30を超えるdatasetでzero-shot transferを評価しました。27 datasetの比較では、zero-shot CLIPがResNet-50 featureへ教師ありlinear classifierを学習したbaselineを16 datasetで上回りました。ImageNetでも、原論文が比較対象にしたoriginal ResNet-50に匹敵するzero-shot性能を報告しています。
ただし、平均だけを見ると得意・不得意が消えます。
- Food101やStanford Carsなどでbaselineを大きく上回る条件があった。
- Flowers102やFGVC Aircraftでは10 point以上下回った。
- satellite image、traffic sign、object counting、nearest-car distanceなどでは弱かった。
- zero-shot性能は、多くのdatasetで同じCLIP featureを使った教師ありlinear probeより10〜25 point低かった。
この差は、画像表現の品質と、自然言語だけでtaskを指定する能力が別問題であることを示します。良いEmbeddingを持っていても、class名やpromptがtaskの判定軸を十分に表せなければzero-shot分類は失敗します。
CLIPの限界はどこにあるか
候補外の答えは出せない
zero-shot classifierは、用意したclass promptの中から最も近いものを選びます。すべてが不適切でも必ずどれかを選ぶため、unknown判定、閾値、human reviewを別に設計する必要があります。
細かな数・位置・関係が苦手な場合がある
「犬がいる」のような大まかなsemantic概念と、「犬が3匹いる」「赤い箱が青い箱の左にある」は同じ難しさではありません。原論文もcountingやdistance推定で弱さを報告しました。全体を一つのvectorへ圧縮して近さを測るため、局所的な位置関係を保証する仕組みではありません。
domain shiftとtaxonomyに依存する
自然画像で良くても、医療画像、衛星画像、工場検査、手書き文字へそのまま移せるとは限りません。OpenAIのCLIP model cardは、固定class taxonomyの限定的な画像検索であっても、domain内のtask-specific testingなしに推奨しないとしています。
Web dataのbiasを学ぶ
internet上のimage-text pairは中立な標本ではありません。地域、言語、年齢、性別、文化、撮影対象の偏りがあり、不適切な関連付けも含みます。原論文とmodel cardは、社会的biasやsurveillance用途を含む影響を明示しています。
人に関する属性、危険度、犯罪可能性、雇用適性のような高risk判断へsimilarity scoreを直結してはいけません。accuracyだけでなく、class別・属性別の誤り、拒否動作、異議申立て、人間の確認を含めて評価します。
CLIPを使う前に何を評価するか
CLIP系modelを採用するときは、model名ではなくpipeline全体を確認します。
| 評価軸 | 確認すること | 失敗時の切り分け |
|---|---|---|
| Task | 分類、retrieval、filterのどれか | 出力形式が目的に合うか |
| Taxonomy | classの粒度と重複 | 候補同士が曖昧でないか |
| Prompt | template、language、ensemble | 表現変更でrankが不安定でないか |
| Domain | 撮影条件、地域、専門分野 | pre-training分布から離れていないか |
| Threshold | unknown、abstain条件 | 全候補が不適切でも強制分類していないか |
| Bias | 属性別のerror | 特定groupへ誤りが集中しないか |
| Operations | latency、cache、model version | image/text encoderやindex versionが一致するか |

text候補は事前にencodeしてcacheできます。検索用途ではimage embeddingも事前計算できます。ただしencoderやpreprocessingを更新したら、古いvectorと新しいvectorの互換性を評価し、必要なら再計算します。
まとめ
CLIPは、画像とtextを別々のencoderで処理し、同じ次元の正規化vectorへ写してsimilarityを比較するmodelです。batch内のN×N pairを使う対称Contrastive Lossにより、image-to-textとtext-to-imageの両方向を同時に整えます。
zero-shot画像分類では、class名を自然文promptへ変え、Text Encoderが作ったvectorをclassifier weightとして使います。そのため候補classをtextで変更できますが、未知概念を無条件に理解するわけではありません。prompt、taxonomy、domain、data biasによって結果は変わります。
次回は、CLIPのImage Encoderにも使われたVision Transformerを取り上げ、画像をpatch列へ変えてTransformerへ入力する仕組みを説明します。



コメント