wikillm

Paper · 2022-03-31 · cs.CV

Exploring Visual Prompts for Adapting Large-Scale Models

Learns one additive image perturbation (a padding frame, a fixed patch or a random patch) for a frozen model by cross-entropy, then adds it to every test image. On CLIP ViT-B/32 over 12 datasets the author-reported average is 78.2 with the prompt, against 54.2 for zero-shot text prompts and 83.1 for a linear probe. On frozen ImageNet vision models it trails linear probes by about 40 points.

Visual promptingSoft prompt tuningVision-language pre-trainingvisual-promptingprompt-tuningclipadaptationadversarial-reprogrammingfrozen-backbone

arXivPDFCodeMarkdown15 min read

AI-compiled by claude-haiku-5-5 on 2026-11-01, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.

In plain words

A large image model is usually adapted to a new job by retraining some of its weights, or by training a new output layer on top of it. Both need access to the model's inside. This paper asks whether you can leave the model completely alone and change only what you feed it. The method learns one picture-sized overlay of coloured pixels, a sort of frame, that is added to every input. The model never changes; only the frame is trained.

The frame turns out to work well with CLIP, a model that matches images to text. With CLIP the frame helps a lot over a plain text prompt and comes close to a classic linear probe, and it stays close to one when the test images come from a different source than the training images. With image classifiers that were not trained on text, the frame is far behind a linear probe. Because the frame is the only thing that changes, it can be handed to someone who has only input access to a model.

TL;DR

  • Learns one additive visual prompt, applied to all images, while the pre-trained model stays frozen §3.2.1.
  • The default is a padding frame of width 30 on 224×224 inputs, trained with SGD at learning rate 40 for 1,000 epochs §3.2.2 §3.4.
  • Author-reported: on CLIP ViT-B/32 the prompt lifts the 12-dataset average from 54.2 (text prompt) to 78.2, against 83.1 for a linear probe tab. 1.
  • It is weaker on ImageNet-pretrained classifiers and on BiT-M, where linear probes lead by about 40 points tab. 4.
  • Code is released under MIT by the first author; several settings the paper leaves open are fixed in code and differ from the paper's wording main_clip.py.

Problem

Fine-tuning changes all parameters and linear probes need penultimate-layer activations; both need some access to the model §1 §2.4. Prompting in natural language adapts a frozen model through its input, but the authors note that pixel input has no discrete vocabulary to hand-write prompts from §3.2. The paper argues input-side adaptation is useful when the model is only reachable through an API or cannot be modified §1 §7. It does not state a compute budget or a dataset-size threshold where the method stops being useful.

Method

The method has two parts: an input transformation and an output transformation §3. For vision models, the authors say visual prompting is essentially the same as adversarial reprogramming; the v2 change log removes the earlier novelty claims app. A.3.

Input transformation (learn one prompt). Given a frozen model F and a labelled downstream set, learn one prompt v of the input's shape. During training the frozen model is asked for the likelihood of the correct label given x + v, and only v is updated §3.2.1 eq. 1.

Test time. The same v is added to every test image, and the prompted images go through F unchanged §3.2.1 eq. 2. The prompt is input-agnostic: one vector per dataset, not one per image §2.4.

Templates. Three templates are compared: a pixel patch at a random location, a pixel patch at a fixed location, and a padding frame. The number of parameters is C·p² for a patch and 2Cp(H + W − 2p) for padding, where C, H, W are channels, height and width and p is the prompt size §3.2.2. Padding with p = 30 is the default for all experiments §3.2.2 §6.2.

Resizing. Every downstream image is resized to the pre-trained model's input size, and the prompt is added directly to the input region, not padded around a smaller image §3.2.1. Images are preprocessed as in the model's own evaluation setting, and the paper calls this important §3.4.

Output transformation (map outputs to labels).

  • CLIP: each class name is written into the fixed text prompt. Cosine similarities between the prompted image and each class text are normalised with a softmax, and the highest-probability class is the answer §3.3. Only the visual prompt is optimised; the text prompt is fixed §3.3.
  • Vision models without text: downstream class indices are assigned arbitrarily to pre-trained output indices, and unassigned indices are dropped from the loss §3.3.

Training recipe (CLIP and vision). SGD at learning rate 40, with cosine decay over 1,000 epochs §3.4. Batch sizes are 256 for CLIP, and 128 (BiT-M, RN50) or 32 (Instagram) for the vision models §3.4. Images are 224×224 §3.4. The paper states no adversarial constraint on the perturbation; imperceptibility is not a goal §3.2.1.

