VerifiedarXiv:2103.0002030 min
Multimodal · Representation learning

CLIP: Learning Transferable Visual Models From Natural Language Supervision

Train on 400 million web images and their captions, and any list of class names becomes an image classifier.

OpenAI trained an image encoder and a text encoder to pick out which caption in a batch belongs to which image. At test time the text encoder turns class names into classifier weights, and with no ImageNet training images the result matches a supervised ResNet-50 on ImageNet.

Explaining the paperLearning Transferable Visual Models From Natural Language SupervisionRadford, Kim, Hallacy, Ramesh, Goh, Agarwal, Sastry, Askell, Mishkin, Clark, Krueger, Sutskever · OpenAI · ICML 2021 · arXiv:2103.00020 ↗

A supervised ResNet-101 and zero-shot CLIP both score 76.2% on ImageNet. On ImageNet Sketch, drawings of the same 1,000 classes, the ResNet-101 scores 25.2% and CLIP scores 60.2%.

CLIP (Contrastive Language-Image Pre-training) is a pair of networks trained together. An image encoder maps a picture to a vector, a text encoder maps a sentence to a vector of the same length, and training makes the two vectors point the same way when the sentence is the picture's caption. The training data is 400 million (image, caption) pairs collected from the web, with no human labeling.

After training, CLIP classifies images into categories it was never trained on. You write each category as a short sentence ("A photo of a golden retriever."), embed the sentences once, embed the image, and pick the sentence whose vector is closest. On ImageNet this zero-shot classifier reaches 76.2% top-1 accuracy (the true class scores highest on 76.2% of test images), the accuracy of the original ResNet-50, which was trained on ImageNet's 1.28 million labeled images; CLIP uses none of them. The paper benchmarks this zero-shot transfer on over 30 existing computer-vision datasets.

The page goes in this order: why fixed label sets were the bottleneck, which training task the authors picked and why, the shared embedding space, the contrastive loss with a worked 6-pair example, the learned temperature, the full-size training step with shapes, zero-shot classification and prompts, the robustness results, and the limitations.

Why fixed label sets limit image classifiers

A standard image classifier is trained on a fixed list of categories, such as ImageNet's 1,000. Each training image carries an integer, and the network's last layer has one output per integer. The integer carries no meaning inside the model: class 207 is "golden retriever" only in a lookup file outside it. The loss treats a golden retriever labeled as class 208 (Labrador retriever) exactly as wrong as one labeled as a toaster, and the model cannot output a category that was not in the list. To add "satellite photo of farmland", someone collects and labels examples and the model is retrained.

"A maltese puppy sitting in a teacup" names a breed, an age, an object and a pose, and the same words appear in millions of other captions, so a model reading them can relate this image to every other image described with "puppy" or "teacup". People also write captions without being paid to. CLIP tests whether that noisier signal, collected at a scale no labeling project can reach, trains a better visual model than clean labels.

Earlier image-text work had used MS-COCO and Visual Genome (about 100,000 photos each) or YFCC100M, which shrinks to 15 million photos once images without natural-language titles or descriptions are removed. The authors built a new dataset instead. They searched the web for (image, text) pairs whose text contains one of 500,000 queries (every word that occurs at least 100 times in English Wikipedia, plus high-mutual-information bigrams, the titles of Wikipedia articles above a search-volume threshold, and WordNet synsets), kept up to 20,000 pairs per query, and ended with 400 million pairs. They call it WIT, for WebImageText. Its total word count is similar to WebText, the corpus GPT-2 was trained on.

Choosing the training task

