Paper · 2022-04-14 · cs.LG, cs.AI, cs.CV, eess.IV
Masked Siamese Networks for Label-Efficient Learning
Masked Siamese Networks (MSN) pre-trains a Vision Transformer without labels. A randomly masked view must match the prototype assignments that an EMA teacher gives the unmasked view, so no pixels are reconstructed. Author-reported: 72.4% top-1 with 5 labels per ImageNet class and 75.7% with 1% of labels (both ViT-B/4).
Self-supervised learningMasked image modelingVision Transformer (ViT) backbonesLinear probingself-supervisedmasked-image-modelingjoint-embeddingvision-transformerlabel-efficientcomputer-vision
arXivPDFCodeMarkdown21 min read
AI-compiled by claude-haiku-5-5 on 2026-10-18, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.
In plain words
Masked Siamese Networks teach a vision model to recognise a picture even when parts of it are hidden. The model never tries to draw the missing pixels. Instead it learns to give a partly hidden picture the same internal summary as the full one. The summary is measured against a set of learned reference points called prototypes. A second copy of the model, updated slowly, supplies the target summary. Training uses only unlabelled photos.
Because the hidden parts are dropped from the input, the masked version has fewer pieces to process, which keeps training cost down. The authors focus on the case where very few labelled examples are available: one to five per class. The representation they learn is meant to be adapted to that task with little labelled data.
TL;DR
MSN is a self-supervised pre-training method for Vision Transformers that does not reconstruct pixels. A masked view is trained to match the prototype assignments of an unmasked view, which comes from an EMA teacher. Unlike DINO, it needs no unmasked anchor view, so only the masked view's activations are kept for backpropagation. Author-reported: 72.4% top-1 with 5 labels per class and 75.7% with 1% of ImageNet labels, both for ViT-B/4. The paper and its code disagree on several details, listed under Paper vs code.
Problem
Self-supervised pre-training should give representations that work with few labels §1. Masked auto-encoders learn by reconstructing masked pixels or tokens. That objective needs low-level detail that classification does not need, so the features often have to be fine-tuned, and this can overfit in the low-shot regime §1. Joint-embedding methods avoid reconstruction and tend to give more semantic features, but they need views whose invariances are designed in advance and a mechanism to stop collapse §1, §2, §6. DINO-style methods also require an unmasked anchor view, which costs memory and compute §4. The paper's stated assumptions are a large unlabelled image set, a small labelled set that may overlap with it, and invariances defined by the chosen augmentations, which may depend on the dataset §2, §6.
Method
MSN builds on a siamese setup with a prototype-based objective §3. For each image, one target view is left unmasked. The anchor views are masked. The objective is to assign the anchor representation to the same prototypes as the target representation §3, Training Objective fig. 3.
- Views. Each image yields one target view and M ≥ 1 anchor views. The default is one large (224×224) anchor with a random mask and ten small focal anchors (96×96) §3, Input Views §5 app. A.1.
- Random masking. The masking drops a fraction of the global anchor's patches, so the encoder sees fewer tokens §3, Patchify and Mask app. A.1. The code keeps the CLS token and drops patches only in the first crop group deit.py.
- Focal masking. A focal anchor is a small crop. It is not patch-dropped. The authors use both random and focal views together, and combining them gives the best low-shot accuracy §5.4, Combining Random and Focal Masking tab. 7.
- Encoders. The anchor encoder is a ViT whose trainable weights are θ. The target encoder has the same architecture and its weights are an exponential moving average of the anchor's. The representation is the CLS token output §3, Encoder §2, Vision Transformer.
- Anchor predictions. Each anchor representation is L2-normalised and compared by cosine similarity with K learnable prototypes (K = 1024, dimension d = 256). The softmax temperature is τ = 0.1 §3, Similarity Metric and Predictions app. A.1.
- Target predictions. The same operation on the target view uses a sharper temperature τ⁺ = 0.025. Targets are computed without gradient. The paper requires τ⁺ < τ and states that training without sharpening can collapse §3, Similarity Metric and Predictions app. A.1.
- Sinkhorn normalisation. The targets are normalised with Sinkhorn over the batch. This is on by default, and the paper says it removes the need to tune the ME-max weight app. A.1 app. C.1 tab. 11.
- Loss. The loss is the average cross-entropy between each target distribution and each anchor distribution, minus λ times the entropy of the mean anchor prediction (ME-max). λ = 1.0 by default §3, Training Objective eq. 1 app. A.1.
- Gradients and updates. Gradients flow only through the anchor predictions, never through the targets §3, Training Objective. The anchor encoder and prototypes are trained with AdamW. The target encoder is updated by EMA with momentum m, which the paper says rises from 0.996 to 1.0 over training §3, Encoder app. A.1.
- Evaluation. The projection head is discarded at evaluation, and the target encoder's trunk representation is used app. A.1. See Pitfalls for what the code actually evaluates.
The paper gives a guarantee that the representations cannot collapse to a constant, under the assumption that the sharpened target is not uniform. It is stated in Proposition 1 app. B.
Prediction and objective equations, using the paper's notation. The prediction is not numbered in the paper. The objective is eq. 1:
p_{i,m} = \mathrm{softmax}\left(\frac{z_{i,m}\,\mathbf{q}}{\tau}\right), \qquad \bar{p} = \frac{1}{MB}\sum_{i=1}^{B}\sum_{m=1}^{M} p_{i,m}
Both are unnumbered in the paper; they are cited to §3, Similarity Metric and Predictions and §3, Training Objective.
\frac{1}{MB}\sum_{i=1}^{B}\sum_{m=1}^{M} H\left(p_i^{+},\, p_{i,m}\right) - \lambda\, H(\bar{p})
This is the only numbered equation, eq. 1 §3, Training Objective.
Pseudocode, written from the paper's description. The paper has no algorithm box. Where the official code differs, see Paper vs code.
# MSN pre-training step [§3] [app. A.1]
# Input: images (B, 3, 224, 224); prototypes (K, d), K = 1024, d = 256
# Output: scalar loss; updates to the anchor encoder and prototypes
def msn_step(images, anchor_encoder, target_encoder, prototypes):
# 1. One unmasked target and M anchor views per image [§3, Input Views]
# Default: one global anchor and ten focal anchors [§5] [app. A.1]
target_view = augment(images, size=224) # (B, 3, 224, 224)
global_anchor = augment(images, size=224) # (B, 3, 224, 224)
focal_anchors = [augment(images, size=96) for _ in range(10)]
# 2. Random mask on the global anchor only; drop a fraction of patches
# (0.15 ViT-S/16, 0.3 ViT-B/16 and B/8, 0.7 ViT-L/7 and B/4) [§3]
masked_global = drop_patches(global_anchor, ratio=mask_ratio)
# 3. Focal anchors are small crops, not patch-dropped [§3] [app. A.1]
# 4. Encode anchors with the trainable encoder; take CLS output [§3]
anchor_feats = anchor_encoder([masked_global] + focal_anchors)
# 5. Encode the unmasked target with the EMA encoder, without gradient [§3]
with no_grad:
target_feats = target_encoder(target_view) # (B, d)
# 6. Anchor predictions: cosine to prototypes, softmax at tau = 0.1
# [§3, Similarity Metric and Predictions] [app. A.1]
anchor_preds = softmax(
normalize(anchor_feats) @ normalize(prototypes).T / 0.1) # (B*M, K)
# 7. Target predictions: same similarity, sharper tau+ = 0.025, no gradient
# [§3] [app. A.1]
with no_grad:
target_preds = softmax(
normalize(target_feats) @ normalize(prototypes).T / 0.025)
# 8. Sinkhorn normalisation of the targets over the batch (default on)
# [app. A.1] [app. C.1]
target_preds = sinkhorn(target_preds) # (B, K)
# 9. Pair every anchor with its image's target; M = 11 by default [§3]
target_preds = tile(target_preds, times=M) # (B*M, K)
# 10. Cross-entropy between target and anchor distributions, averaged
# over anchors and images [§3, Training Objective] [eq. 1]
loss_ce = mean(-sum(target_preds * log(anchor_preds), dim=1))
# 11. ME-max: entropy of the mean anchor prediction, weight lambda = 1.0
# (subtracted; rewards using all prototypes) [§3] [app. A.1]
mean_preds = mean(anchor_preds, dim=0) # (K,)
entropy = -sum(mean_preds * log(mean_preds))
loss = loss_ce - 1.0 * entropy
# 12. AdamW update of anchor encoder and prototypes; no grad to targets
# [§3, Training Objective] [app. A.1]
adamw_step(loss, anchor_encoder.parameters() + [prototypes])
# 13. EMA update of the target encoder; momentum m rises from 0.996 to 1.0
# [§3, Encoder] [app. A.1]
for target_param, anchor_param in zip(target_encoder, anchor_encoder):
target_param.data = m * target_param.data + (1 - m) * anchor_param.data
return lossHyperparameters
Pre-training, with the official config for ViT-S/16 msn_vits16.yaml. Values not in the paper say so.
| Name | Value | Where | Notes |
|---|---|---|---|
| Optimizer | AdamW | app. A.1 msn_train.py | |
| Batch size | 1024 images per iteration | app. A.1 §5 | Config: 64 per process msn_vits16.yaml; README runs 2 nodes × 8 tasks = 16 processes README.md |
| Learning rate | linear warm-up 0.0002 → 0.001 over 15 epochs, then cosine | app. A.1 msn_vits16.yaml | Warm-up is per iteration in code msn_train.py |
| Final learning rate | not stated | msn_vits16.yaml | 1e-6 in config, used as the cosine floor utils.py |
| Pre-training epochs | 800 for ViT-S/16 | tab. 1 msn_vits16.yaml | tab. 3 lists 600 for the same architecture; see Pitfalls |
| Weight decay | 0.04 → 0.4, cosine | app. A.1 msn_vits16.yaml | Schedule horizon is 1.25 × epochs in code msn_train.py |
| Weight decay exclusions | not stated | msn_train.py | No decay on biases, norm layers and 1-d parameters; prototypes have decay 0 |
| Gradient clipping | not stated | msn_vits16.yaml msn_train.py | Norm 3.0 |
| EMA momentum (target) | 0.996 → 1.0, linear | app. A.1 msn_train.py | Code's end value is 0.9992; see Pitfalls |
| Anchor temperature τ | 0.1 | app. A.1 msn_vits16.yaml | |
| Target temperature τ⁺ | 0.025 | app. A.1 | Code sharpens by exponent 1/T with T = 0.25 on a τ = 0.1 softmax; same as τ⁺ = 0.1 × 0.25 losses.py msn_vits16.yaml |
| Prototypes K | 1024 | app. A.1 §5 msn_vits16.yaml | |
| Prototype dimension d | 256 | app. A.1 msn_vits16.yaml | Init uniform in ±1/√d, not stated in paper msn_train.py |
| Prototype learning | learnable | app. A.1 | |
| ME-max weight λ | 1.0 | app. A.1 msn_vits16.yaml | |
| Sinkhorn on targets | on | app. A.1 msn_vits16.yaml | Iterations not stated in paper; code uses 3 losses.py |
| Projection head | 3 linear layers, output 256, batch-norm at input and hidden layers | app. A.1 | Code: hidden width 2048, BN after the first two layers, none at input; see Paper vs code msn_train.py msn_vits16.yaml |
| Global anchor size | 224 × 224 | app. A.1 msn_vits16.yaml | |
| Focal anchors | 10 at 96 × 96 | §5 app. A.1 msn_vits16.yaml | |
| Random mask ratio (global anchor) | 0.15 ViT-S/16; 0.3 ViT-B/16 and ViT-B/8; 0.7 ViT-L/7 and ViT-B/4 | app. A.1 §5.4 msn_vits16.yaml | Only the ViT-S/16 value (0.15) is in the repository config. The ratio is model-dependent §5 |
| Augmentation, global | random resized crop (scale 0.3–1.0), horizontal flip, colour distortion, Gaussian blur | app. A.1 data_manager.py | The paper gives no crop scale. Code uses 0.3–1.0 |
| Augmentation, focal | random resized crop (scale 0.05–0.3), flip, colour distortion, blur | data_manager.py | Not in paper |
| Colour distortion | jitter strength s = 0.5: brightness/contrast/saturation 0.8·s, hue 0.2·s, applied with p = 0.8; grayscale p = 0.2 | msn_vits16.yaml data_manager.py | Not in paper |
| Gaussian blur | p = 0.5; radius 0.1–2.0 | data_manager.py | Not in paper |
| Drop path | not stated | msn_vits16.yaml | 0.0 in the config |
| Projection/loss modes | use_pred_head false; entropy term present with weight 0 | msn_vits16.yaml | The entropy term has no effect in this config |
Low-shot evaluation app. A.2:
| Name | Value | Where | Notes |
|---|---|---|---|
| Classifier | L2-regularised logistic regression on frozen features | app. A.2 | Solved with cyanure logistic_eval.py |
| Labelled data | 1, 2 or 5 images per class; 3 random splits | §5.1 tab. 1 | Splits are in imagenet_subsets1/2/3 README.md |
| Crop | single centre crop of each labelled image | app. A.2 | Code: resize 256, centre crop 224 logistic_eval.py |
| Regularisation λ | not stated | app. A.2 | Code default 0.00025, divided by the number of embeddings logistic_eval.py. README example uses 0.0025 README.md |
| Solver | cyanure, 10 initial iterations, tol 1e-3, up to 300 epochs | logistic_eval.py | Not in paper |
| Feature normalisation | cyanure preprocessing: normalise and centre | logistic_eval.py | Not in paper |
| Feature | CLS output of the last block; head removed | app. A.2 logistic_eval.py deit.py | No final LayerNorm is applied; see Pitfalls |
Linear evaluation, 100% labels app. A.3:
| Name | Value | Where | Notes |
|---|---|---|---|
| Batch size | 16,384 | app. A.3 | Code: 256 per process linear_eval.py. README uses 32 processes README.md. See Paper vs code |
| Epochs | 100 | app. A.3 lineval_msn_vits16.yaml | |
| Learning rate | 6.4, cosine, no warm-up | app. A.3 lineval_msn_vits16.yaml linear_eval.py | Warm-up epochs default to 0 |
| Optimizer | SGD with Nesterov | app. A.3 linear_eval.py | Momentum 0.9 is not in paper |
| Weight decay | 0 | app. A.3 lineval_msn_vits16.yaml | |
| Features | L2-normalised CLS output of the last block | app. A.3 linear_eval.py lineval_msn_vits16.yaml | No final LayerNorm; see Pitfalls |
| Augmentation | random resized crop 224 (scale 0.08–1.0 in code), horizontal flip | app. A.3 linear_eval.py | Scale not in paper |
Fine-tuning and transfer app. A.4, A.5. These protocols are not in this repository. The README points fine-tuning to the MAE codebase README.md.
| Name | Value | Where | Notes |
|---|---|---|---|
| Fine-tuning: optimizer and length | AdamW, 100 epochs, batch 1024, learning rate 0.002 | app. A.4 | |
| Fine-tuning: schedule | 5-epoch linear warm-up, cosine decay, layer-wise decay 0.65 | app. A.4 | |
| Fine-tuning: regularisation | RandAugment(9, 0.5), label smoothing 0.1, mixup 0.8, cutmix 1.0, drop path 0.2 | app. A.4 | |
| Transfer, linear | resize 256, centre crop 224, L2-regularised logistic regression | app. A.5.1 | |
| Transfer, fine-tuning on CIFAR-10/100 | 1000 epochs, batch 768, learning rate 0.000075 | app. A.5.2 | Drop path 0.1; label smoothing 0.1; mixup 0.8; cutmix 1.0 |
| Transfer, fine-tuning on iNat18/19 | 300 epochs, batch 1024, learning rate 0.0001 | app. A.5.2 | Same regularisation as above |
Results
Author-reported. Setup: pre-training on ImageNet-1K; ViT backbones (ViT-S, B and L with patch sizes 16, 8, 7 and 4); baselines are DINO, iBOT, MAE, BYOL, SimCLRv2, PAWS and MoCov3 as listed in each table §5. Evaluation protocols are in Hyperparameters.
Headline numbers. ViT-B/4 reaches 72.4% top-1 with 5 labels per class tab. 1 and 75.7% with 1% of labels, about 13 per class tab. 2 §5.1. The paper says the 1% result exceeds an 800M-parameter convolutional network, while the best published 1% number it cites (76.6%) comes from a multi-stage semi-supervised pipeline, not a self-supervised one §5.1.
tab. 1 Extreme low-shot, ImageNet-1K pre-training. Top-1 %, mean ± std over 3 splits, for 1, 2 and 5 labelled images per class.
| Method | Architecture | Epochs | 1 | 2 | 5 |
|---|---|---|---|---|---|
| iBOT | ViT-S/16 | 800 | 40.4 ± 0.5 | 50.8 ± 0.8 | 59.9 ± 0.2 |
| iBOT | ViT-B/16 | 400 | 46.1 ± 0.3 | 56.2 ± 0.7 | 64.7 ± 0.3 |
| DINO | ViT-S/16 | 800 | 38.9 ± 0.4 | 48.9 ± 0.3 | 58.5 ± 0.1 |
| DINO | ViT-B/16 | 400 | 41.8 ± 0.3 | 51.9 ± 0.6 | 61.4 ± 0.2 |
| DINO | ViT-S/8 | 800 | 45.5 ± 0.4 | 56.0 ± 0.7 | 64.7 ± 0.4 |
| DINO | ViT-B/8 | 300 | 45.8 ± 0.5 | 55.9 ± 0.6 | 64.6 ± 0.2 |
| MAE | ViT-B/16 | 1600 | 8.2 ± 0.3 | 25.0 ± 0.3 | 40.5 ± 0.2 |
| MAE | ViT-L/16 | 1600 | 12.3 ± 0.2 | 19.3 ± 1.8 | 42.3 ± 0.3 |
| MAE | ViT-H/14 | 1600 | 11.6 ± 0.4 | 18.6 ± 0.2 | 32.8 ± 0.2 |
| MSN (this paper) | ViT-S/16 | 800 | 47.1 ± 0.1 | 55.8 ± 0.6 | 62.8 ± 0.3 |
| MSN (this paper) | ViT-B/16 | 600 | 49.8 ± 0.2 | 58.9 ± 0.4 | 65.5 ± 0.3 |
| MSN (this paper) | ViT-B/8 | 600 | 55.1 ± 0.1 | 64.9 ± 0.7 | 71.6 ± 0.3 |
| MSN (this paper) | ViT-B/4 | 300 | 54.3 ± 0.4 | 64.6 ± 0.7 | 72.4 ± 0.3 |
| MSN (this paper) | ViT-L/7 | 200 | 57.1 ± 0.6 | 66.4 ± 0.6 | 72.1 ± 0.2 |
MAE uses partial fine-tuning except for the 1-image setting and ViT-H/14, which use a linear classifier §5.1 app. A.2.
tab. 2 Low-shot, 1% of ImageNet-1K labels (~13 per class). Top-1 %. † marks numbers the authors computed from public checkpoints.
| Method | Architecture | Params | Top-1 |
|---|---|---|---|
| Barlow Twins | RN50 | 24M | 55.0 |
| SimCLRv2 | RN50 | 24M | 57.9 |
| PAWS | RN50 | 24M | 66.5 |
| DINO | ViT-S/16 | 22M | 64.5 |
| iBOT | ViT-S/16 | 22M | 65.9 |
| MSN | ViT-S/16 | 22M | 67.2 |
| BYOL | RN200 (2×) | 250M | 71.2 |
| SimCLRv2 | RN151+SK (3×) | 795M | 74.9 |
| iBOT † | ViT-B/16 | 86M | 69.7 |
| DINO † | ViT-B/8 | 86M | 70.0 |
| MSN | ViT-L/7 | 304M | 75.1 |
| MSN | ViT-B/4 | 86M | 75.7 |
The footnote in §5.4 says the ViT-S/16 row removes Sinkhorn normalisation. Its value, 67.2, matches the no-Sinkhorn, λ = 5 row of tab. 11 app. C.1.
tab. 3 Linear evaluation, 100% of ImageNet-1K labels. Top-1 %.
| Method | Architecture | Params | Epochs | Top-1 |
|---|---|---|---|---|
| SimCLRv2 | RN50 | 24M | 800 | 71.7 |
| BYOL | RN50 | 24M | 1000 | 74.4 |
| DINO | ViT-S/16 | 22M | 800 | 77.0 |
| iBOT | ViT-S/16 | 22M | 800 | 77.9 |
| MSN | ViT-S/16 | 22M | 600 | 76.9 |
| MAE | ViT-H/14 | 632M | 1600 | 76.6 |
| BYOL | RN200 (2×) | 250M | 800 | 79.6 |
| SimCLRv2 | RN151+SK (3×) | 795M | 800 | 79.8 |
| iBOT | ViT-B/16 | 86M | 400 | 79.4 |
| DINO | ViT-B/8 | 86M | 300 | 80.1 |
| MoCov3 | ViT-BN-L/7 | 304M | 300 | 81.0 |
| MSN | ViT-L/7 | 304M | 200 | 80.7 |
tab. 4 End-to-end fine-tuning, ViT-B/16, 100% labels. Top-1 %. The MSN row's pretraining is 600 epochs.
| Initialisation | Pre-train epochs | Top-1 |
|---|---|---|
| DINO | 800 | 83.6 |
| BEiT | 800 | 83.2 |
| iBOT | 800 | 83.8 |
| MAE | 1600 | 83.6 |
| SimMIM | not stated | 83.8 |
| MaskFeat | not stated | 84.0 |
| Data2Vec | 800 | 84.2 |
| MSN | 600 | 83.4 |
tab. 5 Transfer, fine-tuning from ImageNet-1K ViT-B/16. Top-1 %. Masking ratio 0.3 tab. 5 caption.
| Method | CIFAR-10 | CIFAR-100 | iNat18 | iNat19 |
|---|---|---|---|---|
| DINO | 99.0 | 90.5 | 72.0 | 78.2 |
| MSN | 99.0 | 90.5 | 72.1 | 78.1 |
tab. 6 Transfer, linear evaluation, ViT-B/16. Top-1 %.
| Method | CIFAR-10 (4000 labels) | CIFAR-10 (50000 labels) | CIFAR-100 |
|---|---|---|---|
| DINO | 93.2 | 95.3 | 82.9 |
| MSN | 93.8 | 95.7 | 82.8 |
tab. 7 Masking strategy, ViT-B/16, 1% of labels. Top-1 %. The last row uses two anchors, one random and one focal.
| Anchor view | Top-1 |
|---|---|
| No mask | 49.3 |
| Focal mask | 39.3 |
| Random mask (ratio 0.5) | 52.3 |
| Random + focal | 59.8 |
tab. 8 Random masking ratio, 1% of labels. Top-1 %. Ratios are fractions of dropped patches.
| Architecture | 0.15 | 0.3 | 0.5 | 0.7 |
|---|---|---|---|---|
| ViT-S/16 | 66.3 | 66.0 | 64.8 | – |
| ViT-B/16 | 68.8 | 69.6 | – | – |
| ViT-L/16 | NaN | NaN | 70.1 | 69.4 |
tab. 9 Augmentation and view invariance, ViT-B/16, 1% of labels. Top-1 %.
| Anchor view | Top-1 |
|---|---|
| Target view only (shared view) | 7.0 |
| Target view + colour jitter | 48.7 |
| Target view + colour jitter + crop + flip + blur | 52.3 |
The text gives 48.3% for the second row. See Pitfalls.
tab. 10 Compute, ViT-L/7 pre-training. Single p4d-24xlarge (8 A100 GPUs), batch 2 per GPU.
| Masking ratio | Memory per GPU | Throughput |
|---|---|---|
| 0.0 | 26 GB | 415 img/s |
| 0.3 | 21 GB | 480 img/s |
| 0.5 | 18 GB | 525 img/s |
| 0.7 | 17 GB | 600 img/s |
tab. 11 Sinkhorn normalisation, ViT-S/16, masking 0.15, 1% of labels. Top-1 %.
| Target normalisation | ME-max λ | Top-1 |
|---|---|---|
| Sinkhorn | 1.0 | 66.4 |
| None | 1.0 | 60.8 |
| None | 5.0 | 67.2 |
tab. 12 Number of prototypes, ViT-B/16, masking 0.3, 1% of labels. Top-1 %.
| Prototypes | Top-1 |
|---|---|
| 512 | 67.6 |
| 1024 | 69.5 |
| 2048 | 69.5 |
tab. 13 MAE low-shot protocols, ImageNet-1K. Top-1 %. The paper marks the ViT-H/14 partial fine-tuning row as "rand". It has no value.
| Architecture | Protocol | 2 per class | 5 per class | ~13 per class |
|---|---|---|---|---|
| ViT-B/16 | Partial fine-tuning | 25.0 | 40.5 | 51.1 |
| ViT-B/16 | Linear | 14.5 | 25.2 | 36.6 |
| ViT-L/16 | Partial fine-tuning | 19.3 | 42.3 | 59.4 |
| ViT-L/16 | Linear | 22.1 | 35.7 | 48.6 |
| ViT-H/14 | Partial fine-tuning | rand | rand | rand |
| ViT-H/14 | Linear | 18.6 | 32.8 | 46.7 |
tab. 14 Alternative ImageNet validation sets, fine-tuned ViT-B/16 app. D. Higher is better for A, R and Sketch (top-1 %). Lower is better for C (mean corruption error).
| Method | IN-A | IN-R | IN-Sketch | IN-C (mCE) |
|---|---|---|---|---|
| Supervised ResNet-50 | 0.04 | 36.11 | 24.2 | 76.7 |
| MAE ViT-B/16 | 35.9 | 48.3 | 34.5 | 51.7 |
| MSN ViT-B/16 | 37.5 | 50.0 | 36.3 | 46.6 |
tab. 15 Robustness to missing patches at evaluation, 1% of labels. Top-1 %. app. E
| Method | Pre-train masking | Eval masking 0.0 | Eval masking 0.7 | Δ |
|---|---|---|---|---|
| DINO ViT-B/16 | 0.0 | 67.0 | 63.1 | −3.9 |
| MSN ViT-B/16 | 0.3 | 69.5 | 67.1 | −2.4 |
| MSN ViT-L/7 | 0.7 | 75.1 | 74.9 | −0.2 |
tab. 16 Cosine similarity between representations of masked and unmasked views, ImageNet-1K validation. app. E
| Method | 0.15 | 0.3 | 0.5 | 0.7 | 0.9 |
|---|---|---|---|---|---|
| DINO ViT-B/16 | 0.98 | 0.97 | 0.92 | 0.81 | 0.56 |
| MSN ViT-B/16 (pre-train 0.3) | 0.99 | 0.99 | 0.99 | 0.98 | 0.97 |
Figures are described in the paper, not reproduced here. fig. 1 has two panels: at 1% of labels, frozen-feature and fine-tuning results; and low-shot results comparing MSN ViT-L/7 with DINO ViT-B/8 and MAE ViT-L/16. fig. 2 shows samples from a generative model conditioned on MSN representations §1. fig. 3 is the method schematic and fig. 4 the masking strategies §3. fig. 5–fig. 9 compare MSN and DINO representations under masking app. F.
Paper vs code
Official code: github.com/facebookresearch/msn, at commit 4388dc1eadbe3042b85d3296d41b9b207656e043. It is linked in the abstract, and its owner is facebookresearch, the organisation the authors belong to. Code licence: CC BY-NC 4.0, non-commercial. The paper itself is CC BY 4.0, so its text and tables can be reused with attribution. The code cannot be reused commercially, so this card cites it by path and line only and quotes no code.
- Loss placement and evaluation feature. The paper says the loss applies to the encoder's CLS output and that the projection head is discarded at evaluation §3, Encoder app. A.1. In the code, the MLP head sits inside the ViT's feature function, so both anchor and target losses use the MLP output deit.py msn_train.py. The code comment calls
h"before the head" msn_train.py, but on this pathhis already after the MLP. Evaluation uses the CLS output of the last block, with no final LayerNorm and no head deit.py linear_eval.py logistic_eval.py. - Projection head batch-norm. The paper says batch-norm at "the input and hidden layers" app. A.1. The code has linear → BN → GELU → linear → BN → GELU → linear, with no BN before the first linear. Hidden width is 2048 msn_train.py msn_vits16.yaml.
- Target temperature. The paper gives τ⁺ = 0.025 app. A.1. The code uses τ = 0.1 and raises the softmax to 1/T with T = 0.25 msn_vits16.yaml losses.py. Both give the same target distribution, because softmax(s/0.1)^4 normalises to softmax(s/0.025). The sharpening schedule starts and ends at 0.25, so it is constant msn_train.py.
- Schedules. The paper says the EMA momentum reaches 1.0 at the end of training app. A.1. The code increments it over 1.25 × the total steps and stops at 0.9992 msn_train.py. The learning-rate and weight-decay cosine schedules use the same 1.25 × horizon msn_train.py utils.py utils.py.
- Pre-training batch. The paper's 1024 is the total batch app. A.1. The config has 64 per process msn_vits16.yaml and the README runs 16 processes README.md. These agree only if each process is one GPU.
- Linear-evaluation batch. The paper gives 16,384 app. A.3. The code uses 256 per process linear_eval.py. The README runs 4 × 8 = 32 processes README.md, which gives 8,192 if each is one GPU. The two do not agree.
- Logistic regression λ. The paper gives no value app. A.2. The code default is 0.00025, divided by the number of embeddings logistic_eval.py. The README example uses 0.0025, ten times the default README.md.
- ViT-S/16 pre-training epochs. tab. 1 says 800; tab. 3 says 600 for the same model. The config uses 800 msn_vits16.yaml. The README's checkpoint is named
vits16_800epREADME.md. - Repository coverage. The repository has one pre-training config, for ViT-S/16 . There are no configs for ViT-B/16, B/8, B/4 or L/7, though
deit_small_p7exists deit.py. Fine-tuning and transfer are not in this repository README.md. The robustness and diffusion visualisations are not in it either. - Augmentation details. The code fixes crop scales, colour-jitter strength (0.5), probabilities and blur radius data_manager.py msn_vits16.yaml. The paper gives none of these app. A.1.
- Sinkhorn iterations. The paper does not state the count. The code uses 3 losses.py.
- Patch dropping. Only the first crop group is patch-dropped, which is the 224 global anchor. The focal crops are not deit.py deit.py. This matches app. A.1, but implementers who drop patches on every view will differ from the code.
- Other code-only details. Prototypes start uniform in ±1/√256 msn_train.py. Norm-layer and bias weights get no decay msn_train.py. Gradient norm is clipped at 3.0 msn_train.py. The final learning-rate floor is 1e-6 msn_vits16.yaml. SyncBatchNorm is used across processes msn_train.py. None of these are in the paper.
- Released checkpoints. The README links checkpoints for ViT-S/16 (800 epochs), ViT-B/16 (600), ViT-L/16 (600), ViT-B/4 (300) and ViT-L/7 (200) README.md. The repository states no licence for them beyond the code's.
No discrepancies were found in the target and anchor encoder roles, the 1024 prototypes of dimension 256, the anchor temperature 0.1, the ME-max weight 1.0, the AdamW optimiser, the warm-up of 15 epochs, the weight-decay range 0.04 → 0.4, or the one-random-plus-ten-focal anchor layout.
Pitfalls
- Which feature is evaluated. The paper says the trunk output is used app. A.1. The code evaluates the last block's CLS output without the final LayerNorm, and pre-trains the loss on the head's output. An implementation that uses the head output for evaluation, or applies the LayerNorm, will not match the reported numbers. The paper does not say which it used. Read deit.py and msn_train.py before choosing.
- Head batch-norm placement. BN before the first linear layer is in the paper's description app. A.1 and absent from the code msn_train.py. Hidden width 2048 is not stated in the paper.
- Sinkhorn is global. Sinkhorn runs over the batch on every process, with the global batch size, using all-reduce losses.py losses.py. The targets therefore depend on the GPU count. The ME-max average is also all-reduced losses.py.
- Sinkhorn is not always on. The footnote in §5.4 says the ViT-S/16 row of tab. 2 removes Sinkhorn. The 67.2 value matches the no-Sinkhorn, λ = 5 row of tab. 11. With Sinkhorn and λ = 1.0, the same model gives 66.4 app. C.1. The config has Sinkhorn on msn_vits16.yaml.
- Schedules are longer than the run. The momentum, learning-rate and weight-decay schedules are all built over 1.25 × the epochs msn_train.py. Momentum ends at 0.9992, not 1.0. The learning rate is still about 0.1 × peak at the last step for the 800-epoch config. This is my arithmetic from the schedule formula utils.py.
- Entropy term is inert.
use_entis true, butent_weightis 0.0 msn_vits16.yaml msn_train.py. Do not add an entropy term with non-zero weight unless the paper's objective calls for it. The paper's objective has none eq. 1. - Target encoder mode and buffers. The EMA update covers parameters only msn_train.py. The target's batch-norm running statistics are not averaged.
msn_train.pynever calls.eval(), so the target encoder runs in training mode with batch statistics. This is the code's behaviour, not a stated design. - Collapse. app. B proves the no-collapse property only when the sharpened target is not uniform. The paper says that without sharpening it observed collapse §3, Similarity Metric and Predictions. Keep the sharpening even when the batch looks healthy.
- Text and table disagree on the augmentation ablation. The text says 48.3% for colour jitter alone §5.4. tab. 9 says 48.7.
- Epoch counts disagree. ViT-S/16 is 800 epochs in tab. 1 and 600 in tab. 3. Use the config's 800 unless you are reproducing the linear-evaluation row.
- Masking ratio and stability. The paper's ratios are model-specific: 0.15 for ViT-S/16, 0.3 for ViT-B/16 and ViT-B/8, and 0.7 for ViT-L/7 and ViT-B/4 app. A.1. The ablation shows ViT-L/16 at 0.15 and 0.3 gives NaN tab. 8, and the text says those weak-masking runs are unstable §5.4. Use the model-specific ratio.
- Compute claim. The paper says masking 70% "uses half the computation and memory" §1. tab. 10 shows memory falling from 26 GB to 17 GB and throughput rising from 415 to 600 img/s. That is not a halving, and the table does not measure compute directly.
- Scale claims. Pre-training ViT-L/7 needs 18 p4d.24xlarge machines with 70% masking, against more than 42 without masking §1 §5.4. These are the authors' figures.
- Baseline numbers are re-evaluations. The DINO and iBOT ViT-B rows in tab. 2 are marked † because the authors computed them from public checkpoints tab. 2 caption.
- Citation slip. In the source, the iBOT row of tab. 4 cites the MAE reference. Check the iBOT reference before citing that row.
- Placeholder. The ViT-H/14 partial-fine-tuning row in tab. 13 reads "rand" and has no value.
- Unstated values. Projection-head width, drop path, final learning rate, gradient clipping, weight-decay exclusions, prototype initialisation, Sinkhorn iterations and all augmentation strengths are not in the paper. Taking them from the code is the only way to match the reported setup, and this card shows them with their source.
- Licence. The code is non-commercial LICENSE. The paper is CC BY 4.0. Implement from the paper and this card, and do not copy code from the repository into commercial work.
Lineage
- Builds on: DINO (Caron et al., ICCV 2021, "Emerging properties in self-supervised vision transformers"). MSN extends it with random and focal masking and drops the requirement for an unmasked anchor view §4. There is no arXiv id in the paper's bibliography, so none is given here. The clustering-based SSL line (SwAV, PAWS) gives the prototype-and-Sinkhorn machinery §3 app. A.1. The EMA target follows BYOL §3, Encoder app. A.1.
- Compared against: iBOT, MAE, DINO, BYOL, SimCLRv2, PAWS, MoCov3, BEiT, SimMIM, MaskFeat, Data2Vec (arXiv:2202.03555) tab. 1–4.
Source and license
Adapted from “Masked Siamese Networks for Label-Efficient Learning” by Mahmoud Assran, Mathilde Caron, Ishan Misra, Piotr Bojanowski, Florian Bordes, Pascal Vincent, Armand Joulin, Michael Rabbat, Nicolas Ballas (arXiv:2204.07141), 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/facebookresearch/msn at commit 4388dc1eadbe (CC BY-NC 4.0 (non-commercial)). Any quoted code is shown under that license.