rusticolus commited on
Commit
18812c2
·
verified ·
1 Parent(s): 6c514a7

Update measure_recall.py

Browse files
Files changed (1) hide show
  1. measure_recall.py +88 -88
measure_recall.py CHANGED
@@ -1,89 +1,89 @@
1
- import torch
2
- import clip
3
- import deeplake
4
- from tqdm import tqdm
5
- from tabulate import tabulate
6
-
7
- # --- SETTINGS ---
8
- EMBEDDINGS_PATH = "flickr_embeddings.pt"
9
- DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
10
- BATCH_SIZE = 32
11
- # ----------------
12
-
13
- def calculate_recall():
14
- print(f"Loading CLIP on {DEVICE}...")
15
- model, _ = clip.load("ViT-B/32", device=DEVICE)
16
-
17
- print(f"Loading Image Index from {EMBEDDINGS_PATH}...")
18
- try:
19
- # Load embeddings and force them to the correct device
20
- image_embeds = torch.load(EMBEDDINGS_PATH, map_location=DEVICE)
21
- except FileNotFoundError:
22
- print(f"ERROR: Could not find '{EMBEDDINGS_PATH}'. Run indexer.py first.")
23
- return
24
-
25
- num_images = len(image_embeds)
26
- print(f"Loaded {num_images} image fingerprints.")
27
-
28
- print("Connecting to Deep Lake to fetch captions...")
29
- # Ensure this matches the dataset used in indexer.py
30
- ds = deeplake.load('hub://activeloop/flickr30k', access_method="stream")
31
-
32
- text_embeds = []
33
-
34
- print("Encoding Captions (this acts as the 'Search Query')...")
35
- with torch.no_grad():
36
- for i in tqdm(range(0, num_images, BATCH_SIZE)):
37
- batch_captions = []
38
- end_idx = min(i + BATCH_SIZE, num_images)
39
-
40
- # Fetch batch of captions
41
- for idx in range(i, end_idx):
42
- try:
43
- # Robust text extraction
44
- txt = ds[idx].caption_0.text().numpy().item()
45
- except AttributeError:
46
- txt = ds[idx].caption_0.numpy().item()
47
- except Exception:
48
- txt = "unknown"
49
-
50
- batch_captions.append(str(txt))
51
-
52
- # Tokenize and Encode
53
- text_tokens = clip.tokenize(batch_captions, truncate=True).to(DEVICE)
54
- batch_features = model.encode_text(text_tokens)
55
-
56
- # Normalize
57
- batch_features /= batch_features.norm(dim=-1, keepdim=True)
58
- text_embeds.append(batch_features)
59
-
60
- text_embeds = torch.cat(text_embeds)
61
-
62
- print("\nCalculating Similarity Matrix...")
63
-
64
- # --- FIX: Force both to float32 to avoid mismatched types (Half vs Float) ---
65
- image_embeds = image_embeds.float()
66
- text_embeds = text_embeds.float()
67
-
68
- # Cosine similarity
69
- similarity = text_embeds @ image_embeds.t()
70
-
71
- print("Computing Recall Metrics...")
72
- results = {}
73
- k_values = [1, 5, 10]
74
-
75
- _, top_indices = similarity.topk(max(k_values), dim=1)
76
-
77
- for k in k_values:
78
- correct_count = 0
79
- for i in range(num_images):
80
- # Check if the correct index 'i' is in the top 'k' predictions
81
- if i in top_indices[i, :k]:
82
- correct_count += 1
83
- results[f"R@{k}"] = (correct_count / num_images) * 100
84
-
85
- print("\n--- RETRIEVAL RESULTS (Zero-Shot) ---")
86
- print(tabulate([[k, f"{v:.2f}%"] for k, v in results.items()], headers=["Metric", "Score"]))
87
-
88
- if __name__ == "__main__":
89
  calculate_recall()
 
1
+ import torch
2
+ import clip
3
+ import deeplake
4
+ from tqdm import tqdm
5
+ from tabulate import tabulate
6
+
7
+ # --- SETTINGS ---
8
+ EMBEDDINGS_PATH = "flickr_embeddings.pt"
9
+ DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
10
+ BATCH_SIZE = 32
11
+ # ----------------
12
+
13
+ def calculate_recall():
14
+ print(f"Loading CLIP on {DEVICE}...")
15
+ model, _ = clip.load("ViT-B/32", device=DEVICE)
16
+
17
+ print(f"Loading Image Index from {EMBEDDINGS_PATH}...")
18
+ try:
19
+ # Load embeddings and force them to the correct device
20
+ image_embeds = torch.load(EMBEDDINGS_PATH, map_location=DEVICE)
21
+ except FileNotFoundError:
22
+ print(f"ERROR: Could not find '{EMBEDDINGS_PATH}'. Run indexer.py first.")
23
+ return
24
+
25
+ num_images = len(image_embeds)
26
+ print(f"Loaded {num_images} image fingerprints.")
27
+
28
+ print("Connecting to Deep Lake to fetch captions...")
29
+ # Ensure this matches the dataset used in indexer.py
30
+ ds = deeplake.load('hub://activeloop/flickr30k', access_method="stream")
31
+
32
+ text_embeds = []
33
+
34
+ print("Encoding Captions (this acts as the 'Search Query')...")
35
+ with torch.no_grad():
36
+ for i in tqdm(range(0, num_images, BATCH_SIZE)):
37
+ batch_captions = []
38
+ end_idx = min(i + BATCH_SIZE, num_images)
39
+
40
+ # Fetch batch of captions
41
+ for idx in range(i, end_idx):
42
+ try:
43
+ # Robust text extraction
44
+ txt = ds[idx].caption_0.text().numpy().item()
45
+ except AttributeError:
46
+ txt = ds[idx].caption_0.numpy().item()
47
+ except Exception:
48
+ txt = "unknown"
49
+
50
+ batch_captions.append(str(txt))
51
+
52
+ # Tokenize and Encode
53
+ text_tokens = clip.tokenize(batch_captions, truncate=True).to(DEVICE)
54
+ batch_features = model.encode_text(text_tokens)
55
+
56
+ # Normalize
57
+ batch_features /= batch_features.norm(dim=-1, keepdim=True)
58
+ text_embeds.append(batch_features)
59
+
60
+ text_embeds = torch.cat(text_embeds)
61
+
62
+ print("\nCalculating Similarity Matrix...")
63
+
64
+ # Force both to float32 to avoid mismatched types
65
+ image_embeds = image_embeds.float()
66
+ text_embeds = text_embeds.float()
67
+
68
+ # Cosine similarity
69
+ similarity = text_embeds @ image_embeds.t()
70
+
71
+ print("Computing Recall Metrics...")
72
+ results = {}
73
+ k_values = [1, 5, 10]
74
+
75
+ _, top_indices = similarity.topk(max(k_values), dim=1)
76
+
77
+ for k in k_values:
78
+ correct_count = 0
79
+ for i in range(num_images):
80
+ # Check if the correct index 'i' is in the top 'k' predictions
81
+ if i in top_indices[i, :k]:
82
+ correct_count += 1
83
+ results[f"R@{k}"] = (correct_count / num_images) * 100
84
+
85
+ print("\n--- RETRIEVAL RESULTS (Zero-Shot) ---")
86
+ print(tabulate([[k, f"{v:.2f}%"] for k, v in results.items()], headers=["Metric", "Score"]))
87
+
88
+ if __name__ == "__main__":
89
  calculate_recall()