Given pairs, the obvious objective is captioning: feed the image to a network and train it to generate the caption one word at a time. The authors started there, with an image CNN and a text transformer trained from scratch, and measured how quickly each objective learns zero-shot ImageNet classification per image processed (the paper's Figure 2). Three objectives, same data:

So the contrastive objective reaches a given zero-shot accuracy with about 12 times fewer images than word-by-word captioning. Both predictive objectives try to reproduce the exact words that came with an image, and web text around an image varies widely: a photo of a dog might be captioned with the dog's name, a joke, or the camera settings. Picking the right caption out of a batch only requires the image and text embeddings to carry enough information to tell this caption from the others in the batch. The authors cite earlier results that pointed the same way: contrastive objectives learned better image representations than their predictive equivalents, and generative image models needed over an order of magnitude more compute for the same quality.

Two encoders, one embedding space

CLIP has two networks, trained from scratch (no ImageNet initialization, no pre-trained language model):

Each encoder's output goes through one learned linear projection into a shared space of dimension ded_e (512 for ViT-B/32, 768 for ViT-L/14). The authors dropped the nonlinear projection head that image-only contrastive methods such as SimCLR used, because they saw no difference in training efficiency.

The text encoder uses causal (masked) self-attention, the kind a language model uses, where each token attends only to itself and the tokens before it. Under that mask only the last token, the end-of-text token [EOS], has seen the whole caption, and CLIP takes the caption's feature from that token's top-layer activation, layer-normalized and then projected. The authors kept the mask so that a pre-trained language model could initialize the encoder later, or language modeling could be added as a second objective; the paper leaves both to future work.

Both projected vectors are then divided by their length (L2L_2-normalized), which places every embedding on the unit sphere. For unit vectors the dot product equals the cosine of the angle between them, so the comparison between image ii and caption jj is

Sij=Ii⊤Tj∥Ii∥ ∥Tj∥=I^i⋅T^j=cos⁡θij∈[−1,1]S_{ij} = \frac{\mathbf{I}_i^{\top}\mathbf{T}_j}{\lVert \mathbf{I}_i\rVert\,\lVert \mathbf{T}_j\rVert} = \hat{\mathbf{I}}_i\cdot\hat{\mathbf{T}}_j = \cos\theta_{ij} \in [-1, 1]
(1)

where I^i\hat{\mathbf{I}}_i and T^j\hat{\mathbf{T}}_j are the normalized embeddings. A value near 1 means the vectors point the same way, near 0 that they are unrelated, and negative that they point apart. Normalizing removes length from the comparison, so a caption cannot score well against every image by having a long vector. Training should rotate each image vector toward its own caption's vector and away from the others.

In the figure, images (amber) and captions (teal) sit on a circle, a 2D stand-in for the 512-dimensional sphere. Pick an image and read the spokes: each spoke's brightness is the cosine to one caption, and the brightest one goes to the image's own caption.

Figure 1 · one shared space
Each image and each caption is a unit vector in the same space. Pick an image with the buttons; its spokes glow by cosine similarity to each caption, and its true caption points almost the same way (cosine near 1).

How the CLIP contrastive loss works

Take a batch of NN pairs. Embed and normalize all NN images and all NN captions, then compute (1) for every image against every caption to fill an N×NN \times N grid SS. The NN diagonal cells SiiS_{ii} are the pairs that occurred together on the web. The other N2−NN^2 - N cells pair an image with some other image's caption. Those are the negatives, and nobody had to label them: any caption from elsewhere in the batch is a wrong answer for image ii. Each image gets one positive and N−1N - 1 negatives per step.

The loss treats each row as a classification problem. Row ii holds image ii's scores against the NN captions, and the correct class is caption ii. A softmax turns the row into probabilities (exponentiate each score, divide by the row's sum), and cross-entropy charges −log⁡-\log of the probability on the correct caption. The columns get the same treatment: column jj holds caption jj's scores against all images, and the correct class is image jj. The loss averages the two directions:

L=12(Limg→txt+Ltxt→img),Limg→txt=−1N∑i=1Nlog⁡eSii/τ∑j=1NeSij/τ,Ltxt→img=−1N∑j=1Nlog⁡eSjj/τ∑i=1NeSij/τ\mathcal{L} = \tfrac{1}{2}\big(\mathcal{L}_{\text{img}\to\text{txt}} + \mathcal{L}_{\text{txt}\to\text{img}}\big), \quad \mathcal{L}_{\text{img}\to\text{txt}} = -\frac{1}{N}\sum_{i=1}^{N} \log \frac{e^{S_{ii}/\tau}}{\sum_{j=1}^{N} e^{S_{ij}/\tau}}, \quad \mathcal{L}_{\text{txt}\to\text{img}} = -\frac{1}{N}\sum_{j=1}^{N} \log \frac{e^{S_{jj}/\tau}}{\sum_{i=1}^{N} e^{S_{ij}/\tau}}L=12(Limg→txt+Ltxt→img),Limg→txt=−1N∑i=1Nlog⁡eSii/τ∑j=1NeSij/τ,Ltxt→img=−1N∑j=1Nlog⁡eSjj/τ∑i=1NeSij/τ\begin{gathered} \mathcal{L} = \tfrac{1}{2}\big(\mathcal{L}_{\text{img}\to\text{txt}} + \mathcal{L}_{\text{txt}\to\text{img}}\big), \\ \mathcal{L}_{\text{img}\to\text{txt}} = -\frac{1}{N}\sum_{i=1}^{N} \log \frac{e^{S_{ii}/\tau}}{\sum_{j=1}^{N} e^{S_{ij}/\tau}}, \\ \mathcal{L}_{\text{txt}\to\text{img}} = -\frac{1}{N}\sum_{j=1}^{N} \log \frac{e^{S_{jj}/\tau}}{\sum_{i=1}^{N} e^{S_{ij}/\tau}} \end{gathered}
(2)