Pseudocode
# Learn one visual prompt for a frozen model  [§3.2.1] [eq. 1]
# Input:  frozen model F; labelled train set D; prompt size p
# Output: prompt v, one tensor shared by all images
def learn_visual_prompt(F, train_set, p):
    # Start from random values; the paper does not state the init
    # [code: models/prompters.py#L13-L16]
    v = padding_prompt_init(p, C, H, W)           # (1, C, H, W)
    # Only v is stepped; the weights of F are never updated  [§3.2.1]
    # SGD, momentum 0.9, no weight decay  [code: main_clip.py#L40-L46]
    optimizer = sgd(params=[v], lr=40, momentum=0.9)
    for step, (x, y) in batches(train_set, size=256):
        # Learning rate: linear warmup, then cosine decay  [§3.4]
        # [code: utils.py#L34-L48]
        set_learning_rate(optimizer, lr_schedule(step))
        # Add the prompt after the model's normalisation, not to raw pixels
        # [code: main_clip.py#L261]
        x_prompted = x + v                        # (B, C, H, W)
        # Scores from the frozen model; CLIP uses cosine similarity to text
        # embeddings of the class names  [§3.3]
        scores = F(x_prompted)
        # Cross-entropy; minimising it maximises the label likelihood [eq. 1]
        loss = cross_entropy(scores, y)
        loss.backward()
        optimizer.step()
    return v


# Test time: the same prompt is added to every test image  [§3.2.1] [eq. 2]
def predict(F, v, x_test):
    # The prompt is one fixed tensor for the whole dataset  [§3.2.1]
    return argmax(F(x_test + v))

Hyperparameters

NameValueWhereNotes
OptimizerSGD§3.4 main_clip.pySame in main_vision.py#L184-L187
Learning rate40§3.4 main_clip.pyPaper and code agree
Momentum0.9main_clip.pyNot stated in the paper
Weight decay0main_clip.pyNot stated in the paper
Learning-rate schedulecosine decay§3.4 utils.pyCode uses linear warmup first; see next row
Warmup1000 steps, linearmain_clip.py utils.pyNot stated in the paper
Schedule lengthlen(train loader) × epochsmain_clip.pyDecay target inferred from code
Epochs1000§3.4 main_clip.pyPaper and code agree
Early stoppingpatience 1000main_clip.py main_clip.pyPaper says nothing; default effectively disables it
Batch size, CLIP256§3.4 main_clip.py
Batch size, BiT-M and RN50128§3.4 main_vision.py
Batch size, Instagram32§3.4 README.mdCode has no per-model default
Input size224×224§3.4 main_clip.py
Prompt templatepadding§3.2.2 main_clip.pyOptions: padding, fixed patch, random patch
Prompt size p30§3.2.2 main_clip.pyAblated from 1 to 224 §6.2
Padding parameters2·C·p·(H + W − 2p)§3.2.2Equals 69,840 at p = 30 and 224×224 (our arithmetic); the four code tensors sum to the same size prompters.py
Prompt initnot stated in paperprompters.pyCode draws standard-normal values
Random seednot stated in papermain_clip.pyCode uses 0
Mixed precisionnot stated in papermain_clip.py main_clip.pyCLIP path only; vision path is fp32
Logit-scale clampnot stated in papermain_clip.pyClamped to ln 100 after each step
CLIP modelViT-B/32tab. 3 main_clip.py--arch flag is parsed but unused
Text prompt, default"This is a photo of a {}"§4.2 tab. 6 main_clip.pyOnly this template is in code
Text prompt, CLEVR"This is a photo of {} objects" with labels "three" to "ten"§4.2 tab. 6Not in code
Text prompt, Camelyon17"a tissue region {} tumor" with "containing" / "not containing"§4.2 tab. 6Not in code
Dataset splitsper tableapp. A.2 tab. 6Splits for OxfordPets, Flowers, Food, SUN, DTD, EuroSAT and UCF follow the cited prior split source
Pre-trained modelsCLIP ViT-B/32; Instagram ResNeXt; BiT-M ResNet-50; RN50tab. 3 §3.1Instagram model fine-tuned on ImageNet-1k §3.1

Results

Author-reported. Setup: four frozen pre-trained models tab. 3; 12 image classification datasets §4.1 tab. 6; baselines are zero-shot text prompting, linear probe and full fine-tuning §4.2; WILDS distribution-shift datasets for robustness §4.1. Hardware and run time are not stated.

