TAI BUI
Back to curriculum
CapstonePython

Multimodal Evaluation

Training is half the loop. The other half is measurement. You build three evaluation surfaces from primitives: image-caption retrieval reported as R@1, R@5, R@10; visual question answering reported as exact match accuracy; and image captioning reported as BLEU-4. Each metric is a plain function over the model's outputs and a synthetic eval suite that runs in seconds.

TIME: ~90 minutesPREREQUISITES: Phase 19 lessons 58-62 (Track E foundations: encoder, transformer, projection, cross-attention fusion, pretraining)

Learning Objectives

  • Compute Recall@K from a similarity matrix between image and caption embeddings.
  • Compute exact-match VQA accuracy from a model that maps (image, question) pairs to a fixed answer vocabulary.
  • Compute BLEU-4 from generated and reference token sequences without any external library.
  • Run all three evals against a synthetic suite built on top of the trained model from lesson 62.

The Problem

Multimodal evaluation scores a model on held-out data along three surfaces: retrieval, visual question answering, and captioning. Training loss can't stand in for any of them. It measures fit on the training distribution, not whether the model can rank pairs in a held-out batch, answer a question, or write a caption a human would accept, and a plateaued loss curve is a poor signal that the model is finished.

The three surfaces:

  • Retrieval (R@1, R@5, R@10). Build the joint embedding for a query caption, rank every image in the eval pool by cosine, and report whether the matching image lands in the top 1, top 5, or top 10. The symmetric (image-to-text) form runs the same way.
  • Visual question answering (exact match). Given an (image, question) pair, the model outputs an answer token. Exact match is one bit per sample: the predicted answer either equals the reference answer or it doesn't. Average over the eval set.
  • Captioning (BLEU-4). Generate a caption, then take the geometric mean of the 1-gram through 4-gram precisions against the reference captions, with a brevity penalty. Multi-reference is the standard form: one image, several reference captions.

Each metric is a thin function, and I build all three in code so the math stays concrete and the eval surface stays in your hands. Real benchmark suites (MS-COCO, VQA v2, GQA, OK-VQA) plug into the same function shapes.

Warm-up0/3
1. A model's training loss keeps falling. What is the standard way to learn whether it will work on new data?Warm-up
2. A model maps images and captions into one shared vector space. What is the most natural way to check whether a caption fits an image?Warm-up
3. A guesser picks uniformly at random among 20 equally likely answers on every question. What accuracy does it get on average?Warm-up
Check: The Problem0/1
1. Why can't training loss alone show that a multimodal model is finished?Explain

The Concept

Mermaid diagram

Recall@K from a similarity matrix

Recall@K is the fraction of queries whose correct match lands in the top K results. To compute it, build the (N, N) cosine similarity matrix between image and caption embeddings and sort each row's columns by descending similarity. A row counts as a hit when its diagonal column index sits within the top K positions. Symmetric Recall@K (caption-to-image) comes from the transposed matrix, and both numbers get reported. On an N=100 eval, R@1 = 0.6 means 60 of the 100 captions retrieved their correct image as the top match.

VQA exact match

Exact match scores a VQA prediction as correct only when the predicted answer equals the reference answer. For each (image, question, answer), encode the image, embed the question, fuse the two via the decoder, and read out the next-token prediction at the last non-pad question position. Compare the predicted token id to the reference id, then average over the eval set. Real VQA datasets ship with multiple human-annotated answers per question and score with a soft-accuracy formula (1.0 if at least 3 of 10 annotators agree, scaled below that). Here I use single-answer exact match for clarity.

BLEU-4

BLEU-4 is the geometric mean of the modified 1-gram through 4-gram precisions, scaled by a brevity penalty:

text
BLEU-4 = BP * exp(mean(log p1, log p2, log p3, log p4))

Here p_n is the modified n-gram precision (the clipped count of generated n-grams that appear in any reference, divided by total generated n-grams), and BP is the brevity penalty:

text
BP = 1                if generated length > reference length
   = exp(1 - r/g)     otherwise, where r is the length of the reference closest
                      in length to the generated caption (ties go to the shorter) and g is generated

Small samples often leave some p_n at zero, which needs smoothing. The implementation uses Chen and Cherry "method 1" (add 1 to numerator and denominator for any zero count), the safest default for low-count regimes. Smoothing only rescues orders that have candidates but no matches. A generated caption shorter than 4 tokens has no 4-grams at all, so bleu4 returns 0.0 early even if the caption equals a reference exactly. The demo's captions are 8 tokens, so it never hits this.

Synthetic eval suite