τ\tau is a temperature that divides every score before the softmax; the next section covers it. For now use CLIP's starting value, τ=0.07\tau = 0.07, so every cosine is multiplied by 1/0.07≈14.31/0.07 \approx 14.3. The paper does not number this equation; (2) is its Figure 3 pseudocode written out. The row term trains image-to-text matching, the direction zero-shot classification uses; the column term trains text-to-image matching, the direction a text search over images uses. Both read the same grid, so the second direction costs one more softmax and no extra encoder work.

A worked example with six pairs

Take a batch of six pairs: photos of a dog, a cat, a beach, a bike, a pizza and a guitar, each with its own caption. Early in training the cosines are small and nearly flat. The dog image's row, against the six captions in that order, might be

Sdog,⋅=[ 0.16, 0.12, 0.02, 0.05, 0.03, 0.04 ]S_{\text{dog},\cdot} = [\,0.16,\ 0.12,\ 0.02,\ 0.05,\ 0.03,\ 0.04\,]

Multiplied by 14.3 these become the logits, the scores that go into the softmax, [2.29,1.71,0.29,0.71,0.43,0.57][2.29, 1.71, 0.29, 0.71, 0.43, 0.57], and the softmax gives probabilities 0.446 on the dog caption and 0.252 on the cat caption, with the rest between 0.060 and 0.093. The row contributes −log⁡0.446=0.807-\log 0.446 = 0.807 to the image-to-text loss. For comparison, if all six cosines were equal the softmax would be uniform and every row would cost ln⁡6=1.792\ln 6 = 1.792, the loss of guessing. Averaged over all six rows and all six columns, this early batch has L=0.890\mathcal{L} = 0.890.

The gradient shows where training pushes. For softmax followed by cross-entropy, the derivative of the row's loss with respect to logit jj is pj−yjp_j - y_j, the predicted probability minus the target (1 on the diagonal, 0 elsewhere). For the dog row that is −0.554-0.554 on the dog caption, which gradient descent raises, and +0.252+0.252 on the cat caption, the largest push down among the negatives, then +0.093+0.093 on the bike caption and less on the rest. Each negative is pushed down in proportion to the probability it currently takes, so the captions most easily confused with the right one (cat, for a dog photo) get the most correction. Through (1), those logit gradients become gradients on the two embedding vectors and flow back into both encoders.

After training the same row might read [0.90,0.55,0.08,0.20,0.10,0.12][0.90, 0.55, 0.08, 0.20, 0.10, 0.12]. The logits are [12.86,7.86,1.14,2.86,1.43,1.71][12.86, 7.86, 1.14, 2.86, 1.43, 1.71], the dog caption gets probability 0.993, and the row costs 0.0068. The cat caption still has the highest cosine among the negatives, 0.55, but a gap of 0.35 in cosine is 5 in logits and a factor of e5≈148e^5 \approx 148 in probability. The whole trained batch has L=0.0020\mathcal{L} = 0.0020.

The figure holds both grids. Switch between the four views to see the raw cosines, the row softmax, the column softmax, and the gradient; switch the stage to compare early and trained.

Figure 2 · the contrastive grid
Six images (rows) against their six captions (columns). The amber-ringed diagonal holds the real pairs. The header shows both directional losses of (2) at scale 14.3 and the chance value ln 6. Click a cell, or focus the grid and use the arrow keys, to read out one row (one column in the column view). In the gradient view the dog row shows the cat caption taking the largest push down.

The objective is older than CLIP. It is the multi-class NN-pair loss from metric learning (Sohn, 2016), popularized for representation learning as InfoNCE (Oord et al., 2018), and applied to medical images paired with radiology reports by ConVIRT (Zhang et al., 2020). CLIP simplifies ConVIRT's recipe: training from scratch, a linear projection instead of a nonlinear one, no sampling of single sentences from the text, and a random square crop of the resized image as the only data augmentation. The authors write that with 400 million pairs, over-fitting is not a major concern.