SettingMetricBaselineThis paperSource
CLIP, 12-dataset averagetop-1 accuracy54.2 (text prompt)78.2 (visual prompt + text)tab. 1
CLIP, 12-dataset averagetop-1 accuracy83.1 (linear probe)78.2tab. 1
CLIP, 12-dataset averagetop-1 accuracy86.9 (fine-tuning)78.2tab. 1
CLIP, WILDS average (iWildCAM, FMoW, Camelyon17)top-1 accuracy62.6 (linear probe)58.1tab. 2
CLIP, WILDS averagetop-1 accuracy61.6 (fine-tuning)58.1tab. 2
CLIP, Camelyon17top-1 accuracy84.9 (linear probe)89.8tab. 2
Instagram ResNeXt, 12-dataset averagetop-1 accuracy71.7 (linear probe)32.4tab. 4
BiT-M ResNet-50, 12-dataset averagetop-1 accuracy72.6 (linear probe)32.6tab. 4
RN50, 12-dataset averagetop-1 accuracy72.5 (linear probe)25.7tab. 4

Full CLIP results, 12 datasets tab. 1. Shaded in the paper where the visual prompt beats the linear probe: EuroSAT, SVHN and CLEVR.

ModelMethodCIFAR100CIFAR10FlowersFoodEuroSATSUNUCFSVHNPetsDTDRESISCCLEVRAverage
CLIPTP63.189.061.979.840.060.059.95.185.943.042.420.254.2
CLIPVP + TP75.394.270.378.996.460.666.188.485.057.184.581.478.2
CLIPLP80.095.096.984.695.375.083.365.489.274.692.366.083.1
CLIPFT82.195.897.480.597.964.080.995.788.572.393.394.486.9

CLIP, WILDS distribution shift tab. 2. Shaded where the visual prompt beats the linear probe: Camelyon17.

ModelMethodiWILDCAMFMoWCamelyon17Average
CLIPTP14.113.552.726.8
CLIPVP + TP51.732.989.858.1
CLIPLP66.736.384.962.6
CLIPFT54.946.683.361.6

Vision models, 12 datasets tab. 4. Shaded where the visual prompt beats the linear probe: SVHN and CLEVR for Instagram.

ModelMethodCIFAR100CIFAR10FlowersFoodEuroSATSUNUCFSVHNPetsDTDRESISCCLEVRAverage
InstagramVP16.762.122.99.985.42.215.453.818.629.141.430.932.4
InstagramLP64.090.192.765.890.658.176.648.094.570.979.230.271.7
InstagramFT77.877.894.575.697.456.772.996.893.973.593.487.983.2
BiT-MVP16.253.629.211.672.52.616.656.324.730.043.034.832.6
BiT-MLP73.090.899.172.694.449.572.949.885.268.487.728.472.6
BiT-MFT76.294.199.475.698.352.781.397.289.069.393.688.284.6
RN50VP10.154.514.05.178.71.19.557.110.88.229.929.525.7
RN50LP67.787.792.762.594.557.569.460.391.166.787.132.672.5
RN50FT79.994.196.973.296.555.976.796.992.366.793.489.384.3

Vision models, WILDS tab. 5. Shaded where the visual prompt beats the linear probe and fine-tuning: Camelyon17 for Instagram.

ModelMethodiWILDCAMFMoWCamelyon17Average
InstagramVP52.214.087.151.1
InstagramLP64.122.777.454.7
InstagramFT62.646.886.565.3
BiT-MVP48.715.783.349.2
BiT-MLP55.922.389.055.7
BiT-MFT59.049.881.863.5
RN50VP51.912.684.549.7
RN50LP62.728.790.260.5
RN50FT62.246.788.065.6

Pre-trained models tab. 3.

ModelArchitectureModalityPre-trained datasetObjective
CLIPViT-B/32Vision-language400M image-text pairsContrastive
InstagramResNeXt-101 32x8dVision3.5B Instagram photosCross entropy
BiT-MResNet-50Vision14M ImageNet-21kCross entropy
RN50ResNet-50Vision1.2M ImageNet-1kCross entropy

Downstream datasets and CLIP text prompts tab. 6. Splits for OxfordPets, Flowers102, Food101, SUN397, DTD, EuroSAT and UCF101 follow a cited prior split source; the rest use the official splits app. A.2.

