Recognition & Detection
Few-Shot Recognition
Recognizing new image classes from one or a few labelled examples each, set up as N-way K-shot episodes with support and query sets; metric-based methods (siamese, matching, prototypical and relation networks), optimization-based meta-learning (MAML) and pretrained-embedding baselines, few-shot detection, and the Omniglot, miniImageNet, tieredImageNet and Meta-Dataset protocols.
intermediate
Few-shot recognition asks a model to recognize classes it was never trained on, given only one or a few labelled images of each. A system that has learned from many base classes is shown, for instance, five new novel classes with a single example each and must label further images of those five. The setting is also called few-shot classification or few-shot learning, one-shot learning when each class has one example, and low-shot learning. It is image classification with the training set for the classes of interest cut to a handful, so that training a classifier on those images alone overfits, and it borrows its main tool from metric learning: compare a new image with the few labelled ones in a learned feature space. Fei-Fei, Fergus and Perona’s “One-Shot Learning of Object Categories” (2006) addressed the problem for object categories before deep networks, a line of work described with the Caltech-101 dataset; this article covers the deep-learning formulation that Vinyals et al. (2016) standardized as N-way K-shot episodes. With no labelled image of a class at all, the task becomes zero-shot recognition, which uses class descriptions instead.
Problem Definition
The classes are split into disjoint sets: base classes , with plenty of labelled images, and novel classes , seen only at test time. A test episode (also called a task) draws novel classes and gives:
- a support set with labelled images per class, so ;
- a query set of further images of the same classes, which the model must label.
This is the N-way K-shot task in the terms of Vinyals et al. (2016), who defined it as classifying a disjoint batch of unlabelled examples into one of classes not previously trained on, given labelled examples of each, so that chance accuracy is . The labels are reassigned in every episode, so a model cannot memorize them; it must learn to use the support set. Results are reported as mean query accuracy over many test episodes, usually 600 or 1,000, with a 95% confidence interval.
Most methods also train on episodes. Vinyals et al. built their training procedure on the principle that test and train conditions must match: each training step samples a few base classes, a support set and a batch of queries, and minimizes the error on the queries given the support set,
where is a label set drawn from a task distribution . They called this a form of meta-learning, since the training learns to learn from a support set; in that vocabulary the base classes form the meta-training set and the novel classes the meta-test set, and a validation split of further classes (meta-validation) is used for model selection.
Two variants of the evaluation matter for comparing numbers. In the usual inductive setting each query is classified independently; transductive methods use the whole query set of an episode at once, which Tian et al. (2020) point out uses information from the test data. In generalized few-shot evaluation the model must handle base and novel classes together, which is the setting few-shot detection benchmarks adopted (below).
Input and Output
The input to one episode is the labelled support images and the query images, typically small: Omniglot characters resized to 28 × 28 and miniImageNet images at 84 × 84 in the papers below. The output is a label in for each query, usually from a probability over the episode classes. The model’s parameters may stay fixed during the episode (metric-based methods), be updated by a few gradient steps on the support set (optimization-based methods), or feed a small classifier trained on the support set from scratch (transfer baselines).
Variants
- One-shot () and few-shot ( from 2 to about 10) classification; is most often 5, with 20-way tasks on Omniglot.
- Cross-domain few-shot recognition trains on one domain and tests on another, such as miniImageNet to the CUB birds dataset (Chen et al., 2019) or across the ten datasets of Meta-Dataset.
- Semi-supervised episodes add unlabelled images, some from distractor classes; the README of Ren et al.’s code release, which introduced tieredImageNet, tests miniImageNet and tieredImageNet models on episodes with 20 unlabelled and 20 query images per class.
- Few-shot object detection gives a few annotated boxes per novel class (below).
- Few-shot keypoint localization, category-agnostic pose estimation from annotated support images, is covered under keypoint detection.
- Face verification compares a new face with one enrolled image of each identity, a one-shot problem usually solved with a learned embedding rather than episodes, trained for instance with the triplet loss; see face recognition and FaceNet.
Challenges
- Overfitting. A network fitted to images per class memorizes them. Snell et al. (2017) built prototypical networks around this point, working under the assumption that with so little data a classifier should have a very simple inductive bias.
- Distance from the base classes. What transfers depends on how similar the novel classes are to the base ones. Vinyals et al. trained matching networks on non-dog ImageNet classes and tested on 118 dog classes; the model fell slightly below the Inception features it started from (58.8% against 59.8%, 5-way 1-shot), which they attributed to the fine-grained test classes differing from the randomly sampled training tasks. Chen et al. (2019) found that a simple fine-tuning baseline compared favourably with meta-learning methods when the domain changed from miniImageNet to CUB.
- High variance. With one to five support images, accuracy changes a great deal from episode to episode, so results need many test episodes and confidence intervals. In detection, Wang et al. (2020) found that the accuracy on the first random sample of training shots was high and that the average fell significantly as more of 40 samples were added.
- Comparability. Backbones, input sizes, data augmentation, the number of ways used in training and the data splits all change the numbers. Finn et al. (2017) warned that their Omniglot results might not be strictly comparable because earlier train/test splits were not available, and Chen et al. found that a baseline trained without data augmentation was underestimated.
Approaches
Tian et al. (2020) divide meta-learning methods into two families, and Chen et al. (2019) set both against non-episodic baselines, giving three groups: metric-based methods learn an embedding and classify queries by comparing them with the support images; optimization-based methods learn how to adapt a network to the support set; and transfer baselines train an ordinary classifier on the base classes and fit a simple classifier on its features for each episode. Most methods published from 2016 to 2018 trained on episodes; comparisons published from 2019 (Chen et al.; Tian et al.) found that much of the gain came from the embedding rather than the meta-learning algorithm.
Before deep networks
Fei-Fei, Fergus and Perona’s work on one-shot learning of object categories predates the deep methods below, and Lake and colleagues collected Omniglot for developing more human-like learning algorithms, as its official repository puts it. On Lake’s 20-way within-alphabet one-shot task, Koch et al. (2015) list results from Lake et al. (2013): humans 95.5%, Hierarchical Bayesian Program Learning 95.2%, and a 1-nearest-neighbour baseline 21.7%.
Metric-based methods
Siamese networks. Koch, Zemel and Salakhutdinov (2015) trained a convolutional siamese network to verify whether two Omniglot characters were the same, using a weighted distance between the twin feature vectors followed by a sigmoid and a cross-entropy loss, then used it for one-shot classification by picking the support image with the highest predicted similarity. On Lake’s 20-way within-alphabet task (400 trials over the ten evaluation alphabets) it reached 92.0%, below Hierarchical Bayesian Program Learning and humans but above every other model in the comparison (the next was an affine model at 81.8%). The network was trained for verification, not for the one-shot task itself; the later methods train directly on episodes.
Matching networks. Vinyals et al. (2016) classify a query by attention over the support set,
where are one-hot labels, is the cosine similarity and , are embedding networks; the output is a soft nearest-neighbour vote that needs no fine-tuning for new classes. Full context embeddings (FCE) let each support embedding depend on the whole support set through a bidirectional LSTM and the query embedding attend to the support set through an LSTM with read attention. The embedding for Omniglot was four blocks of 3 × 3 convolution with 64 filters, batch normalization, ReLU and 2 × 2 max pooling, the “Conv-4” network that later papers reused. On Omniglot (5-way 1-shot) matching networks reached 98.1%, against 41.7% for cosine matching on pixels and 96.7% for their reimplementation of the convolutional siamese network; on their own miniImageNet split, 5-way 1-shot accuracy was 41.2% without fine-tuning or FCE, and 46.6% with both. On full ImageNet, starting from an Inception classifier trained on the other classes, they raised 5-way 1-shot accuracy on 118 random held-out classes from 87.6% to 93.2%.
Prototypical networks. Snell, Swersky and Zemel (2017) represent each class by a single prototype, the mean of its embedded support images,
and train by minimizing the negative log-probability of the true class over episodes. Three of their observations shaped later work:
- Why the mean. For a Bregman divergence such as the squared Euclidean distance, the class mean is the point closest on average to the class’s support points, and the classifier equals cluster assignment in a mixture of exponential-family densities, one component per class. Cosine distance is not a Bregman divergence, and the squared Euclidean distance worked much better than cosine for both prototypical and matching networks in their miniImageNet comparison.
- A linear classifier. With the squared Euclidean distance, ; the first term is the same for every class, so the model is a linear classifier with weights and biases on the learned features. With one shot the prototype is the single support embedding, and prototypical and matching networks coincide.
- Episode design. Training with more classes per episode than at test time helped (they used 60-way episodes on Omniglot, and 30-way for 1-shot and 20-way for 5-shot on miniImageNet, chosen on validation classes), and matching the training shot to the test shot was usually best.
Their Algorithm 1 writes the prototype’s normalizing factor as , where is the number of classes per episode, while Equation 1 and the text define the prototype as the mean over the class’s support points (, which is in the algorithm’s notation). With the Conv-4 network, they reported 98.8% (5-way 1-shot) and 96.0% (20-way 1-shot) on Omniglot, and 49.42 ± 0.78% and 68.20 ± 0.66% for 5-way 1-shot and 5-shot on miniImageNet with Ravi and Larochelle’s split. Sung et al. (2018) note that the prototypical network reached 46.14 ± 0.77% (1-shot) when trained with 5-way episodes.
Relation networks. Sung et al. (2018) replaced the fixed distance with a learned one. An embedding module produces feature maps for a query and a support image; the two are concatenated in depth and passed to a relation module, two convolutional blocks and two fully connected layers ending in a sigmoid, which outputs a relation score between 0 and 1 (the last two embedding blocks omit pooling to leave feature maps for it). For the support feature maps of a class are summed. The model is trained by regressing the scores to 1 for matching pairs and 0 otherwise with a mean squared error, which the authors call somewhat non-standard. It reached 50.44 ± 0.82% and 65.32 ± 0.70% on miniImageNet (5-way 1-shot and 5-shot) and 99.6% and 97.6% on Omniglot 5-way and 20-way 1-shot. The paper describes its miniImageNet training episodes twice in different terms: 15 query images per class for 1-shot and 10 for 5-shot in the training paragraph, but “1 query for 1-shot and 5 queries for 5-shot” in the comparison with prototypical networks.
Optimization-based methods
Instead of a fixed comparison, optimization-based methods adapt the network’s weights to each support set. Snell et al. describe the meta-learner LSTM of Ravi and Larochelle (2017) as an LSTM trained to produce the updates of a classifier for each episode, so that it generalizes to the episode’s test set.
MAML. Model-Agnostic Meta-Learning (Finn, Abbeel and Levine, 2017) learns an initialization from which a few gradient steps on a new task’s support set give good performance on its queries. For task with loss , one inner step gives adapted parameters, and the outer update optimizes the initial for the loss after adaptation:
The method adds no parameters beyond the model’s own, and applies to any model trained by gradient descent; the paper also used it for regression and reinforcement learning. The outer gradient passes through the inner gradient step, which needs Hessian–vector products. A first-order approximation that drops these second derivatives scored almost the same on miniImageNet (48.07 ± 1.75% and 63.15 ± 0.91% against 48.70 ± 1.84% and 63.11 ± 0.92% for full MAML, 5-way 1-shot and 5-shot), and the authors measured roughly a 33% speed-up in network computation; Tian et al. (2020) later described the first-order version as giving orders of magnitude speed-up, which the MAML paper does not report. MAML used the Conv-4 network with 32 filters per layer on miniImageNet to reduce overfitting. Its Omniglot result, 98.7% (5-way 1-shot), was obtained on a random split of 1,200 training characters, which the authors note may not be strictly comparable because the splits of earlier work were not available.
The MAML paper describes the miniImageNet split as 64 training, 12 validation and 24 test classes, while the split files in Ravi and Larochelle’s release, the source the paper cites for the dataset, contain 64, 16 and 20 classes (see below). Its Table 1 also labels the 28.86% and 41.08% baselines taken from Ravi and Larochelle “fine-tuning” and “nearest neighbor”, while Snell et al. label 28.86% “baseline nearest neighbors”; Ravi and Larochelle’s paper could not be read to settle which is which. Snell et al.’s Table 2 lists MAML at 48.70 ± 1.84% and 63.15 ± 0.91%, the full method’s 1-shot result beside the first-order 5-shot result; Sung et al. and Tian et al. give the full method’s 63.11 ± 0.92%.
Transfer baselines and the role of the embedding
A closer look. The paper by Chen et al. (2019) could not be read for this article (it is on OpenReview and arXiv, which are not used here); this paragraph and the other mentions of it follow the authors’ project page and ICLR poster. Chen et al. reimplemented matching, prototypical and relation networks and MAML in one code base and compared them with two non-episodic baselines: Baseline, a network trained with a linear classifier on all base classes, after which a new linear classifier is trained on each episode’s support set with the features fixed; and Baseline++, which replaces the linear layer with cosine similarities to class weight vectors, each of which acts as a class prototype. Their poster reports, for 5-way miniImageNet with Conv-4:
| Method | 1-shot | 5-shot |
|---|---|---|
| Baseline (no data augmentation) | 36.35 ± 0.64 | 54.50 ± 0.66 |
| Baseline | 42.11 ± 0.71 | 62.53 ± 0.69 |
| Baseline++ | 48.24 ± 0.75 | 66.43 ± 0.63 |
| MatchingNet | 48.14 ± 0.78 | 63.48 ± 0.66 |
| ProtoNet | 44.42 ± 0.84 | 64.24 ± 0.72 |
| MAML | 46.47 ± 0.82 | 62.71 ± 0.71 |
| RelationNet | 49.31 ± 0.85 | 66.60 ± 0.69 |
The authors’ summary on their project page is that the differences between methods shrink as the backbone gets deeper when the domain difference is limited, that the slightly modified baseline is competitive with the state of the art on miniImageNet and CUB, and that in the cross-domain miniImageNet-to-CUB setting a baseline with standard fine-tuning compares favourably with the meta-learning methods. The underestimated baseline came partly from omitted data augmentation, as the first two rows show.
A good embedding. Tian et al. (2020) dropped episodes entirely. They merged all meta-training classes into one ordinary classification task, trained a network with the cross-entropy loss, froze it at the penultimate layer, and for each test episode fitted a logistic regression on the support embeddings, the same structure as a linear probe in transfer learning. They added sequential self-distillation, retraining the same architecture to match the previous generation’s predictions as well as the labels. With a ResNet-12 at 84 × 84:
- on miniImageNet, the simple baseline scored 62.02 ± 0.63% and 79.64 ± 0.44% (5-way 1-shot and 5-shot), against 62.64 ± 0.61% and 78.63 ± 0.46% for MetaOptNet, a meta-learning method with the same backbone; with distillation, 64.82 ± 0.60% and 82.14 ± 0.43%;
- on tieredImageNet, 69.74 ± 0.72% and 84.41 ± 0.55%, against 65.99 ± 0.72% and 81.56 ± 0.53% for MetaOptNet (Table 1; the Table 5 ablation row whose other miniImageNet and tieredImageNet entries match Table 1 gives 85.23 for this 5-shot result);
- with a Conv-4 network, their embedding scored 55.25 ± 0.58% and 71.56 ± 0.52% on miniImageNet, above the prototypical network’s 49.42% and 68.20% with that architecture, although the training recipes differ, Tian et al.’s with data augmentation (our caveat);
- on Meta-Dataset, training a ResNet-18 on the ImageNet training classes, logistic regression on its features averaged 68.02% over the ten test sources against 60.94% for the best result per source among the seven methods and three backbones of the Meta-Dataset paper, and beat that best result on nine of the ten.
Their ablations point to the embedding rather than the classifier on top: logistic regression beat nearest neighbour, normalization of the features improved 1-shot accuracy on all four benchmarks, by 1.9 to 4.3 points in their Table 5 (the text says by 2%), and a self-supervised ResNet-50 (MoCo) trained without labels on the meta-training images scored 54.19% (1-shot) and 73.04% (5-shot) on miniImageNet against 57.56% and 73.81% for the same network trained with labels. Fine-tuning a WRN-28-10 on each episode’s support images, as Dhillon et al. (2020) did, gave 57.73% (1-shot); the same architecture kept frozen gave Tian et al. 61.1%. Training one shared embedding by multi-task learning, with a separate classification head per task instead of one head over all 64 classes, gave 58.53% against 62.02%, which the authors attribute to the base tasks being mutually exclusive and so mergeable into one many-way problem.
What the comparisons show. Tian et al. concluded that, in both small and large models, few-shot and meta-learning algorithms were no better than learning a good embedding, and they cite the finding of Raghu et al. (2019) that feature reuse, not rapid learning, dominates MAML’s effectiveness. As of November 2026, the Meta-Dataset leaderboard for training on ImageNet only ranks the plain fine-tuning baseline of the original study (average rank 10.45) above prototypical networks (10.75), first-order MAML (12.25), matching networks (13.55) and relation networks (15.55), though below first-order Proto-MAML (9.25), a combination of the two families. In our reading, these results do not show that meta-learning is useless, only that on these benchmarks the quality of the features learned from the base classes, which depends on the backbone, the training recipe and the data, explains more of the accuracy than the episodic algorithm. The same lesson came from the metric learning benchmarks, where losses compared under one protocol differed far less than published gains suggested.
Example: nearest prototypes on pixels and on pretrained features
The example builds Omniglot-like synthetic characters with known ground truth: each class is a glyph of two to four random strokes (straight segments or quadratic Bézier curves) on a 28 × 28 canvas, and each of its 20 instances, like a different drawer, jitters the stroke points, applies a random small rotation, scaling, shear and shift, varies the stroke width and adds noise. There are 200 base classes and 100 novel classes. Every 5-way episode on the novel classes is classified by nearest prototype, the mean of the support vectors, on four kinds of features: raw pixels; a Conv-4 network with random weights (a control for the architecture); the same network pretrained as an ordinary 200-way classifier on the base classes, then frozen (the transfer baseline); and the same network trained episodically as a prototypical network on the base classes (20-way, 5-shot episodes) with the same number of image passes, 120,000. Because Snell et al. found the squared Euclidean distance better than cosine while Tian et al. found that -normalizing the features helped, every row is printed with the squared Euclidean distance on raw features and on -normalized features. A label-free check comes first: classifying each query by normalized correlation with the clean, undistorted glyph of each episode class, with no training. The script loops over three seeds, each generating its own classes and training its own networks, and uses the same 600 test episodes per for every feature type. It is slow for an example: on our machine three identical runs took about 24, 10 and 5 minutes of wall-clock time, depending on the load from other jobs (17, 14 and 10 minutes of user CPU time; PyTorch 2.14.1, NumPy 2.5.4, SciPy 1.18.1, four threads), most of it training the two networks.
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from scipy.ndimage import gaussian_filter
torch.set_num_threads(4)
S = 28 # image size
N_BASE, N_NOVEL, PER_CLASS = 200, 100, 20
def random_glyph(rng):
"""A class: 2-4 strokes, each a quadratic Bezier (p0, p1, p2) in pixel units."""
strokes = []
for _ in range(rng.integers(2, 5)):
p0, p2 = rng.uniform(6, 22, size=(2, 2))
p1 = (p0 + p2) / 2 if rng.random() < 0.5 else rng.uniform(6, 22, size=2)
strokes.append(np.stack([p0, p1, p2]))
return strokes
def render(strokes, rng=None):
"""Draw one instance; rng=None gives the clean canonical glyph."""
if rng is None:
A, t, jit, sigma, noise = np.eye(2), np.zeros(2), 0.0, 0.9, 0.0
else:
a, s = np.deg2rad(rng.uniform(-12, 12)), rng.uniform(0.9, 1.1)
sh = rng.uniform(-0.1, 0.1)
A = s * np.array([[np.cos(a), -np.sin(a)], [np.sin(a), np.cos(a)]]) @ np.array([[1, sh], [0, 1]])
t, jit = rng.uniform(-2, 2, size=2), 1.5
sigma, noise = rng.uniform(0.7, 1.1), 0.05
img = np.zeros((S, S))
u = np.linspace(0, 1, 60)[:, None]
for st in strokes:
p = st + (rng.uniform(-jit, jit, size=st.shape) if rng is not None else 0)
pts = (1 - u) ** 2 * p[0] + 2 * u * (1 - u) * p[1] + u ** 2 * p[2]
pts = (pts - S / 2) @ A.T + S / 2 + t
x, y = np.clip(pts[:, 0], 0, S - 1.001), np.clip(pts[:, 1], 0, S - 1.001)
x0, y0 = x.astype(int), y.astype(int)
fx, fy = x - x0, y - y0
for dx, dy, w in [(0, 0, (1 - fx) * (1 - fy)), (1, 0, fx * (1 - fy)),
(0, 1, (1 - fx) * fy), (1, 1, fx * fy)]:
np.add.at(img, (y0 + dy, x0 + dx), w)
img = gaussian_filter(img, sigma)
img /= img.max()
if rng is not None:
img += noise * rng.standard_normal(img.shape)
return img.astype(np.float32)
def make_data(rng):
glyphs = [random_glyph(rng) for _ in range(N_BASE + N_NOVEL)]
X = np.stack([render(g, rng) for g in glyphs for _ in range(PER_CLASS)])
y = np.repeat(np.arange(N_BASE + N_NOVEL), PER_CLASS)
clean = np.stack([render(g) for g in glyphs])
return X, y, clean
def conv4():
def block(cin):
return nn.Sequential(nn.Conv2d(cin, 64, 3, padding=1), nn.BatchNorm2d(64),
nn.ReLU(), nn.MaxPool2d(2))
return nn.Sequential(block(1), block(64), block(64), block(64), nn.Flatten()) # 64-d
def embed(net, X):
net.eval()
with torch.no_grad():
return net(torch.from_numpy(X[:, None])).numpy()
def train_classifier(Xb, yb, seed):
torch.manual_seed(seed)
net, head = conv4(), nn.Linear(64, N_BASE)
opt = torch.optim.Adam(list(net.parameters()) + list(head.parameters()), lr=1e-3)
Xt, yt = torch.from_numpy(Xb[:, None]), torch.from_numpy(yb)
g = torch.Generator().manual_seed(seed)
for epoch in range(30): # 30 x 4,000 = 120,000 image passes
net.train()
for idx in torch.randperm(len(Xt), generator=g).split(100):
loss = F.cross_entropy(head(net(Xt[idx])), yt[idx])
opt.zero_grad(); loss.backward(); opt.step()
net.eval()
with torch.no_grad():
acc = (head(net(Xt)).argmax(1) == yt).float().mean().item()
return net, acc
def train_protonet(Xb, yb, seed, way=20, shot=5, query=5, episodes=600):
torch.manual_seed(seed)
rng = np.random.default_rng(seed + 1000)
net = conv4()
opt = torch.optim.Adam(net.parameters(), lr=1e-3)
by_class = [np.flatnonzero(yb == c) for c in range(N_BASE)]
for _ in range(episodes): # 600 x 200 = 120,000 image passes
net.train()
cls = rng.choice(N_BASE, way, replace=False)
idx = np.stack([rng.choice(by_class[c], shot + query, replace=False) for c in cls])
z = net(torch.from_numpy(Xb[idx.ravel()][:, None])).view(way, shot + query, -1)
protos = z[:, :shot].mean(1)
q = z[:, shot:].reshape(way * query, -1)
logits = -torch.cdist(q, protos) ** 2
loss = F.cross_entropy(logits, torch.arange(way).repeat_interleave(query))
opt.zero_grad(); loss.backward(); opt.step()
return net
def episodes(rng, n_novel, way=5, shot=1, query=5, n=600):
"""Each episode: way novel classes, shot support and query instances per class."""
out = []
for _ in range(n):
cls = rng.choice(n_novel, way, replace=False)
perm = np.stack([rng.permutation(PER_CLASS)[:shot + query] for _ in cls])
out.append((cls, perm[:, :shot], perm[:, shot:]))
return out
def proto_accuracy(feats, eps, normalise):
"""feats: (n_novel, PER_CLASS, d). Nearest prototype under squared Euclidean distance."""
f = feats / np.linalg.norm(feats, axis=-1, keepdims=True) if normalise else feats
accs = []
for cls, sup, qry in eps:
protos = np.stack([f[c, s].mean(0) for c, s in zip(cls, sup)])
q = np.concatenate([f[c, s] for c, s in zip(cls, qry)])
d = ((q[:, None, :] - protos[None]) ** 2).sum(-1)
accs.append((d.argmin(1) == np.repeat(np.arange(len(cls)), qry.shape[1])).mean())
return np.array(accs)
def template_oracle(Xn, clean_n, eps):
"""Label-free check: normalised correlation with the clean glyphs, best shift within +-3 px."""
def nz(a):
a = a.reshape(len(a), -1) - a.reshape(len(a), -1).mean(1, keepdims=True)
return a / np.linalg.norm(a, axis=1, keepdims=True)
q = nz(Xn.reshape(-1, S, S))
best = np.full((len(q), len(clean_n)), -np.inf)
for dy in range(-3, 4):
for dx in range(-3, 4):
best = np.maximum(best, q @ nz(np.roll(clean_n, (dy, dx), axis=(1, 2))).T)
best = best.reshape(len(clean_n), PER_CLASS, -1) # [query class, instance, template]
accs = []
for cls, sup, qry in eps:
sc = np.concatenate([best[c, s][:, cls] for c, s in zip(cls, qry)])
accs.append((sc.argmax(1) == np.repeat(np.arange(len(cls)), qry.shape[1])).mean())
return np.mean(accs)
SHOTS = [1, 2, 5, 10]
results = {} # (feature, dist, shot) -> per-seed (mean, ci)
for seed in range(3):
rng = np.random.default_rng(seed)
X, y, clean = make_data(rng)
base = y < N_BASE
Xb, yb = X[base], y[base]
Xn = X[~base].reshape(N_NOVEL, PER_CLASS, S, S)
eps = {k: episodes(np.random.default_rng(100 + seed), N_NOVEL, shot=k) for k in SHOTS}
torch.manual_seed(seed)
random_net = conv4()
clf_net, train_acc = train_classifier(Xb, yb, seed)
proto_net = train_protonet(Xb, yb, seed)
feats = {"pixels": Xn.reshape(N_NOVEL, PER_CLASS, -1)}
for name, net in [("random CNN", random_net), ("pretrained classifier", clf_net),
("prototypical network", proto_net)]:
feats[name] = embed(net, Xn.reshape(-1, S, S)).reshape(N_NOVEL, PER_CLASS, -1)
oracle = template_oracle(Xn, clean[N_BASE:], eps[1])
print(f"seed {seed}: template oracle 5-way 1-shot {oracle:.3f}; "
f"classifier accuracy on base training images {train_acc:.3f}")
for name, f in feats.items():
for dist, norm in [("euclid", False), ("L2-norm", True)]:
for k in SHOTS:
a = proto_accuracy(f, eps[k], norm)
results.setdefault((name, dist, k), []).append(
(a.mean(), 1.96 * a.std() / np.sqrt(len(a))))
print("\n5-way accuracy on novel classes: seed 0 mean +- 95% CI [range over seeds 0-2]")
print(f"{'features':22s} {'distance':8s}" + "".join(f"{'K=' + str(k):>24s}" for k in SHOTS))
for name in feats:
for dist in ["euclid", "L2-norm"]:
row = f"{name:22s} {dist:8s}"
for k in SHOTS:
r = results[(name, dist, k)]
ms = [m for m, _ in r]
row += f" {r[0][0]:.3f}+-{r[0][1]:.3f} [{min(ms):.3f}-{max(ms):.3f}]"
print(row)
Output:
seed 0: template oracle 5-way 1-shot 0.995; classifier accuracy on base training images 1.000
seed 1: template oracle 5-way 1-shot 0.994; classifier accuracy on base training images 1.000
seed 2: template oracle 5-way 1-shot 0.995; classifier accuracy on base training images 1.000
5-way accuracy on novel classes: seed 0 mean +- 95% CI [range over seeds 0-2]
features distance K=1 K=2 K=5 K=10
pixels euclid 0.652+-0.010 [0.625-0.652] 0.760+-0.009 [0.733-0.760] 0.850+-0.007 [0.824-0.850] 0.885+-0.006 [0.863-0.885]
pixels L2-norm 0.647+-0.010 [0.624-0.652] 0.755+-0.009 [0.725-0.755] 0.841+-0.008 [0.815-0.841] 0.875+-0.007 [0.848-0.875]
random CNN euclid 0.658+-0.010 [0.635-0.658] 0.748+-0.009 [0.741-0.753] 0.827+-0.008 [0.811-0.828] 0.856+-0.007 [0.840-0.856]
random CNN L2-norm 0.679+-0.010 [0.651-0.679] 0.769+-0.009 [0.759-0.769] 0.845+-0.008 [0.835-0.845] 0.871+-0.007 [0.862-0.871]
pretrained classifier euclid 0.934+-0.006 [0.920-0.940] 0.974+-0.003 [0.967-0.977] 0.991+-0.002 [0.987-0.993] 0.992+-0.002 [0.992-0.996]
pretrained classifier L2-norm 0.944+-0.005 [0.930-0.947] 0.976+-0.003 [0.969-0.979] 0.991+-0.002 [0.986-0.993] 0.992+-0.002 [0.992-0.996]
prototypical network euclid 0.941+-0.005 [0.932-0.944] 0.979+-0.003 [0.972-0.979] 0.992+-0.002 [0.985-0.992] 0.994+-0.001 [0.992-0.995]
prototypical network L2-norm 0.942+-0.005 [0.934-0.947] 0.979+-0.003 [0.972-0.979] 0.992+-0.002 [0.985-0.992] 0.993+-0.002 [0.992-0.995]
The template check classifies 99.5% of queries correctly, so the classes are well defined, and the classifier fits all of its base training images. Raw pixels are far from useless on such simple images: 62.5–65.2% at 1-shot, against 20% chance, rising to 86.3–88.5% at 10 shots, because averaging more support images washes out each instance’s distortion. The random-weight network stays within about three points of pixels, slightly above them at 1-shot and below them at 10 shots, so the architecture alone does not help. Training on the base classes does: frozen features from the pretrained classifier reach 92.0–94.0% at 1-shot on classes the network never saw, and every learned row saturates near 99% by . Gains from more shots shrink as grows, most sharply for the learned features, which leave little to average away.
The episodically trained prototypical network and the plain classifier differ by less than one point at every for seed 0, and their ranges over the three seeds overlap, a small-scale version of the finding of Tian et al. and Chen et al. that a good embedding, not the episodic training, carries most of the accuracy; at this scale the example cannot separate the two. The distance choice the sources disagree on hardly matters for the learned features (normalization adds about one point to the classifier’s 1-shot result and nothing to the prototypical network trained with Euclidean distances), while it helps the random network by about two points and lowers seed 0’s pixel rows by up to one point. The script shown is the one first run, without changes.
Few-shot object detection
Few-shot detection gives annotated boxes per novel class and asks a detector to find and localize those classes in new images, which may also contain base-class objects and may contain no novel object at all. Kang et al. (2019) defined the splits and training examples that later work, including Wang et al. (2020), reused. On PASCAL VOC, 5 of the 20 classes are novel and 15 are base, in three random splits; training uses VOC 2007 and 2012 trainval with = 1, 2, 3, 5 or 10 boxes per novel class, and testing uses VOC 2007 test, scored by mean AP at an IoU of 0.5. On COCO, the 20 classes shared with VOC are novel and the other 60 base, with = 10 or 30 and 5,000 validation images for testing, scored by COCO-style average precision.
Their detector, which Wang et al. (2020) call FSRW, built on YOLOv2: a reweighting module turns the support images of each novel class into a vector of channel weights that modulates the query image’s features before the detection head, trained first on base classes with episodes and then fine-tuned on a small set with boxes for each novel and each base class. It reached 14.8 and 47.2 mAP on novel set 1 with 1 and 10 shots, against 6.6 and 38.6 for a fully converged fine-tuned YOLOv2, and 5.6 and 9.1 AP on COCO with 10 and 30 shots; jointly training on base and novel classes in one stage gave almost nothing on the novel classes (0.0–3.9 mAP on VOC).
Wang et al. (2020) then showed that meta-learning was not needed here either. Their two-stage fine-tuning approach (TFA) trains a Faster R-CNN with a ResNet-101 feature pyramid backbone on the base classes, then freezes everything except the last box classification and regression layers and fine-tunes those on a small balanced set with shots of every base and novel class; a variant uses a cosine-similarity box classifier. On VOC novel set 1, TFA with the cosine classifier scored 39.8 mAP (AP50) with one shot and 56.0 with ten, against 19.9 and 51.5 for the meta-learning detector Meta R-CNN, and it kept base-class AP50 at 78.4–79.1, against 77.9 for a model trained on base classes only. On COCO it scored 10.0 and 13.7 novel AP with 10 and 30 shots. Because results on one sample of shots vary widely, Wang et al. proposed a revised protocol that averages over many random samples of the training shots (30 samples for VOC and 10 for COCO in their figures) and reports base and overall AP alongside novel AP, and they added an LVIS benchmark that treats its rare classes as novel. Detecting new classes from text instead of example boxes is open-vocabulary object detection.
Datasets and Benchmarks
Omniglot. 1,623 handwritten characters from 50 alphabets, each drawn by 20 people through Amazon Mechanical Turk, with stroke data for every drawing (official repository, accessed November 2026). The official split puts 30 alphabets in a background set for learning and 20 in an evaluation set, and Lake’s one-shot task is 20-way classification within an alphabet, which the repository describes as harder than the between-alphabet tasks used elsewhere. Two variants differ:
- Lake’s protocol, used by Koch et al.: 20-way within-alphabet one-shot trials on the evaluation alphabets (400 trials in Koch et al.). Koch et al. describe Lake’s split as 40 background and 10 evaluation alphabets, which differs from the 30/20 split in the official repository.
- The Vinyals protocol, used by matching and prototypical networks, MAML and relation networks: 1,200 characters, chosen regardless of alphabet, for training and the remaining 423 for testing, with every character augmented by rotations in multiples of 90° into four classes (4,800 training classes in Snell et al.), images resized to 28 × 28, and 5-way and 20-way tasks with 1 and 5 shots. Finn et al. note that the exact character split of earlier work was not available.
By 2018 the Vinyals-protocol accuracies were near the ceiling (97.6–99.8% for relation networks across the four settings), and Omniglot remains in Meta-Dataset as one source among ten.
miniImageNet. Vinyals et al. built it from ImageNet: 60,000 colour images of 84 × 84 pixels in 100 classes with 600 images each, 80 classes for training and 20 for testing. Ravi and Larochelle published a different set of 100 classes, split 64 for training, 16 for validation and 20 for testing; the split files in their repository contain exactly these counts with 600 images per class (38,400, 9,600 and 12,000 images), and this split became the standard one (Snell et al., Sung et al., Tian et al. use it). The usual protocol is 5-way 1-shot and 5-shot with 15 query images per class and 600 test episodes, reporting the mean with a 95% confidence interval; Tian et al. averaged 1,000 episodes per run and reported the median of three runs. Because all 100 classes are ImageNet classes, a network pretrained on full ImageNet would already have seen the test classes (our observation); the papers above train only on the 64 base classes.
tieredImageNet. Ren et al. (2018), as described by Tian et al., grouped 608 ImageNet classes under 34 higher-level categories and split the categories, not the classes: 20 categories (351 classes) for training, 6 (97 classes) for validation and 8 (160 classes) for testing, so test classes are semantically further from training classes than in a random split (Tian et al.; the counts match the split files in the authors’ repository). Evaluation is 5-way 1-shot and 5-shot as for miniImageNet.
Meta-Dataset. Triantafillou et al. (2020) combined ten datasets: ImageNet (ILSVRC 2012), Omniglot, FGVC-Aircraft, CUB-200-2011 birds, Describable Textures, Quick, Draw!, FGVCx Fungi, VGG Flower, German traffic signs and MSCOCO, with 4,934 classes in total split 3,144/598/1,192 for training, validation and test. ImageNet’s 1,000 classes are split 712/158/130 following its hierarchy and Omniglot’s by alphabet (25/5/20); traffic signs are test-only and MSCOCO is used for validation and test only, so they measure transfer to unseen datasets. Benchmarks train either on ImageNet alone or on all eight training sources. Episodes vary in size: in the released configuration the number of ways is drawn uniformly from 5 up to 50 (or the number of classes available), the support set has up to 500 images with at most 100 from one class and class proportions perturbed by random weights between 0.5 and 2, and each class gets up to 10 queries; when a dataset defines a class hierarchy, the sampler can draw an episode’s classes from one part of it. The released training configuration evaluates on 600 episodes, and the leaderboard asks for confidence intervals over at least 600 episodes (Tian et al. used 1,000). As of November 2026 the repository’s README keeps a leaderboard and a second version of the protocol (MD-v2) for the combined VTAB+MD benchmark.
Other benchmarks include CUB-200-2011 for cross-domain and fine-grained few-shot tests (see fine-grained image classification), CIFAR-FS and FC100, both built from CIFAR-100 (Tian et al.), and the few-shot detection splits of PASCAL VOC, COCO and LVIS above.
Evaluation Metrics
Classification benchmarks report the mean accuracy over test episodes with a 95% confidence interval, for episodes with standard deviation ; the interval describes episode sampling only, not training runs, so it understates the real spread between implementations. Accuracy is per episode, with and always stated, since 5-way and 20-way, or 1-shot and 5-shot, numbers are not comparable. Few-shot detection reports AP50 on VOC novel classes and COCO-style AP on COCO novel classes, and the generalized protocol of Wang et al. adds base-class and overall AP and averages over repeated samples of the training shots.
Applications
Few-shot recognition applies wherever new categories appear after a model is trained and labelled images of them are scarce: rare classes, newly introduced products or objects, and per-user categories. The papers above motivate it with such cases, rare animals and new consumer devices in Sung et al. (2018) and rare categories in Kang et al. (2019). Enrolling a new identity from one photograph in face recognition, adding a new keypoint layout in category-agnostic pose estimation (keypoint detection) and adding a new object class to a detector from a few boxes are related settings. In our reading of the evidence above, a strong pretrained backbone with a simple classifier or prototypes on its features is the natural starting point, with fine-tuning once more labels arrive.
Open Problems
- Benchmarks that test learning to learn. Tian et al. called for rethinking the benchmarks, since on miniImageNet and tieredImageNet a frozen embedding with a linear classifier matches or beats meta-learning algorithms. Meta-Dataset, with its varied episodes and held-out datasets, is a broader test; Tian et al. describe its samples as more diverse and realistic than those of miniImageNet and tieredImageNet.
- Domain shift. Accuracy drops when novel classes come from another domain, as in Chen et al.’s miniImageNet-to-CUB experiment and Meta-Dataset’s held-out sources, and adapting from a few images without overfitting remains difficult.
- Fine-grained novel classes. Matching networks failed to improve on their starting features for ImageNet dog classes; few examples of visually similar classes leave little to separate them.
- Generalized evaluation. Most classification benchmarks test novel classes alone, while deployed systems must recognize base and novel classes together without forgetting the base ones, a gap the generalized detection protocols address.
- Reporting. Differences in backbones, augmentation, splits and the number of runs have repeatedly changed conclusions; fixed protocols with repeated runs, as in Chen et al.’s common code base and the repeated sampling of Wang et al., are part of the solution.
Related
- Zero-Shot Recognition
Recognizing image classes that had no training images, by relating images to descriptions of the classes such as attributes, word vectors or text; from attribute classifiers and compatibility functions to generated features and vision–language models, with the standard and generalized settings, the proposed splits of AwA2, CUB, SUN and aPY, and the harmonic mean.
- Transfer Learning
Reusing what a network learned on a large source task, typically by pretraining on many labelled images and then adapting it to a target task with few labels, through a linear probe on frozen features, partial fine-tuning or full fine-tuning.
- Fine-Tuning
Adapting a pretrained network to a new task by continuing to train some or all of its weights, and the choices that decide how well it works, including which layers to freeze, how fast each layer learns, how the new head starts, and how to keep what pretraining learned.
- Triplet Loss
A loss for learning embeddings that asks an anchor image to be closer to a positive of its own class than to a negative of another class by a margin, how it grew out of relative-comparison metric learning, and how the choice of triplets (random, semi-hard, batch-hard, distance-weighted) decides whether training learns, stalls or collapses.
- Fine-Grained Image Classification
Telling apart subordinate categories such as bird species, car models or aircraft variants, where classes differ in small local details; from part annotations and part detectors to bilinear pooling and learned attention, with the CUB-200-2011, Stanford Cars, FGVC-Aircraft, Stanford Dogs and iNaturalist benchmarks.
- ImageNet
A large database of web images organized by the noun hierarchy of WordNet, whose 1,000-class ILSVRC subset became the standard benchmark for image classification and the default source of pretrained networks.
References
- Fei-Fei, L., Fergus, R. & Perona, P. (2006). One-Shot Learning of Object Categories. IEEE Transactions on Pattern Analysis and Machine Intelligence, 28(4), 594–611. Cited for its title and subject only; not read.
- Koch, G., Zemel, R. & Salakhutdinov, R. (2015). Siamese Neural Networks for One-shot Image Recognition. ICML Deep Learning Workshop. Read in the authors' copy.
- Vinyals, O., Blundell, C., Lillicrap, T., Kavukcuoglu, K. & Wierstra, D. (2016). Matching Networks for One Shot Learning. Advances in Neural Information Processing Systems 29 (NIPS).
- Snell, J., Swersky, K. & Zemel, R. (2017). Prototypical Networks for Few-shot Learning. Advances in Neural Information Processing Systems 30 (NIPS).
- Finn, C., Abbeel, P. & Levine, S. (2017). Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks. Proceedings of the 34th International Conference on Machine Learning (ICML), PMLR 70, 1126–1135.
- Sung, F., Yang, Y., Zhang, L., Xiang, T., Torr, P. H. S. & Hospedales, T. M. (2018). Learning to Compare: Relation Network for Few-Shot Learning. IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR), 1199–1208.
- Chen, W.-Y., Liu, Y.-C., Kira, Z., Wang, Y.-C. F. & Huang, J.-B. (2019). A Closer Look at Few-shot Classification. International Conference on Learning Representations (ICLR). The paper was not read (OpenReview and arXiv are not used); described from the authors' project page and poster.
- Chen, W.-Y., Liu, Y.-C., Kira, Z., Wang, Y.-C. F. & Huang, J.-B. (2019). A Closer Look at Few-shot Classification: ICLR 2019 poster (authors' copy, accessed November 2026).
- Chen, W.-Y., Liu, Y.-C., Kira, Z., Wang, Y.-C. F. & Huang, J.-B. A Closer Look at Few-shot Classification: project page (accessed November 2026).
- Tian, Y., Wang, Y., Krishnan, D., Tenenbaum, J. B. & Isola, P. (2020). Rethinking Few-Shot Image Classification: A Good Embedding is All You Need? European Conference on Computer Vision (ECCV), Lecture Notes in Computer Science, 266–282.
- Kang, B., Liu, Z., Wang, X., Yu, F., Feng, J. & Darrell, T. (2019). Few-Shot Object Detection via Feature Reweighting. IEEE/CVF International Conference on Computer Vision (ICCV), 8419–8428.
- Wang, X., Huang, T. E., Darrell, T., Gonzalez, J. E. & Yu, F. (2020). Frustratingly Simple Few-Shot Object Detection. Proceedings of the 37th International Conference on Machine Learning (ICML), PMLR 119, 9919–9928.
- Lake, B. M. Omniglot data set for one-shot learning, GitHub repository brendenlake/omniglot: README, commit 057f034baf2ecb8530bc5710e5a23584d2a519cc (accessed November 2026).
- Ravi, S. & Larochelle, H. meta-learning-lstm, GitHub repository twitter/meta-learning-lstm: miniImageNet split files (data/miniImagenet), commit 0cffa2481619ce643d0951bd637bf05b23ef827a (accessed November 2026). Code for “Optimization as a Model for Few-Shot Learning” (ICLR 2017), which was not read.
- Ren, M. et al. few-shot-ssl-public, GitHub repository renmengye/few-shot-ssl-public: README and tieredImageNet split files (fewshot/data/tiered_imagenet_split), commit 4ce8726c036ae2811050e9571e8d2b4b46b2acac (accessed November 2026). Code for “Meta-Learning for Semi-Supervised Few-Shot Classification” (ICLR 2018), which was not read.
- Triantafillou, E. et al. Meta-Dataset, GitHub repository google-research/meta-dataset: README (dataset summary, leaderboard) and episode-sampling code and configuration, commit 167609505780a3dc604f50206253d65839093be9 (accessed November 2026). Code for “Meta-Dataset: A Dataset of Datasets for Learning to Learn from Few Examples” (ICLR 2020), which was not read.