The learned temperature

Dividing every cosine by τ\tau before the softmax is the same as multiplying by a scale 1/τ1/\tau. The code stores the log of that scale as one learned parameter, t in the paper's pseudocode and logit_scale in model.py:

logitsij=et I^i⋅T^j,et=1τ,t=log⁡1τ\text{logits}_{ij} = e^{t}\,\hat{\mathbf{I}}_i\cdot\hat{\mathbf{T}}_j, \qquad e^{t} = \frac{1}{\tau}, \qquad t = \log\frac{1}{\tau}
(3)

Storing the log keeps the scale positive whatever value gradient descent gives tt. The initial value is t=log⁡(1/0.07)≈2.66t = \log(1/0.07) \approx 2.66, a scale of about 14.3, a setting the authors took from Wu et al. (2018). The paper clips tt so the scale never exceeds 100, which means τ≥0.01\tau \ge 0.01, and says the clip was necessary to prevent training instability. A small τ\tau spreads the logits apart, so the softmax concentrates on the top score. A large τ\tau squeezes them together, so the softmax approaches uniform.

A scale is needed at all because of (1). Cosines are bounded, so with scale 1 the logits of a row span at most 2 units. Suppose the correct caption sits at cosine 1 and all 32,767 other captions of a full batch sit at cosine 0. With scale 1, the correct caption's probability is e1/(e1+32,767 e0)≈8.3×10−5e^{1}/(e^{1} + 32{,}767\,e^{0}) \approx 8.3 \times 10^{-5} and the row costs 9.40, barely below the chance value ln⁡32,768=10.40\ln 32{,}768 = 10.40. With scale 14.3 the same geometry gives probability 0.980 and a loss of 0.020.

Figure 3 shows one image's softmax over five captions as you drag τ\tau. Switch the batch to 32,768 captions to add the 32,763 other captions of a full batch, each at an illustrative cosine of 0.05, as one lumped bar. At the initial τ=0.07\tau = 0.07 the dog caption gets 0.663 among five captions but only 0.00125 among 32,768; it needs τ\tau near the floor of 0.01 to take 0.998.

Figure 3 · temperature and batch size
τ = 0.070
One image's softmax over its captions as τ varies. The slider stops at τ = 0.01, where CLIP's clamp holds the scale at 100. The batch buttons switch between 5 captions and a full batch, where 32,763 unrelated captions share the violet bar.

Figure 4 trains tt along with the embeddings on a toy: six pairs, each embedding a free angle on a circle instead of an encoder output, trained with Adam on (2). Press Play and compare the three temperature settings. With τ=1\tau = 1 fixed, the pairs line up and spread evenly around the circle, yet the loss stops at 1.03; even perfect alignment cannot push a softmax far from uniform when the logits span only 2 units. With the scale fixed at 14.3 the loss falls to about 0.003. With tt learned, the scale first drops, because a sharp softmax over misaligned pairs puts high probability on wrong captions and the gradient lowers it; once the pairs line up, raising the scale lowers the loss further with no limit, so the scale climbs until the clamp at 100 stops it, and the loss stops falling at the same step.

Figure 4 · contrastive training in miniature
step 0
Six pairs trained on a circle: filled dots are images, rings are captions, same color is a true pair. Play or scrub through 600 Adam steps; the charts show the loss (log scale) and the scale et for all three settings, the selected one bright. New random start draws new initial angles; in 2D a start can occasionally leave two pairs stuck in a local minimum.

One training step at full size

Now the real sizes, for a ViT-B/32 CLIP (the base-size Vision Transformer with 32 x 32-pixel patches, so a 224 x 224 image becomes a 7 x 7 grid of 49 patches) with de=512d_e = 512 and the paper's batch of N=32,768N = 32{,}768 pairs:

  1. Encode. The ViT maps 32,768 images to features, and the text Transformer maps 32,768 captions of up to 76 tokens to the activation at each caption's [EOS].
  2. Project and normalize. Two linear maps give I,T∈R32768×512\mathbf{I}, \mathbf{T} \in \mathbb{R}^{32768 \times 512}, and every one of the 65,536 rows is scaled to unit length.
  3. Score. S=I^T^⊤S = \hat{\mathbf{I}}\hat{\mathbf{T}}^{\top} has 32,7682≈1.07×10932{,}768^2 \approx 1.07 \times 10^{9} cells: 32,768 correct pairs on the diagonal and 1,073,709,056 wrong ones off it. Multiply by ete^{t}.
  4. Loss. The labels are [0,1,…,32767][0, 1, \dots, 32767]. Cross-entropy along the rows, cross-entropy down the columns, average. At initialization, when every cosine is close to 0, the loss is close to ln⁡32,768=10.40\ln 32{,}768 = 10.40.
  5. Backward. The gradient reaches both encoders, both projections and tt.