DatasetTrainValidationTestClassesText prompt
CIFAR10050,000-10,000100"This is a photo of a {}"
CIFAR1050,000-10,00010"This is a photo of a {}"
Flowers1024,0931,6332,463102"This is a photo of a {}"
Food10150,50020,20030,300101"This is a photo of a {}"
EuroSAT13,5005,4008,10010"This is a photo of a {}"
SUN39715,8883,97019,850397"This is a photo of a {}"
UCF1017,6391,8983,783101"This is a photo of a {}"
SVHN73,257-26,03210"This is a photo of a {}"
OxfordPets2,9447363,66937"This is a photo of a {}"
DTD2,8201,1281,69247"This is a photo of a {}"
Resisc4518,9006,3006,30045"This is a photo of a {}"
CLEVR/count70,000-15,0008"This is a photo of {} objects"
iWildCAM129,80914,96142,791182"This is a photo of a {}"
FMoW76,86319,91522,10862"This is a photo of a {}"
Camelyon17302,43634,90485,0542"a tissue region {} tumor"

Other reported results, in text.

  • Average gain of the CLIP visual prompt over the text prompt is 24 points §5.1 (computed as 78.2 − 54.2 tab. 1).
  • The CLIP gap to linear probe is reduced to 4.5 points and to fine-tuning 3.5 points on WILDS averages §5.2 tab. 2.
  • Dataset-level gain ranges from +83.2% (best) to −1% (worst) §6.1.
  • Prompt-template ablation on EuroSAT with frozen CLIP: fixed-location templates beat random-location ones, and padding with p = 30 is best overall §6.2 fig. 6. A single-pixel prompt gives about +3% over the text prompt on EuroSAT §6.2 fig. 7.
  • Output-mapping test with a dogs-vs-cats subset on RN50: 100% with semantically similar index mapping vs 62.5% with swapped indices §6.3.
  • Lower-quality CLIP text prompts show larger visual-prompt gains §6.3 fig. 8.
  • Model-architecture ablation on CIFAR100 is in fig. 9 (app. A.1); no numbers are given in text.

Paper vs code

Code: hjbahng/visual_prompting at 679e71f, MIT, copyright 2022 Hyojin Bahng LICENSE. It is linked from the project page and the abstract, and its owner is the first author. The repository has the CLIP and vision training scripts and the prompt module. It contains CIFAR-100 only.

  • Dataset coverage. The paper reports 12 datasets and three WILDS sets §4.1. The code loads CIFAR-100 only, hard-coded in both scripts main_clip.py main_vision.py. The other datasets, the WILDS sets and the CLEVR/Camelyon templates are not in the release tab. 6.
  • Text template. The paper uses per-dataset templates §4.2 tab. 6. The CLIP script fixes "This is a photo of a {}" for every run main_clip.py.
  • Model selection. The paper does not say which checkpoint it reports. The code validates after every epoch on the CIFAR-100 test split, keeps the checkpoint with the best accuracy, and saves it as model_best main_clip.py main_clip.py. Any reported number taken from model_best was selected on the test split.
  • Vision label mapping. The paper maps downstream classes arbitrarily, then drops unassigned indices §3.3. The code uses the first N output indices in order (class i to index i), with N = 100 for CIFAR-100 main_vision.py main_vision.py main_vision.py. That is not the semantic mapping the paper's own dog/cat test relies on §6.3.
  • CLIP architecture flag. The paper's CLIP model is ViT-B/32 tab. 3. The code loads ViT-B/32 directly, and the --arch option is parsed but never read main_clip.py main_clip.py.
  • Optimizer details. Momentum 0.9, zero weight decay and 1000 warmup steps are in the code only main_clip.py utils.py.
  • Logit scale. The CLIP script clamps the logit scale to ln 100 after each step. The code comment attributes this to the original CLIP work main_clip.py. The paper does not mention it.
  • Mixed precision. CLIP training uses autocast and a gradient scaler main_clip.py main_clip.py. Vision training is fp32 main_vision.py.
  • Frozen model. Both scripts call model.eval() but never set requires_grad to false on the frozen model's parameters main_clip.py main_vision.py. Only the prompt is in the optimizer, so the frozen weights do not change, but backward still computes their gradients.
  • Random-patch location. The paper says the random template is placed at a random location, without detail §3.2.2. The code draws one location per forward call, so one location is shared by the whole batch. It also draws a new location at evaluation time prompters.py.
  • Fixed-patch location. The paper says "fixed location" without naming it §3.2.2. The code places the patch in the top-left corner prompters.py.
  • Prompt init. Padding values are standard-normal draws in the normalised input space prompters.py. The paper gives no init.
  • Zero-valued centre. The centre of the padding prompt is zero in the normalised space, so it equals each model's mean colour, not black prompters.py main_vision.py.
  • Batch size for vision. The code default is 128 main_vision.py. The README says to use 32 for Instagram README.md, which matches §3.4.
  • Baselines. The zero-shot text number on CIFAR-100 can be checked from the "Original Acc@1" line the CLIP script prints main_clip.py main_clip.py. The paper gives the same number as 63.1 tab. 1. Linear probe and fine-tuning baselines are not in the code.
  • Early stopping. The patience default of 1000 means it is effectively never triggered main_clip.py main_clip.py.
  • Text vs paper claim. The text says the vision-model gap is about +40% §5.1. From the averages in tab. 4 the gap is 39.3 points for Instagram, 40.0 for BiT-M and 46.8 for RN50 (our arithmetic).

