Paper · 2022-02-07 · cs.CV
Context Autoencoder for Self-Supervised Representation Learning
Context autoencoder (CAE) pretrains a ViT by hiding 50% of the patches. An encoder sees only the visible ones, a cross-attention regressor predicts the hidden patches' encoder representations, and a decoder reconstructs discrete tokens from them. Author-reported: ViT-B at 1600 epochs gives 83.9 fine-tuning, 77.1 attentive probing and 50.2 ADE20K mIoU.
Masked image modelingSelf-supervised learningVision Transformer (ViT) backbonesLinear probingpretrainingmasked-image-modelingvision-transformerrepresentation-learning
arXivPDFCodeMarkdown14 min read
AI-compiled by claude-haiku-5-5 on 2026-10-24, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.
In plain words
Self-supervised pretraining for images often works like a fill-in-the-blank game. Parts of a picture are hidden, and the network learns to guess them from the parts it can see. The network that learns this way is then reused for other vision jobs. This paper keeps that game but changes how the guessing is organised.
The main idea is to split the network into three jobs: an encoder that only looks at the visible pieces and builds features, a small module that predicts the features of the hidden pieces from the visible features, and a decoder that turns those predicted features into a description of the hidden pieces. Only the encoder is kept afterwards. Because the predictions are made in the feature space itself, the encoder is not forced to do the decoding work.
The authors argue that this separation gives better features for tasks such as segmentation and detection than older masked-image methods, which mix the two jobs inside one network.
TL;DR
Context autoencoder (CAE) is a masked-image-modeling method for ViT pretraining without labels. It hides about half the patches, encodes only the visible ones, and regresses the hidden patches' encoder representations with a cross-attention regressor. A decoder then predicts discrete tokens for the hidden patches, and the two losses are summed. Only the encoder is kept for downstream tasks. Reported gains over MAE and BEiT are author-reported and depend on the probe and the tokenizer.
Problem
Masked image modeling pretrains a ViT by predicting hidden patches. In BEiT, the ViT paper and iBOT, one ViT both builds the representation and completes the prediction, so the two roles are mixed §1. MAE separates encoder and decoder, but the authors say the decoder can still learn representations for the visible patches, which limits representation quality §1 §4.2. Most earlier methods also lack an explicit model that maps visible-patch representations to masked-patch representations §1.
The authors assume that predicting masked patches is easier when the encoded representations carry more semantics, and that accurate prediction pushes the encoder toward semantics §1. They also argue that contrastive pretraining with random crops mostly learns from central image regions, whereas masked modeling covers all patches §4.2. Both points are arguments from the authors' analysis and visualisations, not separate proofs §4.1 §4.2 §4.3.
Method
CAE has three parts: an encoder F, a latent contextual regressor H and a decoder G §3.1 fig. 1. Each image is split into visible patches X_v and masked patches X_m, using random block-wise masking in the style of BEiT. For each 224 by 224 image, 98 of the 196 patches (14 by 14 grid) are hidden §3.2.
- Mask. Hide 98 of 196 patches in random blocks §3.2. The block sampler is defined in the code, not in the paper's text masking_generator.py.
- Encode visible patches. F is a ViT that embeds only the visible patches, adds position embeddings and outputs Z_v, with a class token kept. The masked patches never enter F during the prediction path §3.1 modeling_cae_helper.py.
- Regress hidden representations. H is a stack of cross-attention blocks. Its queries are one learned mask token, repeated for every hidden patch, plus the hidden patches' positions. Its keys and values are Z_v together with the output of the previous regressor layer. Visible representations are not updated §3.1 modeling_cae_helper.py.
- Targets for the hidden representations. The target Z̄_m is the encoder's output for the hidden patches, with gradient stopped §3.2 modeling_cae.py.
- Decode. G is a stack of self-attention blocks, followed by a linear layer. It receives only the regressor output for the hidden patches plus their positions, not the visible representations §3.1 modeling_cae_helper.py.
- Reconstruction targets. A discrete tokenizer assigns one code to each patch of the full image. The reported main runs use a d-VAE trained on ImageNet-1K without labels, and a second setting uses the DALL-E tokenizer, trained on 400M images §3.2 tab. 1 §5.5.
- Loss. The total loss is a cross-entropy term on the decoder's token logits plus λ times a mean-squared-error term between the regressor output and Z̄_m, with λ = 2 eq. 1 §3.2 §5.2.
- Downstream use. After pretraining, the encoder is kept and the pretext parts are replaced by the downstream head §3.1 fig. 1.
The paper also gives a probabilistic factorisation, read as encoder, then regressor, then decoder §4.3. It is an interpretation, not a training change. The probabilistic equations are not numbered in the source as checked here, so they are cited by section.
# CAE pretraining loss [§3.1] [§3.2] [eq. 1]
# image: (B, 3, H, W); masked: (B, 196) bool, True for 98 hidden patches
def cae_loss(image, masked):
# Keep the visible patches as the only encoder input [§3.1]
visible = patches(image)[~masked] # (B, N_v, d_in)
# Encode visible patches; the class token is kept [§3.1]
visible_repr = encoder(visible, positions) # (B, N_v + 1, d)
# Target: the encoder on the hidden patches, no gradient [§3.2]
hidden_target = stop_gradient(
target_encoder(patches(image)[masked]) # (B, N_m, d)
)
# Predict hidden representations from the visible ones [§3.1]
# Queries: learned mask token plus position of each hidden patch
hidden_pred = regressor(
mask_token, visible_repr, pos_hidden, pos_visible
) # (B, N_m, d)
# Decode hidden representations into token logits [§3.1]
logits = decoder(hidden_pred + pos_hidden) # (B, N_m, 8192)
# Discrete targets from the tokenizer, no gradient [§3.2]
codes = tokenizer(image)[masked] # (B, N_m)
# Reconstruction plus alignment, lambda = 2 [eq. 1] [§3.2] [§5.2]
loss_rec = cross_entropy(logits, codes)
loss_align = mse(hidden_pred, hidden_target)
return loss_rec + 2.0 * loss_alignThe pseudocode above is a condensed, language-agnostic reading. In the code, target_encoder is a second module that shares the encoder's weights, with no gradient. See Paper vs code.
Hyperparameters
Pretraining is on ImageNet-1K. Values are the paper's unless the code column says otherwise.
| Name | Value | Where | Notes |
|---|---|---|---|
| Input | 224 by 224, 16 by 16 patches (14 by 14 grid) | §5.2 | |
| Mask | 98 of 196 patches hidden, block-wise (50%) | §3.2 §5.5 tab. 7 | 40% and 60% tested in tab. 7; 50% chosen |
| Minimum block size | 16 patches | not stated in paper | code default run_pretraining.py |
| Encoder | ViT-S 12 blocks, width 384; ViT-B 12 blocks, width 768; ViT-L 24 blocks, width 1024 | §5.1 | |
| Regressor | 4 cross-attention blocks | §5.1 | cae_base_800e.sh |
| Decoder | 4 self-attention blocks, then a linear layer | §5.1 | cae_base_800e.sh |
| Decoder output classes | 8192 tokens | not stated in paper | code default run_pretraining.py |
| Decoder width (large) | not stated in paper | not stated | code default 768 run_pretraining.py; the large script intends 1024, see Paper vs code |
| Loss weight λ | 2 | eq. 1 §5.2 §5.5 | λ = 1, 1.5, 2 give linear probe 63.4, 63.7, 64.1 §5.5 |
| Optimizer | AdamW | §5.2 | |
| Peak learning rate | 1.5e-3 | §5.2 | cae_base_800e.sh |
| Schedule | warmup, then cosine decay | §5.2 | minimum LR 1e-5 in code run_pretraining.py |
| Warmup | 10, 20 and 40 epochs for 300, 800 and 1600 epochs | §5.2 | cae_base_300e.sh |
| Weight decay | 0.05 | §5.2 | |
| Batch size | 2048 (64 per GPU on 32 GPUs) | §5.2 | README.md |
| Epochs | 300, 800 or 1600 | §5.2 | |
| Augmentation | random cropping and horizontal flipping | §5.2 | crop scale 0.08 to 1.0, bicubic, in code datasets.py run_pretraining.py |
| Drop path | 0.1 | §5.2 | cae_base_800e.sh |
| Dropout | 0 | §5.2 | |
| Gradient clipping | 3.0 | not stated in paper | cae_base_800e.sh |
| Layer scale (base) | 0.1 for encoder and decoder | not stated in paper | cae_base_800e.sh cae_base_800e.sh |
| Layer scale (large) | 1e-5 | not stated in paper | cae_large_1600e.sh cae_large_1600e.sh |
| Color jitter | 0 | not stated in paper | cae_base_800e.sh |
| Mixed precision | torch autocast | not stated in paper | engine_for_pretraining.py |
Linear probing (frozen encoder, class token):
| Name | Value | Where | Notes |
|---|---|---|---|
| Optimizer | LARS, momentum 0.9 | §5.2 | run_linear.py |
| Epochs | 90 | §5.2 | |
| Batch size | 16384 | §5.2 | 512 per GPU on 32 GPUs cae_base_800e.sh |
| Learning rate | 6.4 | §5.2 | base 0.1 times batch divided by 256 run_linear.py |
| Warmup | 10 epochs | §5.2 | code default run_linear.py |
| Weight decay | 0 | §5.2 | |
| Head | BatchNorm without affine, then linear classifier | §5.2 | run_linear.py |
Attentive probing (frozen encoder, learned query token):
| Name | Value | Where | Notes |
|---|---|---|---|
| Head | one cross-attention module with a learned query token, BatchNorm without affine, then linear | §5.2 | no MLP and no skip connection in the probe §5.2 modeling_finetune.py |
| Optimizer | SGD, momentum 0.9 | §5.2 | |
| Epochs | 90 | §5.2 | |
| Batch size | 8192 | §5.2 | 256 per GPU on 32 GPUs cae_base_800e.sh |
| Learning rate | 0.4 | §5.2 | used as given, no batch scaling cae_base_800e.sh |
| Warmup | 10 epochs | §5.2 | |
| Weight decay, mixup, cutmix, drop path | 0, off, off, 0 | §5.2 | cae_base_800e.sh |
Fine-tuning on ImageNet-1K (ViT-B shown; ViT-S and ViT-L in the paper):
| Name | Value | Where | Notes |
|---|---|---|---|
| Model | ViT-B, 100 epochs | §5.2 | |
| Batch size | 4096 | §5.2 | 128 per GPU cae_base_finetune.sh |
| Learning rate | 8e-3 | §5.2 | cae_base_finetune.sh |
| Layer-wise LR decay | 0.65 | §5.2 | cae_base_finetune.sh |
| Warmup, weight decay, drop path | 5 epochs, 0.05, 0.1 | §5.2 | cae_base_finetune.sh |
| Mixup, cutmix | not stated in paper | not stated | 0.8 and 1.0 in code cae_base_finetune.sh |
| ViT-S | 200 epochs, LR 1.6e-2, decay 0.75 | §5.2 | not compared with code |
| ViT-L | 50 epochs, LR 2e-3, decay 0.75 | §5.2 | not compared with code |
Downstream, from the text §5.2:
- ADE20K segmentation with UperNet, AdamW, input 512 by 512, batch 16, 160k steps, no multi-scale testing. For ViT-B, LR chosen from 1e-4, 2e-4, 3e-4 and 4e-4, decay 0.65, drop path 0.1. For ViT-L, LR from 3e-5, 4e-5 and 5e-5, decay 0.95, drop path 0.15.
- COCO Mask R-CNN 1× schedule with multi-scale training on short side 480 to 800, long side at most 1333, batch 32. ViT-S: LR 3e-4, decay 0.75, drop path 0.1. ViT-B: LR 3e-4, decay 0.75, drop path 0.2. ViT-L: LR 2e-4, decay 0.8, drop path 0.2.
Results
Author-reported. Setup in each row. All results are ImageNet-1K pretraining unless stated. CAE* uses the DALL-E tokenizer; CAE uses the d-VAE tokenizer trained on ImageNet-1K tab. 1 caption.
ImageNet-1K evaluation, ViT-B tab. 1:
| Method | Epochs | Fine-tuning | Linear | Attentive |
|---|---|---|---|---|
| MoCo v3 (2 crops) | 600 effective | 83.0 | 76.2 | 77.0 |
| DINO (12 crops) | 1600 effective | 83.3 | 77.3 | 77.8 |
| iBOT (12 crops) | 1600 effective | 83.8 | 79.5 | 79.8 |
| MAE | 1600 | 83.6 | 67.8 | 74.2 |
| CAE* | 300 | 83.6 | 64.1 | 73.8 |
| CAE* | 800 | 83.8 | 68.6 | 75.9 |
| CAE* | 1600 | 83.9 | 70.4 | 77.1 |
| CAE | 1600 | 83.9 | 71.4 | 77.4 |
ImageNet-1K evaluation, ViT-L, 1600 epochs tab. 1:
| Method | Fine-tuning | Linear | Attentive |
|---|---|---|---|
| MAE | 86.0 | 76.0 | 78.8 |
| CAE* | 86.3 | 78.1 | 81.2 |
| CAE | 86.3 | 77.9 | 81.2 |
ADE20K semantic segmentation, mIoU, UperNet tab. 2:
| Method | Epochs | ViT | mIoU |
|---|---|---|---|
| MAE | 1600 | B | 48.1 |
| iBOT | 1600 effective | B | 50.0 |
| CAE* | 300 | B | 48.3 |
| CAE* | 800 | B | 49.7 |
| CAE* | 1600 | B | 50.2 |
| CAE | 1600 | B | 50.1 |
| MAE | 1600 | L | 53.6 |
| BEiT | 1600 | L | 53.3 |
| CAE* | 1600 | L | 54.7 |
| CAE | 1600 | L | 54.6 |
COCO object detection and instance segmentation, Mask R-CNN 1× tab. 3:
| Method | Epochs | ViT | AP^b | AP^m |
|---|---|---|---|---|
| MAE | 1600 | B | 48.4 | 42.6 |
| iBOT | 1600 effective | B | 48.2 | 42.7 |
| CAE* | 300 | S | 44.1 | 39.2 |
| CAE* | 300 | B | 48.4 | 42.6 |
| CAE* | 1600 | B | 50.0 | 44.0 |
| CAE | 1600 | B | 50.2 | 44.2 |
| MAE | 1600 | L | 54.0 | 47.1 |
| CAE* | 1600 | L | 54.5 | 47.6 |
| CAE | 1600 | L | 54.6 | 47.6 |
Table 3's ViT-S block lists only DeiT, MoCo v3, BEiT and CAE*. The comparisons in the text use the ViT-B and ViT-L blocks.
Classification, fine-tuning on ViT-B, top-1 tab. 4:
| Method | Food-101 | Clipart | Sketch |
|---|---|---|---|
| Random init | 82.77 | 52.90 | 46.42 |
| DeiT (supervised) | 91.81 | 81.18 | 73.45 |
| DINO | 91.67 | 80.72 | 73.13 |
| MAE | 93.19 | 80.63 | 73.87 |
| CAE* | 93.32 | 81.84 | 74.65 |
Ablations, ViT-B, 300 epochs, ImageNet-1K tab. 5:
| Decoder | Alignment | Linear | Attentive | Fine-tune | ADE20K | COCO det. | Params | Train time |
|---|---|---|---|---|---|---|---|---|
| no | no | 60.3 | 71.2 | 82.9 | 47.0 | 46.9 | 120.32M | 1× |
| yes | no | 63.1 | 72.7 | 83.4 | 47.1 | 47.2 | 148.68M | 1.14× |
| no | yes | 62.0 | 71.5 | 83.4 | 47.1 | 47.2 | 120.32M | 1.12× |
| yes | yes | 64.1 | 73.8 | 83.6 | 48.3 | 48.4 | 148.68M | 1.24× |
Reconstruction target, ViT-B, 1600 epochs tab. 8: DALL-E tokenizer 70.4 / 77.1 / 50.2 (linear / attentive / ADE20K); d-VAE tokenizer 71.4 / 77.4 / 50.1; raw RGB pixels 72.4 / 77.0 / 50.4. The authors conclude the target does not matter much.
Mask ratio, ViT-B, 300 epochs tab. 7: 40%: 63.1 / 73.0 / 47.2; 50%: 64.1 / 73.8 / 48.3; 60%: 64.8 / 74.2 / 48.1.
Other numbers in the text §5.4 §5.5:
- Layer count of regressor and decoder, linear probe for 1, 2, 4 and 5 layers: 58.7, 62.1, 64.1, 64.2. Attentive: 67.5, 71.1, 73.8, 73.7. Four layers were chosen §5.5.
- Cascade Mask R-CNN, ViT-B, 1600 epochs: AP^b 52.9 and AP^m 45.5 for CAE*, against MAE at 51.3 and 44.3 tab. 6.
- Detection with a ViT-Huge encoder pretrained on ImageNet-22K: 64.6 mAP on COCO test-dev, given in the text only §5.4. The paper gives no table for it, and this card did not check the repository for its configuration.
Paper vs code
Official repository: https://github.com/Atten4Vis/CAE at commit a7fd1628176358e3e76b0b042b0f6e9f3cd7c76c. The paper links it in the abstract and in its unnumbered Declarations section. The repository has no LICENSE file, so code_license is "not stated". No code is quoted in this card.
- Alignment target is a second module that shares the encoder's weights. The paper defines the target as the same encoder applied to the hidden patches, with gradient stopped §3.2. The code builds a second ViT, the alignment encoder, copies the weights once at construction, and freezes it modeling_cae.py. After each target forward pass, it points each of its parameters at the encoder's tensor storage modeling_cae.py. From the first update on, the target therefore follows the encoder's in-place optimizer updates, as the paper describes. The paper does not mention the aliasing.
- Regressor keys and values include hidden tokens. The paper's §3.1 names visible representations and the previous regressor output as keys and values. Section 5.1 calls self-attention over masked tokens together with visible representations a choice that costs more computation and slightly reduces performance. The code always concatenates visible and hidden tokens into the keys and values, with no switch modeling_cae_helper.py. The paper does not say which setting produced the reported numbers.
- Default tokenizer is DALL-E. The Table 1 rows named CAE use the d-VAE tokenizer trained on ImageNet-1K. In the code, the default is
dall-erun_pretraining.py, the README downloads the DALL-E encoder and decoder README.md, and all scripts use the default. The d-VAE setting appears to need--discrete_vae_type customizedutils.py, and the repository does not show where its weights come from. The DALL-E weights are not included in this card. - Large-model script has a line-continuation bug.
scripts/cae_large_1600e.shends the pretraining command at line 37 without a backslash. Lines 38 to 40 (--decoder_embed_dim 1024,--decoder_num_heads 16,--fix_init_weight) are therefore not passed torun_pretraining.pycae_large_1600e.sh. The script's defaults then apply: decoder width 768, 12 heads, no fixed init run_pretraining.py. Whether the reported ViT-L numbers used the intended 1024 width is not stated. - README numbers differ slightly from the paper. The README's CAE-base rows at 300 and 1600 epochs read linear 64.5 and 70.3, and attentive 74.0 and 77.2 README.md, README.md. The paper reports 64.1 and 70.4 for linear, and 73.8 and 77.1 for attentive tab. 1. The ViT-L row reads linear 77.8, against 78.1 in the paper README.md tab. 1. The README says the paper's results are reproduced README.md. The differences are small but are not the paper's numbers.
- Code-only pretraining settings. These are not in the paper's text: gradient clipping at 3.0 cae_base_800e.sh; layer-scale initial values 0.1 for base and 1e-5 for large cae_base_800e.sh cae_large_1600e.sh; minimum block size 16 patches run_pretraining.py; cosine decay to 1e-5 run_pretraining.py; mixed-precision autocast engine_for_pretraining.py. Each one changes training, so the card lists them rather than assuming the paper's defaults.
- Fine-tuning script adds mixup and cutmix. The paper's fine-tuning section lists layer-wise decay, weight decay, AdamW and the learning rates §5.2, but no mixup or cutmix. The base script uses mixup 0.8 and cutmix 1.0 cae_base_finetune.sh.
- Regressor normalisation is not in the paper. Each regressor cross-attention block applies a LayerNorm after its residual, before the MLP, and the regressor ends with another LayerNorm modeling_cae_helper.py modeling_cae_helper.py.
- Projection layer. An encoder-to-regressor linear layer with LayerNorm is added only when the encoder and decoder widths differ. The same projection is applied to the alignment targets modeling_cae.py modeling_cae.py. For ViT-B, both widths are 768, so no projection is used.
- Settings that match. Pretraining learning rate 1.5e-3, batch 2048, warmup 10 / 20 / 40, weight decay 0.05, mask 98, λ = 2 and four regressor and decoder blocks agree between paper and scripts §5.1 §5.2 cae_base_800e.sh. Linear probing LR 6.4 equals 0.1 times 16384 over 256 run_linear.py. Attentive probing LR 0.4 and batch 8192 (256 per GPU on 32 GPUs) agree cae_base_800e.sh.
- Not compared. Segmentation and detection configurations under
downstream_tasks/were not checked against the paper's per-run settings. ViT-S and ViT-L fine-tuning settings were not compared.
Pitfalls
- Aliasing. The target follows the encoder only because the copy shares tensor storage and is re-pointed after each target pass modeling_cae.py. If a change replaces encoder tensors rather than updating them in place, the target lags by one step, because the re-pointing runs after the target forward pass. Check this when changing checkpoint loading or optimizer code.
- Extra cost. Each step runs a no-gradient forward pass through the alignment encoder on the hidden patches modeling_cae.py. The speed cost of this is not reported separately in the paper; tab. 5 gives one combined training-time ratio.
- Parameter count. The script's printed count includes only parameters with gradients, so it excludes the frozen alignment module run_pretraining.py. The paper's parameter column in tab. 5 does not say whether that module is counted.
- Do not drop the reconstruction term. The authors say training collapses to a trivial solution without masked patch reconstruction §5.5. Dropping the decoder therefore changes what the encoder learns.
- Decoder alone helps little. tab. 5 and §5.5: adding the decoder alone leaves downstream results almost unchanged, while adding both the decoder and the alignment term gives the best linear and attentive scores. Without the decoder, a linear output layer must map semantic features to low-level targets, which the authors say performs worse §5.5.
- Block masking details. The block sampler adds blocks with random size and aspect ratio, in up to 10 attempts per block, until exactly 98 patches are hidden masking_generator.py. A block that does not fit is retried. Changing the number of hidden patches also changes the block sizes, since the maximum block size equals the total hidden count by default masking_generator.py.
- Learning rate depends on batch size for linear probing. The learning rate is base LR times total batch over 256 run_linear.py. The attentive probe uses its LR as given cae_base_800e.sh. Changing batch size for one probe changes its effective schedule.
- Attentive probe baselines. The paper says scores for other models come from the authors' own implementations unless noted tab. 1 caption. Attentive-probe comparisons therefore depend on one implementation.
- Tokenizer and weights. The DALL-E tokenizer is downloaded from OpenAI's CDN README.md. No tokenizer weights are included in this card, and their license is not checked here.
- Code license not established. The repository has no LICENSE file. One source header names the MIT license modeling_discrete_vae.py, but that does not establish a repository-wide license. Quoting code is avoided for that reason.
- Mixed precision. Losses are computed under autocast and the MSE on the alignment is taken in float engine_for_pretraining.py. Numerical changes are possible if you change precision.
Lineage
- Builds on: BEiT for block-wise masking, tokenizer targets and pretraining settings §3.2 §5.2; BERT's masked language modeling §2; iBOT's combination of masked modeling with DINO-style self-distillation §2 §4.2; denoising autoencoders §2.
- Compared against: MAE, a concurrent masked-autoencoder method, which has a card §2 tab. 1; BEiT, iBOT, MoCo v3, DINO, DeiT, SimMIM, SplitMask, Ge²-AE and A²MIM in the tables §2 tab. 1 tab. 2.
- Superseded by: not stated in the paper. The repository points to CAE v2, which adds CLIP latent alignment README.md. CAE v2 is not covered by this card.
Source and license
Adapted from “Context Autoencoder for Self-Supervised Representation Learning” by Xiaokang Chen, Mingyu Ding, Xiaodi Wang, Ying Xin, Shentong Mo, Yunhao Wang, Shumin Han, Ping Luo, Gang Zeng, Jingdong Wang (arXiv:2202.03026), 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/Atten4Vis/CAE at commit a7fd16281763 (not stated (no LICENSE file in the repository)). Any quoted code is shown under that license.