In the paper's notation the forward pass and loss are these lines:

# CLIP core, from the paper's Figure 3 (numpy-like)
I_f = image_encoder(I)            # [n, d_i]   images in a batch
T_f = text_encoder(T)             # [n, d_t]   their captions

# project into the shared space, then L2-normalize to unit length
I_e = l2_normalize(I_f @ W_i, axis=1)   # [n, d_e]
T_e = l2_normalize(T_f @ W_t, axis=1)   # [n, d_e]

# every image against every caption: an n x n grid of scaled cosines
logits = (I_e @ T_e.T) * np.exp(t)      # t = log(1/tau), learned

# the right answer for row i (and for column i) is i: the diagonal
labels = np.arange(n)
loss_i = cross_entropy(logits, labels, axis=0)   # caption -> image
loss_t = cross_entropy(logits, labels, axis=1)   # image -> caption
loss   = (loss_i + loss_t) / 2

In loss_i the softmax runs over axis=0, down each column, so it is the caption-to-image term; loss_t runs along rows and is image-to-caption. The grid alone is large. In 32-bit floats it takes about 4.3 GB, so no single GPU builds it: the paper shards the similarity computation, with each GPU computing only the pairwise similarities its local batch of embeddings needs. If the batch were split evenly over 256 GPUs, a GPU would hold 128 images and 128 captions and compute their 128 rows and 128 columns of the grid against the full batch.

The authors trained eight CLIP models: five ResNets (RN50, RN101, and RN50x4, RN50x16, RN50x64, scaled EfficientNet-style to about 4, 16 and 64 times the compute of RN50) and three ViTs (ViT-B/32, ViT-B/16, ViT-L/14). All ran 32 epochs over the 400 million pairs, about 12.8 billion pairs seen, which at 32,768 per batch is 390,625 steps. Training used Adam with decoupled weight decay on all weights that are not gains or biases, a cosine learning-rate schedule, mixed precision, gradient checkpointing, half-precision Adam statistics, and half-precision stochastically rounded text-encoder weights. RN50x64 took 18 days on 592 V100 GPUs; ViT-L/14 took 12 days on 256 V100s, then one more epoch at 336-pixel resolution produced ViT-L/14@336px, the best model and the one the paper means by "CLIP" unless it says otherwise.

Zero-shot classification: the text encoder writes the classifier

A trained CLIP scores how well any image matches any text. To classify ImageNet with it, write each of the 1,000 class names into a sentence, "A photo of a {label}.", and run the 1,000 sentences through the frozen text encoder. The 1,000 normalized outputs form a matrix W∈R1000×deW \in \mathbb{R}^{1000 \times d_e}. Embed the test image once to get x^\hat{\mathbf{x}}; its cosines against the rows of WW, scaled and passed through a softmax, give the class probabilities

p(y=k∣x)=exp⁡ ⁣(et x^⋅w^k)∑c=11000exp⁡ ⁣(et x^⋅w^c)p(y = k \mid \mathbf{x}) = \frac{\exp\!\big(e^{t}\,\hat{\mathbf{x}}\cdot\hat{\mathbf{w}}_k\big)}{\sum_{c=1}^{1000}\exp\!\big(e^{t}\,\hat{\mathbf{x}}\cdot\hat{\mathbf{w}}_c\big)}
(4)

and the prediction is the largest. No gradient step and no labeled image is involved. The paper describes (4) as a multinomial logistic regression classifier with L2-normalized inputs, L2-normalized weights, no bias, and temperature scaling. In that reading the image encoder is the backbone and the text encoder is a hypernetwork, a network whose output is another network's weights: it writes one weight vector per class from the class's description. A new task costs one sentence per class, embedded once and cached for every later prediction.

The same reading describes pre-training. Each training step is a classification task with 32,768 classes, each defined by one caption, and one example per class, the matched image; a zero-shot task differs only in that you write the class captions.