No discrepancies in the training objective or in the schedule's base learning rate, epoch count and batch sizes.

Pitfalls

  • Where the prompt is added. The paper says "image" §3.2.1. The code adds it after the model's normalisation, so the prompt values are in normalised units, not pixel units main_clip.py main_vision.py. A reimplementation that adds raw-pixel values gets a different scale for the same numbers.
  • Preprocessing must match the model. The paper says closely following each model's evaluation preprocessing matters §3.4. CLIP uses its own preprocessing main_clip.py. Vision models use resize 256, crop 224 and ImageNet mean/std main_vision.py.
  • Model selection on test. As above, reported CIFAR-100 accuracy from the released script is the best epoch on the test split main_clip.py main_clip.py.
  • Class mapping for vision models. The default is index-order mapping. The paper's own ablation finds that semantically similar index assignments matter §6.3. The paper does not state which indices it used for its vision tables §3.3.
  • CLIP logit scale. The CLIP loss depends on the logit scale used in the text-classifier output (clamped to ln 100 in code main_clip.py). The paper's equation does not show a scale term eq. 1 §3.3.
  • Learning rate depends on the schedule. Both paper and code use 40 §3.4 main_clip.py. The paper names only a cosine decay; the warmup and its length come from code utils.py. A run with a different warmup is not the paper's run.
  • Cost. The default run is 1,000 epochs and validates after every epoch with two forward passes, one with the prompt and one without main_clip.py main_clip.py. Gradients flow through the frozen model every step main_clip.py.
  • Data scope. The WILDS robustness claims §5.2 and the other 11 dataset numbers cannot be reproduced from the release, which has only CIFAR-100 main_clip.py.
  • Prompt meaning. The paper says the prompt need not be readable by people §3.2. It reports no analysis of what a learned frame encodes.
  • Single-pixel claim. The single-pixel result on EuroSAT §6.2 has no separate code path. The nearest is the fixed-patch template with prompt_size=1 prompters.py. The paper does not give the pixel's location.
  • Version history. v1 claimed methodological novelty; v2 withdrew it after the adversarial reprogramming overlap was pointed out app. A.3. This card follows v2.
  • No adversarial constraint. The perturbation is not kept small or invisible §3.2.1. Results do not transfer to adversarial robustness claims.
  • Hardware and time are not stated; compute cost cannot be estimated from the paper.

Lineage

  • Builds on: adversarial reprogramming, which the paper cites as [elsayed2018adversarial] and says shares the mechanism §1 §2.3; soft prompt and prefix tuning in language models, cited as [lester2021power] and [li2021prefix] §2.1.
  • Related concurrent work: Visual Prompt Tuning, which uses deep prompts in Vision Transformers §2.2.
  • Compared against: fine-tuning, linear probe and zero-shot text prompting §4.2.
  • Pre-trained models: CLIP [radford2021learning] tab. 3; Instagram ResNeXt [mahajan2018exploring]; BiT-M [kolesnikov2020big]; RN50 [he2016deep] tab. 3.
  • Superseded by: none recorded in this wiki.

Source and license

Adapted from “Exploring Visual Prompts for Adapting Large-Scale Models” by Hyojin Bahng, Ali Jahanian, Swami Sankaranarayanan, Phillip Isola (arXiv:2203.17274), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/hjbahng/visual_prompting at commit 679e71fc888c (MIT). Any quoted code is shown under that license.