v9.1.1
Menu

Recall@K for Image-Text Retrieval

mediumFREERetrieval & Zero-Shot TransferVision-Language ModelsVLM 1: Vision-Language Models

Problem Statement

Given a query-by-gallery similarity matrix and the index of the correct gallery item for each query, compute Recall@K for several values of K.

Background

Recall@K is the standard retrieval metric for CLIP-style models on COCO and Flickr30k: the fraction of queries whose ground-truth match appears anywhere in the top K results.

For query i, sort the gallery by descending similarity and find the 0-indexed position of ground_truth[i]:

ranki=∣{ j:sim[i][j]>sim[i][gi] }∣(with ties broken by index)\text{rank}_i = \left|\{\, j : \text{sim}[i][j] > \text{sim}[i][g_i] \,\}\right| \quad\text{(with ties broken by index)}

R@K=1n∑i=1n1 ⁣[ranki<K]\text{R@}K = \frac{1}{n}\sum_{i=1}^{n} \mathbb{1}\!\left[\text{rank}_i < K\right]

Two details decide whether your number matches a published one. First, ranks are 0-indexed against K, so R@1 means rank == 0. Second, ties must be broken deterministically - here, toward the lower gallery index - otherwise a model that returns identical scores appears to score differently on every run.

Recall@K is monotone non-decreasing in K, and R@m over an m-item gallery is always 1.0.

Your Task

Implement:

def recall_at_k(sim_matrix, ground_truth, ks):

Return a list of floats, one per entry of ks in the given order, each rounded to 4 decimals.

Input Format

  • sim_matrix - n x m nested list of floats, row i scoring query i against every gallery item
  • ground_truth - list of n ints, the correct gallery index per query
  • ks - list of positive ints (not necessarily sorted)

Output Format

A list of floats rounded to 4 decimals, same length and order as ks.

Sample

sims = [[0.9, 0.2, 0.1], [0.3, 0.4, 0.8], [0.5, 0.7, 0.6]]
print(recall_at_k(sims, [0, 2, 0], [1, 2]))

Output:

[0.6667, 0.6667]

Example

Input
sims = [[0.9, 0.2, 0.1], [0.3, 0.4, 0.8], [0.5, 0.7, 0.6]]
print(recall_at_k(sims, [0, 2, 0], [1, 2]))
Output
[0.6667, 0.6667]
Reasoning
  • Inputs: a 3×33 \times 3 similarity matrix (row ii = query ii scored against gallery items 0, 1, 2), the correct gallery index for each query (g=0,2,0g = 0, 2, 0), and the cutoffs K=1K = 1 and K=2K = 2.
  • Query 0: its answer (item 0) scores 0.90.9, and no other item beats it, so rank0=0\text{rank}_0 = 0.
  • Query 1: its answer (item 2) scores 0.80.8, above 0.30.3 and 0.40.4, so rank1=0\text{rank}_1 = 0.
  • Query 2: its answer (item 0) scores 0.50.5, but items 1 and 2 score 0.70.7 and 0.60.6. Two items beat it, so rank2=2\text{rank}_2 = 2.
  • R@1 counts ranks <1< 1: queries 0 and 1, giving 2/3≈0.66672/3 \approx 0.6667. R@2 counts ranks <2< 2: still only queries 0 and 1, since rank 2 is not below 2. That gives 0.66670.6667 again.
  • Output: [0.6667, 0.6667], one value per cutoff in the order given. Notice R@K never drops as KK grows, and with K=3K = 3 (the whole gallery) it would reach 1.01.0.

Constraints

  • 1 <= n <= 200, 1 <= m <= 200
  • Ranks are 0-INDEXED; a query counts toward R@K when rank < K
  • Break similarity ties toward the LOWER gallery index (stable sort of negated scores)
  • Preserve the order of ks in the output
  • Round each recall to 4 decimals

Learn this in

More from VLM 1: Vision-Language Models

solution.py

Test results

Sign in to run your code against the test cases.