Figure 5 · zero-shot classification
Each class name, wrapped in "A photo of a {label}.", becomes one classifier weight vector. The image is embedded once and the class with the highest cosine similarity wins. Swap the image with the buttons and the argmax moves.
# zero-shot ImageNet: no training, no labeled images
classes = ["tabby cat", "golden retriever", ...]     # 1,000 names
prompts = [f"A photo of a {c}." for c in classes]
W = l2_normalize(text_encoder(prompts), axis=1)       # [1000, d_e]

x = l2_normalize(image_encoder(image))                # [d_e]
logits = 100 * (x @ W.T)                              # cosine to each class
pred = classes[logits.argmax()]                       # highest cosine wins

The 100 in the code is the multiplier the official prompt-engineering notebook uses; any positive multiplier gives the same argmax and changes only the probabilities. On ImageNet the best model reaches 76.2% top-1 and 95% top-5 (the true class is among the five highest scores), which matches Inception-V4's top-5. The previous zero-shot result on ImageNet, Visual N-Grams (Li et al., 2017), was 11.5%. The authors note the comparison is loose: CLIP used a 10x larger dataset and a vision model with about 100x more compute per prediction. A CLIP ResNet-50 trained on the YFCC100M data that Visual N-Grams used matched its reported ImageNet number within one V100 GPU-day.

Across 27 datasets, zero-shot CLIP beats a fully supervised logistic-regression classifier fitted on ResNet-50 features on 16, ImageNet included. The spread is wide: it wins by 28.9 points on Stanford Cars and 22.5 on Food101, and loses by 37.1 on EuroSAT satellite images and 34.0 on KITTI distance estimation. Against few-shot learning on its own features, zero-shot CLIP matches the average of a 4-shot logistic regression, one trained on 4 labeled examples per class, so a class name written as text is worth about four labeled images per class on average.

Prompts and prompt ensembles

The class names that datasets ship with were not written for a text encoder. Most WIT captions are full sentences, so a bare word like dog is an unusual input. Wrapping every label in "A photo of a {label}." closes part of that gap and raises ImageNet accuracy by 1.3%.

Wording also resolves ambiguity. ImageNet has both construction cranes and cranes that fly. In the Oxford-IIIT Pet dataset, "boxer" means a dog breed, but to a text encoder reading the word alone it could as well mean an athlete. The authors wrote per-dataset templates: "A photo of a {label}, a type of pet." for Oxford Pets, a type of food for Food101, a type of aircraft for FGVC Aircraft, "a satellite photo of a {label}." for satellite datasets, and quotation marks around the text or number to be read for OCR (optical character recognition) datasets.

The second technique is ensembling. Build one class vector from several templates ("A photo of a big {label}.", "A photo of a small {label}.") by averaging their embeddings, not their predicted probabilities. The average is one vector per class, so once cached, an ensemble of 80 templates costs the same at test time as a single template. The official notebook normalizes each template's embedding, averages, and renormalizes:

# one class vector from many prompts (order as in the official notebook)
texts = [tpl.format(name) for tpl in templates]   # e.g. 80 templates
e = text_encoder(texts)                           # [80, d_e]
e = e / e.norm(dim=-1, keepdim=True)              # each prompt to unit length
w = e.mean(dim=0)                                 # average in embedding space
w = w / w.norm()                                  # renormalize: one vector

On ImageNet, the 80-template ensemble adds 3.5% over the single default prompt, and the two techniques together add almost 5% with no change to the trained weights. Averaged over 36 datasets they add almost 5 points, about the gain the paper's Figure 4 shows from using 4 times more compute with plain class names. The figure below sketches the mechanism in 2D with made-up angles: a boxer photo, three breed classes, and the three ways of writing the class text.

Figure 6 · prompt wording and ensembles
A 2D sketch with illustrative angles. The amber vector is a photo of a boxer dog; the teal vectors are the class vectors. With the name alone, "boxer" sits between the dog-breed and athlete senses and the photo goes to pug. The pet prompt fixes the sense but wins by a margin of 0.006. The ensemble shows four prompt vectors per class (thin), their shorter raw mean (dot), and the renormalized class vector (bold); the margin grows to 0.150.

Robustness to distribution shift

ImageNet models are usually tested on the ImageNet validation set, which is drawn from the same distribution as its training set. Several datasets ask what happens when the images change and the classes stay: ImageNetV2 (a re-collection following the original process), ImageNet Sketch (drawings), ImageNet-R (renditions such as paintings, cartoons and toys), ObjectNet (objects photographed at odd angles and on unusual backgrounds), ImageNet-A (natural images that ResNet-50 classifiers get wrong), and the video datasets Youtube-BB and ImageNet-Vid. The paper reports that a ResNet-101 makes 5 times as many mistakes on these seven shifted datasets as on the ImageNet validation set.