The suite is a 50-sample eval built in memory from the same mock corpus pattern as lesson 62, using a held-out seed. It holds three lists:

  • pairs: 50 (image, caption_ids) pairs for retrieval.
  • vqa: 50 (image, question_ids, answer_id) triples.
  • caps: 50 (image, [reference_caption_ids, ...]) entries with up to 3 references per image.

The suite is deterministic from the seed and held out from the training corpus, so the metrics are computed on data the model never saw. Persisting the suite to JSON is left for you to add.

MetricRangeRandom baseline (N=50)
R@10 to 10.02 (1 / N)
R@50 to 10.10
R@100 to 10.20
VQA EM0 to 11 / vocab
BLEU-40 to 1small but nonzero

A 50-step training run on synthetic data won't produce high metrics, and not every metric clears its baseline. In our run R@5, R@10, text-to-image R@1 and BLEU-4 rise above it, but VQA exact match prints 0.0000 after training (0.0200 before) and image-to-text R@1 does the same. VQA is stuck at chance because the question is random tokens, the answer is the first token of the caption, and the image carries only a 7-level brightness signal, so nothing in the input predicts the answer. At N=50 each retrieval and VQA metric also moves in steps of 0.02, so one sample flipping is noise.

Check: The Concept0/22
1. What does R@K report for a retrieval eval?Define
2. In VQA scoring, what is exact match?Define
3. What is BLEU-4?Define
4. What does it mean that a captioning metric is multi-reference?Define
5. What makes an eval suite held-out?Define
6. In BLEU-4, what is the modified n-gram precision p_n?Define
7. In the (N, N) similarity matrix, how does recall_at_k find the correct match for image i?Explain
8. How is caption-to-image recall obtained from the same similarity matrix?Explain
9. Why does BLEU-4 combine the n-gram precisions with a geometric mean instead of an arithmetic mean?Explain
10. Why does a generated caption usually score higher against several references than against one?Explain
11. How does the lesson's BLEU-4 handle an n-gram order with zero matches?Explain
12. What does the brevity penalty do in BLEU-4?Explain
13. VQA question tokens are padded to max_len. Where does the eval read the model's answer?Explain
14. Why can VQA be scored by comparing the predicted token id with the reference id, with no similarity score?Explain
15. In the lesson's 50-step demo, which trained metric does not rise above its random baseline, and why?Explain
16. On an N=100 eval, one caption's correct image lands at rank 7. Which of R@1, R@5, and R@10 count that query as a hit?Apply
17. A generated caption has 4 tokens and the references have 8, 12, and 20 tokens. What brevity penalty does the lesson's BLEU-4 apply?Apply
18. A generated caption [1, 2, 3, 4, 5, 6] is scored against references [1, 2, 3, 4] and [1, 2, 3, 4, 5, 6, 7, 8], so every generated n-gram has a match. What is its BLEU-4?Apply
19. A VQA question vector with max_len 8 is [7, 3, 9, 2, 5, 0, 0, 0], and 0 is the pad id. Which position's logits does evaluate read the predicted answer from?Apply
20. After 50 steps of training, the model scores R@1 = 0.04 and R@10 = 0.22 on the N=50 eval. What is the fair reading?Analyze
21. A teammate reports R@1 = 0.9 for the model, measured on 50 pairs drawn from the training corpus. What is wrong with that number?Analyze
22. Model A puts its hits at rank 1 and model B puts its hits at rank 10, with the same 50% of queries hitting within the top 10. Which of the lesson's retrieval numbers separates them?Analyze

Build It

code/main.py implements:

  • recall_at_k(sim_matrix, k), returning a float in [0, 1] for both directions.
  • vqa_exact_match(predictions, references), returning the mean over int equality.
  • bleu4(generated, references, smoothing=True), with multi-reference support.
  • build_eval_suite(seed, n_samples, vocab_size, max_len), returning three deterministic eval lists.
  • evaluate(model, suite), which runs all three metrics and returns a dict of numbers.
  • A demo that loads a freshly-initialized multimodal model from lesson 62, evaluates it, trains it for 50 steps, and evaluates again, printing the before/after metrics.

Run it:

bash
python3 code/main.py

Output: the before/after metric table. Retrieval moves from near-random toward the model's learned signal (R@5 and R@10 rise, while image-to-text R@1 can print 0.0000), VQA stays at chance (0.0000 after training in our run), and BLEU-4 improves from about 0.12 to 0.17 (the synthetic structure is enough for a 4-gram precision lift).

