PIXELBANKv9.1.0
Menu

Problem Statement

A strong training-free baseline (Tip-Adapter, and CLIP's own linear-probe cousins) classifies a query image by a similarity-weighted vote of its nearest neighbors in a labeled support set of embeddings. Implement it.

Background

Given a query embedding q and a support set of (embedding, label) pairs, score every support example by cosine similarity to q, take the top-k most similar, and let each vote for its label with a weight of exp(beta * (sim - 1)) (the sharpening used by Tip-Adapter; beta > 0). The predicted class is the label with the greatest total weight.

Tie-breaking, in order:

  1. Highest total vote weight.
  2. If tied, the label whose single best (highest-similarity) neighbor is more similar.
  3. If still tied, the smaller label value.

Assume all embeddings are already L2-normalized, so cosine similarity is the dot product.

Your Task

Implement:

def knn_zero_shot(query, support_embs, support_labels, k, beta):

Return the predicted label (an int).

Input Format

  • query: list of floats (unit vector).
  • support_embs: M x D nested list (unit vectors).
  • support_labels: list of M int labels.
  • k (int), beta (float).

Output Format

  • A single int label.

Sample

q = [1.0, 0.0]
se = [[1.0, 0.0], [0.9, 0.44], [0.0, 1.0]]
sl = [0, 0, 1]
print(knn_zero_shot(q, se, sl, 2, 5.0))

Output:

0

Example:

Input:
q = [1.0, 0.0]
se = [[1.0, 0.0], [0.9, 0.44], [0.0, 1.0]]
sl = [0, 0, 1]
print(knn_zero_shot(q, se, sl, 2, 5.0))
Output:
0
Reasoning:
  • Compute cosine similarities (dot products) between the query q=[1.0,0.0]q=[1.0, 0.0] and each support embedding to determine relevance:
    • Support 0: [1.0,0.0]⋅[1.0,0.0]=1.0[1.0, 0.0] \cdot [1.0, 0.0] = 1.0
    • Support 1: [0.9,0.44]⋅[1.0,0.0]=0.9[0.9, 0.44] \cdot [1.0, 0.0] = 0.9
    • Support 2: [0.0,1.0]⋅[1.0,0.0]=0.0[0.0, 1.0] \cdot [1.0, 0.0] = 0.0
  • Select the top-kk neighbors with k=2k=2 based on highest similarity: Support 0 (sim 1.01.0) and Support 1 (sim 0.90.9). Support 2 is excluded.
  • Calculate the vote weight for each selected neighbor using the formula w=exp⁡(β⋅(s−1))w = \exp(\beta \cdot (s - 1)) with β=5.0\beta=5.0:
    • Support 0 (Label 0): w0=exp⁡(5.0⋅(1.0−1.0))=exp⁡(0)=1.0w_0 = \exp(5.0 \cdot (1.0 - 1.0)) = \exp(0) = 1.0
    • Support 1 (Label 0): w1=exp⁡(5.0⋅(0.9−1.0))=exp⁡(−0.5)≈0.6065w_1 = \exp(5.0 \cdot (0.9 - 1.0)) = \exp(-0.5) \approx 0.6065
  • Aggregate total weights and track the best similarity for each label:
    • Label 0: Total weight =1.0+0.6065=1.6065= 1.0 + 0.6065 = 1.6065; Best similarity =1.0= 1.0
    • Label 1: Total weight =0= 0 (no neighbors selected); Best similarity is undefined/0
  • Compare labels to determine the winner: Label 0 has a total weight of 1.60651.6065, which is strictly greater than Label 1's weight of 00, so Label 0 is selected without needing tie-breakers.
  • The final output is 0

Constraints:

  • 1 <= k <= M <= 5000, 1 <= D <= 1024, beta > 0.
  • Similarity is the dot product (inputs are unit vectors).
  • Top-k by similarity; ties within selection go to the smaller support index.
  • Apply the three-level tie-break for the final label exactly as described.
solution.py

Test Results

0/0
Run code to see test results.
Weighted k-NN Zero-Shot Transfer - Hard | PixelBank