The paper measures robustness following Taori et al. (2020). Across many ImageNet-trained models, accuracy under distribution shift rises predictably with ImageNet accuracy (linearly, once both accuracies are logit-transformed), along a trend well below the diagonal y=xy = x where a model would lose nothing. Effective robustness is how far a model sits above that trend: extra shifted-dataset accuracy beyond what its ImageNet accuracy predicts. Zero-shot CLIP models sit far above it and close the gap between ImageNet accuracy and shifted accuracy by up to 75%.

The cleanest comparison fixes ImageNet accuracy. A ResNet-101 and zero-shot CLIP both score 76.2% on ImageNet, and the figure shows them on each shifted dataset. The differences run from 5.8 points on ImageNetV2, which was built to match ImageNet, through 35.0 on Sketch, 39.7 on ObjectNet and 51.2 on ImageNet-R, to 74.4 on ImageNet-A. The ImageNet-A number exaggerates the gap: that dataset was built by deleting images that ResNet-50 classifiers predict correctly, so a ResNet-101 fails on it partly by construction.

Figure 7 · the robustness gap
Per dataset, a ResNet-101 against zero-shot CLIP, tied at 76.2% on ImageNet. The amber row gives CLIP's lead in accuracy points. Click a dataset button to highlight its pair. Numbers are from the paper's Figure 13.

The authors test whether the robustness comes from zero-shot CLIP never having trained on the ImageNet distribution. Fitting an L2-regularized logistic-regression classifier on CLIP features using the ImageNet training set raises ImageNet accuracy by 9.2 points, to 85.4%, which ties the 2018 state of the art. Average accuracy on the shifted datasets slightly decreases. ImageNetV2, the dataset built to follow ImageNet's own process, is the only one that improves significantly, which the paper reads as the gain from supervised adaptation being concentrated around the ImageNet distribution. ImageNet-R drops by 4.7 points, ObjectNet by 3.8, ImageNet Sketch by 2.8 and ImageNet-A by 1.9.

Limitations and what came after

The paper's own list of limitations, with its numbers:

Because WIT was collected from the web, some evaluation images may appear in it. The authors ran a duplicate detector over 35 evaluation datasets and found a median overlap of 2.2% and an average of 3.2%. Overall accuracy rarely shifted by more than 0.1%; the largest estimated gain was 0.6%, on Birdsnap, which has 12.1% overlap.

Later systems, outside the scope of the CLIP paper, reuse its encoders as components. DALL-E 2 (Ramesh et al., 2022) generates a CLIP image embedding from the text with a learned prior and decodes it into an image. Stable Diffusion v1 conditions its image generator on a frozen CLIP ViT-L/14 text encoder; the latent diffusion paper it builds on trained its own text encoder from scratch. LLaVA feeds features from a frozen CLIP ViT-L/14 image encoder into a language model, which gives CLIP's image representation a text decoder.

Provenance Verified against primary literatureHow we verify
CLIP (2021)Radford et al.: WIT (400M pairs), the Figure 2 efficiency comparison, the Figure 3 pseudocode for the symmetric loss, the learned temperature and its clamp, the zero-shot, prompt, robustness and limitation results quoted here.
model.py (code)Official OpenAI repo. logit_scale = log(1/0.07); features divided by their norm in forward; logits_per_image = logit_scale.exp() * image_features @ text_features.t(); causal text mask (triu); text feature at text.argmax(dim=-1).
Prompt_Engineering_for_ImageNet.ipynbOfficial notebook: 80 templates; each prompt embedding is normalized, the class average is taken, and the average is renormalized.
N-pair / InfoNCESohn (2016) and Oord et al. (2018): the batch-of-negatives objective CLIP adopts.
ConVIRT (2020)Zhang et al.: the contrastive image-text objective in medical imaging that CLIP simplifies and scales.
ViT (2020)Dosovitskiy et al.: the image encoder for CLIP's strongest models.
ImageNet-A (2019)Hendrycks et al.: built by deleting the images that fixed ResNet-50 classifiers predict correctly.
Later useDALL-E 2 abstract (a prior generates a CLIP image embedding from text); CompVis Stable Diffusion README (v1 conditions on a frozen CLIP ViT-L/14 text encoder).
This page's arithmeticSoftmax, loss and gradient values in the worked examples, ln 6 and ln 32,768, the 390,625 steps, and the 4.3 GB size of a float32 32,768 x 32,768 grid are computed here; the paper does not print them.
correctionTwo points where common summaries, and the paper's own shorthand, differ from what the paper and code do. (1) Figure 3 labels t a "learned temperature parameter", but the logits are multiplied by exp(t), so exp(t) = 1/tau and t = log(1/tau), the log of the inverse temperature. model.py initializes it as logit_scale = log(1/0.07), about 2.66. (2) The 4x efficiency gain in Figure 2 compares the contrastive objective with a bag-of-words predictor. The transformer captioning model was itself 3x slower than bag-of-words, so contrastive against word-by-word captioning is about 12x, not 4x. Two paper-versus-code notes with the same math: Figure 3 applies separate projections W_i, W_t and then L2-normalizes, while model.py folds each projection into its encoder (VisionTransformer.proj or the ResNet attention-pool output projection; text_projection in encode_text) and normalizes in forward; and the paper reads the text feature at [EOS], which the code finds with text.argmax(dim=-1) because <|endoftext|> is the last token added to the BPE vocabulary and has the largest id. The clamp at 100 is stated in the paper; the released model.py is inference code and contains no clamp.

