Paper · 2021-04-20 · cs.LG, stat.ML
Gradient Matching for Domain Generalization
Fish approximates an inter-domain gradient matching objective (IDGM) with a first-order update. Each meta-step takes one plain gradient step on a clone of the model for every training domain, then moves the weights toward the clone. Author-reported: best on 4 of 6 Wilds datasets, 67.1% average on DomainBed (Coral 67.2%, ERM 67.0%).
Domain generalizationInvariant learningMeta-learningdomain-generalizationinvariant-learninggradient-alignmentmeta-learningout-of-distributionbenchmark
arXivPDFCodeMarkdown21 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 model trained on data from several sources often learns shortcuts. In one toy example it leans on a feature that looks reliable inside each source but means something different in the next one. The paper asks for a different signal: the weights should move in a direction that helps every source at the same time. If the gradients from the different sources point the same way, a step on one of them also helps the others, so the feature it learns is probably a real one.
The direct way to reward this needs second-order derivatives, which are slow to compute. The method, Fish, gets close to the same effect with a cheap procedure. It starts from the current weights, makes a copy, and trains the copy briefly on one batch from each source in turn. It then moves the real weights part of the way toward that copy. The copy's path is pulled toward the directions the sources share, so the update works like the direct objective without computing it.
The authors test this on classification and regression tasks with distribution shift, including a benchmark of real-world shifts and a benchmark with synthetic-to-real shifts. The method is competitive and wins on several of the tasks, and it does not win everywhere.
TL;DR
- Fish is a first-order approximation of inter-domain gradient matching: it maximises the inner product of gradients from different training domains without computing second derivatives §3.4 app. A.
- One meta-step runs S plain gradient updates on a copy of the model, one per training domain, then applies θ ← θ + ε(θ̃ − θ) alg. 1.
- Author-reported: Fish is the best of the compared methods on Poverty, Camelyon17, FMoW and CivilComments, and roughly tied on Amazon and iWildCam §4.2 tab. 3; on DomainBed it is second of ten by average accuracy, 0.1 points below Coral §4.3 tab. 4.
- The official code (MIT) implements Fish and ERM only; the direct IDGM objective, SmoothFish and the DomainBed runs are not in that repository main.py README.md.
- Two main-text results tables disagree with the per-dataset appendix tables for the same method (see Pitfalls), so check the numbers against the table you use.
Problem
Empirical risk minimisation (ERM) minimises the average loss over the training domains and ignores how the domains differ. It can therefore lock onto features that predict the label in the training domains but not in a new one §3.1 §2. The paper's toy example shows this: a feature that is only correlated with the label within the training domains gives ERM 97% training accuracy and 57% test accuracy, while the invariant feature alone gives 93% on both tab. 1 §3.2.
Prior invariance methods either enforce a hard constraint on the features (IRM, domain-adversarial training, CORAL, MMD) or minimise the variance of the gradients across domains (IGA). The authors argue that IGA behaves like ERM when ERM is already optimal on every domain, so it can fail in the same way §2. The paper's target is a method that prefers non-ERM solutions whenever the domain gradients agree, and that is cheap enough to run on large models.
Method
Setup and goal
There are S training domains, each a set of i.i.d. samples, and T test domains disjoint from them. The goal is a parameter vector θ with low expected loss on the unseen test domains §3.1, eq. 1:
\arg\min_{\theta} \; \mathbb{E}_{\mathcal{D} \sim \mathcal{D}_{te}} \mathbb{E}_{(x,y) \sim \mathcal{D}} \big[ \ell((x,y); \theta) \big] \qquad [\text{eq. 1}]
ERM minimises the average over the training domains §3.1, eq. 2:
\mathcal{L}_{erm}(\mathcal{D}_{tr}; \theta) = \mathbb{E}_{\mathcal{D} \sim \mathcal{D}_{tr}} \mathbb{E}_{(x,y) \sim \mathcal{D}} \big[ \ell((x,y); \theta) \big] \qquad [\text{eq. 2}]
Inter-domain gradient matching (IDGM)
Let G_s be the expected gradient of the loss on domain s §3.3, eq. 3. The gradient inner product (GIP) is the average over all pairs of distinct domains of G_i · G_j. The IDGM objective subtracts γ times the GIP from the ERM loss §3.3, eq. 4:
\mathcal{L}_{idgm} = \mathcal{L}_{erm}(\mathcal{D}_{tr}; \theta) - \gamma \, \frac{2}{S(S-1)} \sum_{i \ne j} G_i \cdot G_j \qquad [\text{eq. 4}]
Here G_i is the expected gradient on domain i §3.3, eq. 3. The paper notes that the sum of pairwise products can be computed in linear time from the sum of the gradients and their squared norms, up to a constant §3.3. For direct IDGM the paper uses a normalised GIP to avoid exploding gradients §3.2 §4.1; when it tracks the GIP it defines the normalised form as cosine similarity app. G.
The direct optimiser needs the gradient of the GIP with respect to θ, which is second order. Algorithm 2 shows that optimiser alg. 2.
# Direct IDGM step [alg. 2]
# Input: per-domain minibatches; learning rate eps; weight gamma
# Output: updated weights
def idgm_step(model, batches, eps, gamma):
# Gradient of each domain's minibatch loss at the current weights [alg. 2 l. 2-4]
grads = [gradient(loss(model, b), model) for b in batches]
# Average gradient, the ERM part [alg. 2 l. 8]
mean_grad = average(grads)
# Gradient inner product over all pairs of different domains [alg. 2 l. 8]
gip = pairwise_inner_product_mean(grads)
# Second-order term: gradient of the GIP with respect to the weights [alg. 2 l. 8]
gip_grad = gradient(gip, model)
# Descend on ERM and ascend on the GIP [alg. 2 l. 8]
model = model - eps * (mean_grad - gamma * gip_grad)
return modelFish: a first-order approximation
Fish runs an inner loop over the domains on a copy of the weights, then moves the original weights toward the copy alg. 1. The inner loop visits every training domain once, in a random order alg. 1 l. 3.
# Fish [alg. 1]
# Input: domains D_1..D_S; inner rate alpha; outer rate eps; iterations
# Output: trained weights theta
def fish_train(model, domains, alpha, eps, iterations):
# Repeat the outer loop [alg. 1 l. 1]
for step in range(iterations):
# Clone the current weights to start the inner loop [alg. 1 l. 2]
inner = copy(model)
# Visit every domain once, in random order [alg. 1 l. 3]
for domain in permute(domains):
# Draw one minibatch from this domain [alg. 1 l. 4]
batch = sample_batch(domain)
# One plain gradient step on the clone [alg. 1 l. 5-6]
grad = gradient(loss(inner, batch), inner)
inner = inner - alpha * grad
# Move the original weights toward the clone [alg. 1 l. 8]
model = model + eps * (inner - model)
return modelInside the inner loop, gradients are taken at the clone's weights rather than at θ. A Taylor expansion of the Fish update shows that, once the scaled ERM gradient is removed, what remains points in the same direction as the GIP gradient. This is the theorem in §3.4, with the proof in app. A. It is a limit as α → 0; the paper gives no bound at the α values it uses.
The difference from Reptile is which batches go into the inner loop. Reptile uses minibatches from one task, which encourages agreement within a task. Fish takes one minibatch from each training domain, which encourages agreement across domains §3.4 app. A.1.
SmoothFish (optional variant)
Fish gives no direct control over the strength of the GIP term. SmoothFish adds a coefficient γ on the difference between the Fish step and the scaled ERM step app. B. With γ = 1 it is Fish, and with γ = 0 it is ERM with learning rate αS app. B. The paper says γ made little difference in its experiments §3.4 app. B.
Hyperparameters
Paper: ERM baseline tab. 13
| Dataset | Model | Learning rate | Batch size | Weight decay | Optimizer | Val. metric | Cut-off |
|---|---|---|---|---|---|---|---|
| Camelyon17 | DenseNet-121 | 1e-3 | 32 | 0 | SGD | acc. avg. | iter 500 |
| CivilComments | BERT | 1e-5 | 16 | 0.01 | Adam | acc. wg. | best val. metric |
| FMoW | DenseNet-121 | 1e-4 | 64 | 0 | Adam | acc. avg. | best val. metric |
| iWildCam | ResNet-50 | 1e-4 | 16 | 0 | Adam | F1-macro (all) | best val. metric |
| Poverty | ResNet-18 | 1e-3 | 64 | 0 | Adam | Pearson (r) | - |
| Amazon | BERT | 2e-6 | 8 | 0.01 | Adam | 10th percentile acc. | - |
Source: app. D, tab. 13. The paper says the same ERM settings were used to make the Fish pretrained models. Poverty was not pretrained app. D, tab. 13.
Paper: Fish tab. 14
Fish uses the same model, batch size, validation metric and optimiser as ERM, and weight decay is always 0 app. D, tab. 14.
| Dataset | Group by | α (inner) | ε (outer) | # domains | Meta steps |
|---|---|---|---|---|---|
| Camelyon17 | Hospitals | 1e-3 | 0.01 | 3 | 3 |
| CivilComments | Demographics × toxicity | 1e-5 | 0.05 | 16 | 5 |
| FMoW | time × regions | 1e-4 | 0.01 | 80 | 5 |
| iWildCam | Trap locations | 1e-4 | 0.01 | 324 | 10 |
| Poverty | Countries | 1e-3 | 0.1 | 23 | 5 |
| Amazon | Reviewers | 2e-6 | 0.01 | 7,676 | 5 |
Source: app. D, tab. 14. The meta-steps column is the number of domains sampled per inner loop; the paper's Amazon row lists 7,676 domains while the text uses S = 5008 for the training split app. C.6.
Paper: CdSprites-N
The paper gives no separate Fish table for CdSprites-N. It tests N from 5 to 50 and uses the normalised GIP for direct IDGM §4.1. The code configuration for CdSprites is in the next subsection.
Code configuration (official repository)
Values from src/config.py; these are the defaults that main.py loads for each
dataset. Effective outer step = meta_lr / meta_steps (see Paper vs code).
| Dataset | Optimiser | lr | Batch | Weight decay | Epochs | ERM pretrain iters | meta_lr | meta_steps | Selection metric | Reload inner optimiser |
|---|---|---|---|---|---|---|---|---|---|---|
| fmow | Adam (amsgrad) | 1e-4 | 64 | 0 | 12 | 24000 | 0.01 | 5 | acc_worst_region | yes |
| camelyon | SGD (momentum 0.9) | 1e-4 | 32 | 0 | 20 | 10000 | 0.01 | 3 | acc_avg | yes |
| poverty | Adam (amsgrad) | 1e-3 | 64 | 0 | 200 | 0 | 0.1 | 5 | r_wg | yes |
| iwildcam | Adam (amsgrad) | 1e-4 | 16 | 0.0 | 18 | 24000 | 0.01 | 10 | F1-macro_all | yes |
| amazon | Adam (amsgrad) | 2e-6 | 8 | 0 | 3 | 31000 | 0.01 | 5 | 10th_percentile_acc | yes |
| civil | Adam (amsgrad) | 1e-5 | 16 | 0 | 5 | 20000 | 0.05 | 5 | acc_wg | yes |
| cdsprites | Adam (amsgrad) | 1e-3 | 64 | 0 | 100 | 0 | 0.15 | 15 | acc_avg | no |
Source: config.py. CdSprites uses num_domains = 15 by
default config.py and --num-domains on the command line
main.py.
Results
All numbers are author-reported. Each row names its setup. Std values are as printed.
Toy linear example tab. 1
Two training domains, one test domain, four binary features; linear model.
| Method | Train acc. | Test acc. | W | b |
|---|---|---|---|---|
| ERM | 97% | 57% | [2.8, 3.3, 3.3, 0.0] | -2.7 |
| IDGM | 93% | 93% | [0.4, 0.2, 0.2, 0.0] | -0.4 |
| Fish | 93% | 93% | [0.4, 0.2, 0.2, 0.0] | -0.4 |
Source: §3.2 tab. 1. The data layout is in fig. 2.
CdSprites-N §4.1 fig. 4
Shape classification with N domains, each with a fixed shape-colour pairing that changes at test time. Five runs. The paper reports:
- Train accuracy is 100% for all methods at every N.
- Fish and direct IDGM exceed 90% test accuracy for N ≥ 10 and reach nearly 100% for N ≥ 20.
- ERM stays near chance until N = 20 and reaches 95% only for N ≥ 40.
- The text says Fish is about 10 times faster than direct IDGM §4.1. No table or timing figure backs this; it is a claim in the text.
Wilds benchmark §4.2 tab. 2 tab. 3
Six Wilds datasets (Wilds v1, per app. C), same learning rates, batch sizes, architectures and model selection as the Wilds baselines §4.2. Metrics follow Wilds. All runs use 3 seeds except Camelyon17 with 10 §4.2.
Table 2, dataset summary tab. 2:
| Dataset | Domains | Metric | Disjoint | Architecture | # Train |
|---|---|---|---|---|---|
| Poverty | 23 countries | Pearson (r) | yes | ResNet-18 | 10,000 |
| Camelyon17 | 5 hospitals | Avg. acc. | yes | DenseNet-121 | 302,436 |
| FMoW | 16 years × 5 regions | Avg. & worst group acc. | yes | DenseNet-121 | 76,863 |
| CivilComments | 8 demographic groups | Worst group acc. | no | BERT | 269,038 |
| iWildCam | 324 locations | Macro F1 | yes | ResNet-50 | 142,202 |
| Amazon | 7,676 reviewers | 10th percentile acc. | yes | BERT | 1,000,124 |
Table 3, main results tab. 3 (test set; bold marks the paper's best per column):
| Method | Poverty (Pearson r) | Camelyon17 (avg. acc. %) | FMoW (worst acc. %) | CivilComments (worst acc. %) | iWildCam (macro F1) | Amazon (10th pct. acc. %) |
|---|---|---|---|---|---|---|
| Fish | 0.80 ± 1e-2 | 74.7 ± 7e-2 | 34.6 ± 0.00 | 72.8 ± 0.0 | 22.0 ± 0.0 | 53.3 ± 0.0 |
| IRM | 0.78 ± 3e-2 | 64.2 ± 8.1 | 33.5 ± 1.35 | 66.3 ± 2.1 | 15.1 ± 4.9 | 52.4 ± 0.8 |
| Coral | 0.77 ± 5e-2 | 59.5 ± 7.7 | 31.0 ± 0.35 | 65.6 ± 1.3 | 32.8 ± 0.1 | 52.9 ± 0.8 |
| Reweighted | - | - | - | 66.2 ± 1.2 | - | 52.4 ± 0.8 |
| GroupDRO | 0.78 ± 5e-2 | 68.4 ± 7.3 | 31.4 ± 2.10 | 69.1 ± 1.8 | 23.9 ± 2.1 | 53.5 ± 0.0 |
| ERM | 0.78 ± 3e-2 | 70.3 ± 6.4 | 32.8 ± 0.45 | 56.0 ± 3.6 | 31.0 ± 1.3 | 53.8 ± 0.8 |
| ERM (ours) | 0.77 ± 5e-2 | 70.5 ± 12.1 | 30.9 ± 1.53 | 58.1 ± 1.7 | 25.1 ± 0.2 | 53.3 ± 0.8 |
Source: §4.2 tab. 3. The paper says Fish is best on four datasets and close to the best on Amazon and iWildCam §4.2.
Per-dataset appendix results app. C.1–C.6. These are the numbers the appendix gives for the same test sets. They differ from tab. 3 (see Pitfalls).
Poverty tab. 7, validation / test Pearson r: Fish 0.81 ± 6e-3 / 0.81 ± 9e-3; IRM 0.81 ± 4e-2 / 0.78 ± 3e-2; ERM 0.80 ± 3e-2 / 0.78 ± 3e-2; ERM (ours) 0.80 ± 3e-2 / 0.77 ± 5e-2; Coral 0.80 ± 4e-2 / 0.77 ± 5e-2 app. C.1.
Camelyon17 tab. 8, validation / test avg. acc. %: Fish 82.5 ± 1.2 / 79.5 ± 6.0; ERM 84.3 ± 2.1 / 73.3 ± 9.9; ERM (ours) 84.1 ± 2.4 / 70.5 ± 12.1; IRM 86.2 ± 2.1 / 60.9 ± 15.3; Coral 86.3 ± 2.2 / 59.2 ± 15.1 app. C.2.
FMoW tab. 9, validation / test, avg. and worst %:
| Method | Val avg. | Val worst | Test avg. | Test worst |
|---|---|---|---|---|
| Fish | 57.3 ± 0.01 | 49.5 ± 0.44 | 51.8 ± 0.12 | 34.3 ± 0.61 |
| ERM | 59.7 ± 0.14 | 48.2 ± 2.05 | 53.1 ± 0.25 | 31.7 ± 1.01 |
| ERM (ours) | 59.9 ± 0.22 | 47.1 ± 1.21 | 52.9 ± 0.18 | 30.9 ± 1.53 |
| IRM | 57.2 ± 0.01 | 47.4 ± 2.36 | 50.9 ± 0.32 | 31.0 ± 1.15 |
| Coral | 56.7 ± 0.06 | 46.8 ± 1.18 | 50.5 ± 0.30 | 30.5 ± 0.70 |
Source: app. C.3.
CivilComments tab. 10, validation / test, avg. and worst %:
| Method | Val avg. | Val worst | Test avg. | Test worst |
|---|---|---|---|---|
| Fish | 91.8 ± 0.2 | 75.3 ± 0.3 | 91.4 ± 0.3 | 74.2 ± 0.5 |
| Group DRO | 89.6 ± 0.3 | 68.7 ± 1.0 | 89.4 ± 0.3 | 70.4 ± 2.1 |
| Reweighted | 89.1 ± 0.3 | 67.9 ± 1.2 | 88.9 ± 0.3 | 67.3 ± 0.1 |
| ERM | 92.3 ± 0.6 | 53.6 ± 0.7 | 92.2 ± 0.6 | 58.0 ± 1.2 |
| ERM (ours) | 92.1 ± 0.5 | 54.1 ± 0.4 | 92.5 ± 0.3 | 58.1 ± 1.7 |
Source: app. C.4.
iWildCam tab. 11, validation / test (accuracy, weighted F1, macro F1):
| Method | Val acc. | Val F1-w | Val F1-m | Test acc. | Test F1-w | Test F1-m |
|---|---|---|---|---|---|---|
| Fish | 58.0 ± 0.2 | 56.5 ± 0.3 | 25.8 ± 0.5 | 63.2 ± 0.7 | 64.0 ± 0.5 | 24.2 ± 0.9 |
| Coral | - | - | - | 62.5 ± 1.7 | - | 26.3 ± 1.4 |
| ERM | - | - | - | 62.9 ± 0.5 | - | 27.8 ± 1.3 |
| ERM (ours) | 55.8 ± 0.2 | 54.6 ± 0.5 | 27.7 ± 1 | 63.0 ± 0.6 | 62.4 ± 0.2 | 25.1 ± 0.2 |
Source: app. C.5.
Amazon tab. 12, validation / test, average and 10th-percentile %: Fish 73.8 ± 0.1 / 57.3 ± 0.0 (val) and 72.9 ± 0.2 / 56.0 ± 0.0 (test); ERM 74.3 ± 0.0 / 57.3 ± 0.0 and 73.5 ± 0.1 / 56.0 ± 0.0; ERM (ours) 74.0 ± 0.0 / 57.3 ± 0.0 and 73.3 ± 0.1 / 56.0 ± 0.0; IRM 73.6 ± 0.2 / 56.4 ± 0.8 and 73.3 ± 0.2 / 55.1 ± 0.8; Reweighted 69.6 ± 0.0 / 53.3 ± 0.0 and 69.2 ± 0.1 / 52.4 ± 0.8 app. C.6.
The paper's reading: on iWildCam the ERM baseline is best on the primary metric, and on Amazon Fish and ERM are level or ERM is slightly ahead. The paper attributes the weak domain-generalisation results on these two datasets to the large number of domains (324 and 7,676) §4.2.
DomainBed §4.3 tab. 4
Seven DomainBed datasets, 5 random trials, training-domain validation for model selection §4.3. Test accuracy in %.
| Dataset | ERM | IRM | GroupDRO | Mixup | MLDG | Coral | MMD | DANN | CDANN | Fish |
|---|---|---|---|---|---|---|---|---|---|---|
| CMNIST | 52.0 ± 0.1 | 51.8 ± 0.1 | 52.0 ± 0.1 | 51.9 ± 0.1 | 51.6 ± 0.1 | 51.7 ± 0.1 | 51.8 ± 0.1 | 51.5 ± 0.3 | 51.9 ± 0.1 | 51.6 ± 0.1 |
| RMNIST | 98.0 ± 0.0 | 97.9 ± 0.0 | 98.1 ± 0.0 | 98.1 ± 0.0 | 98.0 ± 0.0 | 98.1 ± 0.1 | 98.1 ± 0.0 | 97.9 ± 0.1 | 98.0 ± 0.0 | 98.0 ± 0.0 |
| VLCS | 77.4 ± 0.3 | 78.1 ± 0.0 | 77.2 ± 0.6 | 77.7 ± 0.4 | 77.1 ± 0.4 | 77.7 ± 0.5 | 76.7 ± 0.9 | 78.7 ± 0.3 | 78.2 ± 0.4 | 77.8 ± 0.3 |
| PACS | 85.7 ± 0.5 | 84.4 ± 1.1 | 84.1 ± 0.4 | 84.3 ± 0.5 | 84.8 ± 0.6 | 86.0 ± 0.2 | 85.0 ± 0.2 | 84.6 ± 1.1 | 82.8 ± 1.5 | 85.5 ± 0.3 |
| OfficeHome | 67.5 ± 0.5 | 66.6 ± 1.0 | 66.9 ± 0.3 | 69.0 ± 0.1 | 68.2 ± 0.1 | 68.6 ± 0.4 | 67.7 ± 0.1 | 65.4 ± 0.6 | 65.6 ± 0.5 | 68.6 ± 0.4 |
| TerraInc | 47.2 ± 0.4 | 47.9 ± 0.7 | 47.0 ± 0.3 | 48.9 ± 0.8 | 46.1 ± 0.8 | 46.4 ± 0.8 | 49.3 ± 1.4 | 48.7 ± 0.5 | 47.6 ± 0.8 | 45.1 ± 1.3 |
| DomainNet | 41.2 ± 0.2 | 35.7 ± 1.9 | 33.7 ± 0.2 | 39.6 ± 0.1 | 41.8 ± 0.4 | 41.8 ± 0.2 | 39.4 ± 0.8 | 38.4 ± 0.0 | 38.9 ± 0.1 | 42.7 ± 0.2 |
| Average | 67.0 | 66.0 | 65.5 | 67.1 | 66.8 | 67.2 | 66.8 | 66.4 | 66.1 | 67.1 |
The paper ranks Fish second of ten by average, 0.1 points below Coral and one of three methods above ERM §4.3. The DomainBed experiments are not in the official repository (see Paper vs code).
Analysis §4.4
- Gradient inner product during training (CdSprites-N, N = 15): Fish's normalised GIP between domain minibatches rises during training, while ERM's stays flat §4.4 fig. 5. The appendix shows the same comparison on five Wilds datasets, with the GIP measured before and after each update, and says ERM updates often lower the GIP while Fish keeps it or raises it app. G.
- Random grouping §4.4 tab. 5 (test accuracy %):
| Method | CdSprites (N=10) | FMoW | VLCS | PACS | OfficeHome |
|---|---|---|---|---|---|
| Fish | 100.0 ± 0.0 | 34.3 ± 0.6 | 77.6 ± 0.5 | 85.5 ± 0.3 | 68.6 ± 0.9 |
| Fish, random grouping | 50.0 ± 0.0 | 33.4 ± 1.7 | 77.7 ± 0.3 | 83.9 ± 0.7 | 66.5 ± 1.0 |
| ERM | 50.0 ± 0.0 | 31.7 ± 1.0 | 77.5 ± 0.4 | 85.5 ± 0.2 | 66.5 ± 0.3 |
The paper's reading: grouping minibatches by domain is what makes Fish work; random grouping, which still maximises the inner product between minibatches, does not reach the same generalisation.
Ablations app. E app. F
Pretrained ERM models at different convergence levels, test numbers tab. 15:
| Pretraining | FMoW (test avg. acc.) | Camelyon17 (test avg. acc.) | iWildCam (test macro F1) | CivilComments (test worst acc.) |
|---|---|---|---|---|
| 10% of data (epoch 1) | 21.7 ± 2.5 | 79.1 ± 12.3 | 13.7 ± 0.5 | 71.8 ± 1.3 |
| 50% of data (epoch 1) | 31.0 ± 0.8 | 64.6 ± 12.3 | 19.0 ± 0.06 | 74.2 ± 0.5 |
| Converged | 32.7 ± 1.2 | 63.5 ± 8.2 | 23.7 ± 0.9 | 73.8 ± 1.8 |
The paper's reading: CivilComments tolerates any convergence level; FMoW and iWildCam prefer the converged model; Camelyon17 does best with the least pretraining app. E.
Meta steps N (domains sampled per inner loop) tab. 16:
| N | FMoW (test avg. acc.) | Poverty (test Pearson r) | iWildCam (test macro F1) | CivilComments (test worst acc.) |
|---|---|---|---|---|
| 5 | 33.0 ± 1.6 | 80.3 ± 1.7 | 23.7 ± 0.9 | 74.3 ± 1.5 |
| 10 | 32.7 ± 1.2 | 80.0 ± 0.8 | 23.7 ± 0.5 | 73.4 ± 1.0 |
| 20 | 33.3 ± 2.1 | 77.7 ± 2.1 | 23.7 ± 0.9 | 72.6 ± 2.3 |
The paper reports that α and ε were varied with their product held fixed, and that N = 20 slightly hurts Poverty and CivilComments app. F fig. 7.
Compute
The paper estimates about 1,500 GPU-hours on NVIDIA V100 to replicate all its experiments §5.
Dataset details tab. 6
| Dataset | Domains (# domains) | Data | Target | # train | # val | # test | Domains train / val / test |
|---|---|---|---|---|---|---|---|
| FMoW | Time (16), regions (5) | Satellite images | Land use (62) | 76,863 | 19,915 | 22,108 | 11 / 3 / 2 (time) |
| Poverty | Countries (23), urban/rural (2) | Satellite images | Asset (real) | 10,000 | 4,000 | 4,000 | 13 / 5 / 5 |
| Camelyon17 | Hospitals (5) | Tissue slides | Tumour (2) | 302,436 | 34,904 | 85,054 | 3 / 1 / 1 |
| CivilComments | Demographics (8) | Online comments | Toxicity (2) | 269,038 | 45,180 | 133,782 | - |
| iWildCam2020 | Trap locations (324) | Photos | Species (186) | 142,202 | 20,784 | 38,943 | 245 / 32 / 47 |
| Amazon | Reviewers (7,676) | Product reviews | Stars (5) | 1,000,124 | 100,050 | 100,050 | 5,008 / 1,334 / 1,334 |
Source: app. C tab. 6.
Paper vs code
Repository: https://github.com/YugeTen/fish at commit 333efa24572d99da0a4107ab9cc4af93a915d2a9, MIT licence, copyright Facebook LICENSE. The GitHub user is YugeTen, the abstract links the repository [abstract], and the README directs contact to the first author's address README.md.
What the code contains: Fish and ERM training, for six Wilds datasets and CdSprites-N main.py README.md. Not in the repository: direct IDGM (Algorithm 2), SmoothFish, the GIP tracking experiments and the DomainBed runs; the README points to a separate DomainBed fork for those README.md.
Discrepancies found, each with both citations:
- Outer step size is divided by S. The paper's update applies ε directly
alg. 1 l. 8. The code passes
meta_lr / meta_stepsto the update main.py utils.py. The table values match the undividedmeta_lrtab. 14 config.py config.py. The effective outer rate is therefore ε/N: 0.0033 for Camelyon17, 0.002 for FMoW and Amazon, 0.001 for iWildCam, 0.01 for CivilComments and CdSprites, and 0.02 for Poverty. - Inner optimiser. Algorithm 1 uses a plain gradient step alg. 1 l. 6. The code uses the dataset's ERM optimiser (Adam or SGD with momentum), and for every dataset except CdSprites it carries the optimiser state across inner loops main.py config.py. The paper says Fish uses the same optimiser as ERM app. D but does not say whether the state persists.
- Camelyon17 inner learning rate. The paper gives α = 1e-3 tab. 14; the code's Camelyon17 learning rate is 1e-4 config.py. The paper's ERM learning rate for Camelyon17 is also 1e-3 tab. 13, while the code uses 1e-4 with momentum 0.9 config.py. The paper does not state a momentum value.
- Weight decay for Civil and Amazon ERM. The paper's ERM table gives weight decay 0.01 for both tab. 13. The code uses 0 for both config.py config.py.
- FMoW model selection metric. The paper's ERM table gives validation average accuracy tab. 13. The code selects on worst-region accuracy config.py. The code also saves the last FMoW checkpoint, not the best one utils.py.
- Poverty selection metric. The paper's text names Pearson r app. C.1.
The code selects on
r_wgconfig.py. That metric is not defined in this repository; it presumably comes from the Wilds package, which is not in the repository. - Model backbones. The paper says BERT for CivilComments and Amazon §4.2 app. C.4 app. C.6. The code uses DistilBERT civil.py amazon.py. The paper names DenseNet-121 for Camelyon17 but does not state an ImageNet initialisation. The code uses DenseNet-121 without pretrained weights camelyon.py. FMoW is initialised from ImageNet fmow.py.
- Camelyon17 ERM pretraining length. The paper's cut-off is "iter 500"
tab. 13. The code's Camelyon17 pretraining runs 10,000 iterations and
evaluates only at the end, because
print_itersis -1 config.py config.py main.py. - iWildCam pretraining length. The paper says the pretrained model is trained "till convergence" app. C.5. The code runs a fixed 24,000 iterations config.py.
- CivilComments domain count. The paper lists 16 domains (8 identities × toxicity) tab. 14. The code builds 18 groups: a "no identity" group plus 8 identities, each split by toxicity datasets.py.
- Domain sampling per inner loop. Algorithm 1 loops over all S domains
alg. 1 l. 3. The code samples
meta_stepsdomains per inner loop and stops an epoch once fewer thanmeta_stepsdomains have batches left, so some batches go unused each epoch main.py utils.py. - CdSprites-N batches differ between ERM and Fish. Fish batches come from
one domain at a time with its own colour palette datasets.py
datasets.py. The ERM path reads items through
__getitem__, which picks a random palette per image datasets.py. The paper describes both methods as training on the same N domains §4.1. The comparison may therefore not be like-for-like. - Poverty loss. The paper does not state a loss. The code uses mean squared error for Poverty and cross-entropy for the others utils.py. The Poverty backbone is a ResNet-18 with 8 input channels poverty.py. No discrepancy found for: the Fish inner-loop structure (S steps, one minibatch per domain), the update form θ ← θ + ε(θ̃ − θ) up to the S factor in item 1, the meta steps for Camelyon17, CivilComments, FMoW, iWildCam, Poverty and Amazon in tab. 14, and the batch sizes in tab. 13.
Pitfalls
- Main-text and appendix numbers disagree. For the same method and test sets, tab. 3 gives Camelyon17 74.7 but app. C.2 gives 79.5; Amazon 53.3 in tab. 3 but 56.0 in app. C.6; CivilComments worst-group 72.8 in tab. 3 but 74.2 in app. C.4; Poverty 0.80 in tab. 3 but 0.81 in app. C.1; FMoW worst-case 34.6 in tab. 3 but 34.3 in app. C.3. The paper does not explain the gap. Pick one source and say which you used.
- Paper's Fish step is not the one in the code. An implementation that follows Algorithm 1 literally (plain step, undivided ε) will take steps about S times larger than the released runs (see Paper vs code 1 and 2). Match the code's behaviour if you want to reproduce the reported numbers.
- Inner optimiser state. Carrying the Adam state across inner loops main.py is an implementation choice the paper does not describe. Results may depend on it.
- Second-order term is absent by design. Fish drops the GIP gradient on purpose; the claimed alignment holds only as α → 0 §3.4 app. A. The paper tests α = 1e-3 to 2e-6 tab. 14 with no bound on the error.
- Cost per meta-step. Each meta-step does S forward/backward passes on a model copy main.py, so cost grows with the number of domains sampled. The paper's Wilds runs sample N ≪ S for large S app. C.1 app. C.3 app. C.4 app. C.6. The 10× speed claim §4.1 has no timing table to check.
- Large domain counts. The paper says Fish struggles to beat ERM when there are many domains §5. iWildCam (324) and Amazon (7,676) show this §4.2. Both results in tab. 3 and app. C.5 show ERM ahead on the primary metric for iWildCam.
- Pretraining dependence. Camelyon17, FMoW, iWildCam, Amazon and CivilComments start from an ERM checkpoint, and the results depend on how far it converged app. E tab. 15. Poverty and CdSprites start from scratch tab. 13 [code: src/config.py#L46-L47] config.py. A fair baseline needs the same pretraining.
- Model selection. The paper says it uses the Wilds selection strategy §4.2. The code evaluates at a fixed interval and keeps the checkpoint with the best validation metric, except for FMoW, where it keeps the last one utils.py. Reported test numbers depend on this choice.
- Seed count. Most Wilds datasets use three seeds; Camelyon17 uses ten §4.2 app. C.2. Small seed counts make the ± values unreliable for close comparisons, such as Fish vs. ERM on Amazon.
- Stochastic domain order. The inner loop visits domains in random order alg. 1 l. 3 utils.py. Results may vary with the seed.
- Wilds version. The paper reports Wilds v1 and says v2 results were not ready at submission app. C. Do not compare these numbers with Wilds v2 leaderboards without rerunning.
- Epoch and checkpoint defaults are code-only. The number of epochs and the evaluation interval are not in the paper config.py. Using them reproduces the code, not the paper's text.
Lineage
- Builds on Reptile, a first-order meta-learning method, whose inner loop uses minibatches from one task instead of different domains §2 app. A.1. Reptile is cited as Nichol, Achiam and Schulman, "On First-Order Meta-Learning Algorithms" (no arXiv id in the source).
- Compared against IGA, which minimises the variance of gradients across domains instead of maximising their inner product §2.
- Compared against IRM (arXiv:1907.02893), CORAL, MMD, DANN, Group DRO, Mixup and MLDG on DomainBed (arXiv:2007.01434) §4.3 tab. 4.
- Evaluated on the Wilds benchmark (arXiv:2012.07421) §4.2.
- Superseded by: not stated in the source.
Source and license
Adapted from “Gradient Matching for Domain Generalization” by Yuge Shi, Jeffrey Seely, Philip H. S. Torr, N. Siddharth, Awni Hannun, Nicolas Usunier, Gabriel Synnaeve (arXiv:2104.09937), 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/YugeTen/fish at commit 333efa24572d (MIT). Any quoted code is shown under that license.