Check: Build It0/3
1. sim = [[0.9, 0.1, 0.8], [0.2, 0.3, 0.1], [0.5, 0.6, 0.4]], where row i is image i and column j is caption j. What does recall_at_k(sim, 1) return as (i2t, t2i)?Apply
2. For the same matrix, sim = [[0.9, 0.1, 0.8], [0.2, 0.3, 0.1], [0.5, 0.6, 0.4]], what does recall_at_k(sim, 2) return as (i2t, t2i)?Apply
3. In main.py, bleu4 on a 3-token caption that exactly equals a reference returns 0.0 even with smoothing on. Which part of the implementation explains it?Analyze

Use It

Each metric maps onto a production benchmark:

  • Retrieval. MS-COCO 5K val, Flickr30K, and ImageNet zero-shot are all R@K problems on the same similarity matrix. Swap in the real files and the function signature stays unchanged.
  • VQA. VQA v2, GQA, and OK-VQA use the same exact-match shape, with soft accuracy instead of single-answer EM for VQA v2.
  • BLEU-4. MS-COCO captioning, NoCaps, and Flickr30K captioning use BLEU-4 alongside CIDEr and METEOR. Adding CIDEr is one more function.

For real benchmarks, replace build_eval_suite with a real loader and keep the function bodies. The math doesn't depend on the benchmark.

Check: Use It0/4
1. How does scoring on VQA v2 differ from the single-answer exact match built in this lesson?Explain
2. You replace build_eval_suite with a real MS-COCO loader. What else has to change in the metric functions?Explain
3. You must add CIDEr to the captioning evaluation on a real benchmark and keep retrieval and VQA untouched. Which design follows the lesson's structure?Design
4. You must score a VQA v2 eval where every question has ten human answers, the way VQA v2 does. Which change keeps the rest of the pipeline as it is?Design

Tests

code/test_main.py covers:

  • recall@k returns 1.0 on a perfect identity similarity matrix and 0.0 on a flipped one for k < N
  • recall@k respects k <= N upper bound
  • bleu4 returns 1.0 when generated equals one of the references exactly
  • bleu4 returns 0.0 on disjoint vocabulary
  • vqa exact match equals the fraction of equal pairs
  • build_eval_suite returns the expected number of pairs, vqa items, and caption entries

Run them:

bash
python3 -m unittest code/test_main.py
Check: Tests0/4
1. The generated tokens are eight 1s and the single reference is eight 2s, so no n-gram matches. What does bleu4 return with smoothing on, and with smoothing off?Apply
2. vqa_exact_match is called with predictions [1, 2, 3, 4] and references [1, 0, 3, 0]. What does it return?Apply
3. A 6x6 similarity matrix has 0.0 on the diagonal and 10.0 everywhere else. What does recall_at_k(sim, 5) return?Apply
4. sim is a 4x4 identity matrix. What does recall_at_k(sim, 5) do?Apply

Exercises

  1. Add CIDEr to the captioning metrics. CIDEr uses TF-IDF weighting on n-grams, which rewards informative tokens.

  2. Implement soft-accuracy VQA: multiple human answers per question, accuracy is min(human_count / 3, 1) if any matches. Replicates VQA v2.

  3. Add a NaN-safe variant of bleu4 that handles empty generated sequences without crashing.

  4. Compute mean reciprocal rank (MRR) alongside R@K. MRR is sensitive to where the correct item lands beyond the top K; R@K is sensitive to whether it lands in the top K.

  5. Run the eval on the model at six checkpoints during training (step 0, 10, 20, 30, 40, 50) and plot the learning curve. Confirm the metric trajectories track the loss trajectory.

Key Terms

TermWhat it means
R@KFraction of queries where the correct match lands in the top K results
Exact matchThe simplest VQA scoring: predicted answer equals reference
BLEU-4Geometric mean of 1- to 4-gram precisions, with brevity penalty
Multi-referenceA captioning metric accepts several reference captions per image
Held-outThe eval set is sampled from a seed disjoint from the training corpus
Author's Note

I'd read the BEFORE column of the demo output first. The table above lists the random baselines (0.02 for R@1 at N=50, for instance), and most trained metrics land above them, but VQA exact match and image-to-text R@1 do not. I wouldn't read much into the absolute values from a 50-step run on synthetic data. The gap to the baseline is what I'd look at, metric by metric.

My bet is that single-answer exact match is the right place to start for VQA. It's one bit per sample, so you can check the number by hand before moving to the soft-accuracy version in the exercises.

Further Reading

  • VQA v2 paper for the soft-accuracy formula and dataset statistics.
  • CIDEr paper for TF-IDF-weighted n-gram captioning.
  • BLEU original (Papineni et al., 2002) for the smoothing variants.
  • MS-COCO captioning eval scripts for the canonical reference implementation.

Code