Questions you might still have

?

Why is matching a caption easier than predicting its words?
A caption model must reproduce the exact wording, and many different sentences fit one image, so most of its effort goes into phrasing. The contrastive task only asks which of the batch's captions belongs to this image. In the paper's Figure 2 a transformer captioning model learned ImageNet zero-shot transfer 3x slower than a bag-of-words predictor, and the contrastive objective was a further 4x faster than bag-of-words.

?

The image encoder never sees a class label. How does it classify?
The text encoder supplies the classifier. It embeds one sentence per class name, and those unit vectors are the weight rows of a linear classifier with no bias. The image encoder embeds the image once, and the class whose vector has the highest cosine similarity wins. No labeled image is used.

?

Why learn the temperature instead of fixing it?
Cosine similarities lie between -1 and 1, so without a multiplier the logits span at most 2 units and the softmax over 32,768 captions cannot become confident. The right multiplier is hard to guess and changes during training, so CLIP learns its log as one extra parameter, starting from 1/0.07 and clamped at 100, which the authors found necessary for stable training.

?

Did CLIP see the test sets during pre-training?
Some of them, a little. The paper ran a duplicate detector over 35 evaluation datasets: the median overlap with WIT was 2.2% and the average 3.2%. Overall accuracy rarely moved by more than 0.1%, and the largest estimated gain was 0.6% on Birdsnap, which had 12.1% overlap.

?

Does it understand the image, or just match strings?
It learns a shared geometry in which related images and texts point in similar directions. Prompt wording changes its results for that reason, and it does poorly on images far from web photos and captions: 88% on handwritten MNIST digits, below logistic regression on raw pixels, and near random on tasks such as estimating the distance to the nearest car.

?

Can CLIP write a caption for an image?
No. It scores image-text pairs, so it can only pick from the texts you give it. Generating a caption needs a decoder, which later systems attach to a CLIP-style image encoder; the LLaVA explainer covers one of them.

Footnotes & further reading

  1. The paper: Radford, Kim, Hallacy, Ramesh, Goh, Agarwal, Sastry, Askell, Mishkin, Clark, Krueger, Sutskever, Learning Transferable Visual Models From Natural Language Supervision (OpenAI, ICML 2021). Code, including the prompt-ensembling notebook, and blog post.
  2. The batch-of-negatives objective: Sohn, Improved Deep Metric Learning with Multi-class N-pair Loss (2016), and Oord, Li, Vinyals, Representation Learning with Contrastive Predictive Coding (InfoNCE, 2018).
  3. The contrastive image-text precursor CLIP simplifies: Zhang et al., Contrastive Learning of Medical Visual Representations from Paired Images and Text (ConVIRT, 2020).
  4. The image encoder for the strongest models: Dosovitskiy et al., An Image Is Worth 16x16 Words (the Vision Transformer, 2020); see also the ViT explainer.
  5. How ImageNet-A was built: Hendrycks, Zhao, Basart, Steinhardt, Song, Natural Adversarial Examples (2019).
  6. Later use of CLIP embeddings: Ramesh et al., Hierarchical Text-Conditional Image Generation with CLIP Latents (DALL-E 2, 2022), and the Stable Diffusion v1 repository.