GitHub Actions commited on
Commit
ca43282
·
1 Parent(s): a2e330e

Sync from GitHub Actions

Browse files
notebooks/autocatalogai_model_comparison.ipynb CHANGED
@@ -219,7 +219,7 @@
219
  },
220
  {
221
  "cell_type": "code",
222
- "execution_count": 4,
223
  "id": "1ac434ae",
224
  "metadata": {
225
  "execution": {
@@ -249,16 +249,9 @@
249
  "\n",
250
  "def safe_torch_load(path, map_location=\"cpu\"):\n",
251
  " try:\n",
252
- " return torch.load(\n",
253
- " path,\n",
254
- " map_location=map_location,\n",
255
- " weights_only=True,\n",
256
- " )\n",
257
  " except (TypeError, RuntimeError):\n",
258
- " return torch.load(\n",
259
- " path,\n",
260
- " map_location=map_location,\n",
261
- " )\n",
262
  "\n",
263
  "\n",
264
  "def download_repo_artifacts(repo_id, include_rules=False):\n",
@@ -287,24 +280,16 @@
287
  " }\n",
288
  "\n",
289
  " if include_rules:\n",
290
- " artifacts[\"consistency_rules\"] = load_json(\n",
291
- " paths[\"consistency_rules.json\"]\n",
292
- " )\n",
293
  "\n",
294
  " return artifacts\n",
295
  "\n",
296
  "\n",
297
  "v1_artifacts = download_repo_artifacts(V1_REPO_ID)\n",
298
- "v2_artifacts = download_repo_artifacts(\n",
299
- " V2_REPO_ID,\n",
300
- " include_rules=True,\n",
301
- ")\n",
302
  "\n",
303
  "if v1_artifacts[\"label_maps\"] != v2_artifacts[\"label_maps\"]:\n",
304
- " raise ValueError(\n",
305
- " \"V1 and V2 label maps are different. \"\n",
306
- " \"A direct comparison would not be valid.\"\n",
307
- " )\n",
308
  "\n",
309
  "label_maps = v2_artifacts[\"label_maps\"]\n",
310
  "v1_config = v1_artifacts[\"config\"]\n",
@@ -325,7 +310,7 @@
325
  "}\n",
326
  "\n",
327
  "print(\"Base model:\", MODEL_NAME)\n",
328
- "print(\"Task classes:\", task_num_classes)\n"
329
  ]
330
  },
331
  {
@@ -340,7 +325,7 @@
340
  },
341
  {
342
  "cell_type": "code",
343
- "execution_count": 5,
344
  "id": "bf1f57de",
345
  "metadata": {
346
  "execution": {
@@ -378,11 +363,7 @@
378
  }
379
  ],
380
  "source": [
381
- "raw_dataset = load_dataset(\n",
382
- " DATASET_NAME,\n",
383
- " split=\"train\",\n",
384
- ")\n",
385
- "\n",
386
  "missing_columns = [\n",
387
  " task\n",
388
  " for task in TASKS\n",
@@ -393,9 +374,7 @@
393
  " raise ValueError(\"Dataset must contain an image column.\")\n",
394
  "\n",
395
  "if missing_columns:\n",
396
- " raise ValueError(\n",
397
- " f\"Dataset is missing task columns: {missing_columns}\"\n",
398
- " )\n",
399
  "\n",
400
  "\n",
401
  "def is_valid_row(row):\n",
@@ -404,12 +383,10 @@
404
  "\n",
405
  " for task in TASKS:\n",
406
  " value = row.get(task)\n",
407
- "\n",
408
  " if value is None:\n",
409
  " return False\n",
410
  "\n",
411
  " value = str(value).strip()\n",
412
- "\n",
413
  " if not value:\n",
414
  " return False\n",
415
  "\n",
@@ -420,7 +397,6 @@
420
  "\n",
421
  "\n",
422
  "clean_dataset = raw_dataset.filter(is_valid_row)\n",
423
- "\n",
424
  "print(\"Raw samples:\", len(raw_dataset))\n",
425
  "print(\"Clean samples:\", len(clean_dataset))\n",
426
  "print(\"Dataset fingerprint:\", clean_dataset._fingerprint)\n"
@@ -438,7 +414,7 @@
438
  },
439
  {
440
  "cell_type": "code",
441
- "execution_count": 6,
442
  "id": "2f6aa87a",
443
  "metadata": {
444
  "execution": {
@@ -474,29 +450,20 @@
474
  "df = pd.DataFrame(metadata)\n",
475
  "df[\"dataset_idx\"] = np.arange(len(clean_dataset))\n",
476
  "\n",
477
- "\n",
478
  "def make_safe_stratify_labels(series):\n",
479
  " counts = series.value_counts()\n",
480
- "\n",
481
  " return series.apply(\n",
482
- " lambda value: (\n",
483
- " value\n",
484
- " if counts[value] >= 2\n",
485
- " else \"__rare__\"\n",
486
- " )\n",
487
  " )\n",
488
  "\n",
489
  "\n",
490
  "all_indices = df.index.to_numpy()\n",
491
- "\n",
492
  "try:\n",
493
  " train_idx, temporary_idx = train_test_split(\n",
494
  " all_indices,\n",
495
  " test_size=VAL_RATIO + TEST_RATIO,\n",
496
  " random_state=SEED,\n",
497
- " stratify=make_safe_stratify_labels(\n",
498
- " df[\"articleType\"]\n",
499
- " ),\n",
500
  " )\n",
501
  "except ValueError:\n",
502
  " train_idx, temporary_idx = train_test_split(\n",
@@ -506,15 +473,12 @@
506
  " )\n",
507
  "\n",
508
  "temporary_df = df.loc[temporary_idx]\n",
509
- "\n",
510
  "try:\n",
511
  " val_idx, test_idx = train_test_split(\n",
512
  " temporary_idx,\n",
513
  " test_size=TEST_RATIO / (VAL_RATIO + TEST_RATIO),\n",
514
  " random_state=SEED,\n",
515
- " stratify=make_safe_stratify_labels(\n",
516
- " temporary_df[\"articleType\"]\n",
517
- " ),\n",
518
  " )\n",
519
  "except ValueError:\n",
520
  " val_idx, test_idx = train_test_split(\n",
@@ -531,27 +495,12 @@
531
  "assert set(train_idx).isdisjoint(test_idx)\n",
532
  "assert set(val_idx).isdisjoint(test_idx)\n",
533
  "\n",
534
- "train_df.to_csv(\n",
535
- " PROCESSED_DIR / \"train_v2.csv\",\n",
536
- " index=False,\n",
537
- ")\n",
538
- "val_df.to_csv(\n",
539
- " PROCESSED_DIR / \"val_v2.csv\",\n",
540
- " index=False,\n",
541
- ")\n",
542
- "test_df.to_csv(\n",
543
- " PROCESSED_DIR / \"test_v2.csv\",\n",
544
- " index=False,\n",
545
- ")\n",
546
- "\n",
547
- "test_index_bytes = np.asarray(\n",
548
- " sorted(test_idx),\n",
549
- " dtype=np.int64,\n",
550
- ").tobytes()\n",
551
  "\n",
552
- "test_split_sha256 = hashlib.sha256(\n",
553
- " test_index_bytes\n",
554
- ").hexdigest()\n",
555
  "\n",
556
  "print(\"Train:\", len(train_df))\n",
557
  "print(\"Validation:\", len(val_df))\n",
@@ -569,7 +518,7 @@
569
  },
570
  {
571
  "cell_type": "code",
572
- "execution_count": 7,
573
  "id": "ee239b3e",
574
  "metadata": {
575
  "execution": {
@@ -591,39 +540,20 @@
591
  }
592
  ],
593
  "source": [
594
- "processor = CLIPImageProcessor.from_pretrained(\n",
595
- " MODEL_NAME\n",
596
- ")\n",
597
- "\n",
598
- "\n",
599
- "def extract_color_features(\n",
600
- " image,\n",
601
- " image_size=COLOR_IMAGE_SIZE,\n",
602
- "):\n",
603
- " image = image.convert(\"RGB\").resize(\n",
604
- " (image_size, image_size)\n",
605
- " )\n",
606
  "\n",
 
 
607
  " margin = int(image_size * 0.10)\n",
608
- "\n",
609
  " image = image.crop(\n",
610
  " (\n",
611
- " margin,\n",
612
- " margin,\n",
613
- " image_size - margin,\n",
614
- " image_size - margin,\n",
615
  " )\n",
616
  " )\n",
617
  "\n",
618
- " rgb = np.asarray(\n",
619
- " image,\n",
620
- " dtype=np.float32,\n",
621
- " ) / 255.0\n",
622
- "\n",
623
- " hsv = np.asarray(\n",
624
- " image.convert(\"HSV\"),\n",
625
- " dtype=np.float32,\n",
626
- " ) / 255.0\n",
627
  "\n",
628
  " rgb_flat = rgb.reshape(-1, 3)\n",
629
  " hsv_flat = hsv.reshape(-1, 3)\n",
@@ -631,90 +561,43 @@
631
  " saturation = hsv_flat[:, 1]\n",
632
  " value = hsv_flat[:, 2]\n",
633
  "\n",
634
- " foreground_mask = (\n",
635
- " (saturation > 0.08)\n",
636
- " | (value < 0.92)\n",
637
- " )\n",
638
- "\n",
639
  " if foreground_mask.sum() < 256:\n",
640
- " foreground_mask = np.ones(\n",
641
- " len(hsv_flat),\n",
642
- " dtype=bool,\n",
643
- " )\n",
644
  "\n",
645
  " selected_rgb = rgb_flat[foreground_mask]\n",
646
  " selected_hsv = hsv_flat[foreground_mask]\n",
647
  "\n",
648
- " hue_hist, _ = np.histogram(\n",
649
- " selected_hsv[:, 0],\n",
650
- " bins=12,\n",
651
- " range=(0.0, 1.0),\n",
652
- " )\n",
653
- "\n",
654
- " saturation_hist, _ = np.histogram(\n",
655
- " selected_hsv[:, 1],\n",
656
- " bins=8,\n",
657
- " range=(0.0, 1.0),\n",
658
- " )\n",
659
- "\n",
660
- " value_hist, _ = np.histogram(\n",
661
- " selected_hsv[:, 2],\n",
662
- " bins=8,\n",
663
- " range=(0.0, 1.0),\n",
664
- " )\n",
665
  "\n",
666
  " hue_hist = hue_hist.astype(np.float32)\n",
667
  " saturation_hist = saturation_hist.astype(np.float32)\n",
668
  " value_hist = value_hist.astype(np.float32)\n",
669
  "\n",
670
  " hue_hist /= max(hue_hist.sum(), 1.0)\n",
671
- " saturation_hist /= max(\n",
672
- " saturation_hist.sum(),\n",
673
- " 1.0,\n",
674
- " )\n",
675
  " value_hist /= max(value_hist.sum(), 1.0)\n",
676
  "\n",
677
- " rgb_mean = selected_rgb.mean(\n",
678
- " axis=0\n",
679
- " ).astype(np.float32)\n",
680
- "\n",
681
- " rgb_std = selected_rgb.std(\n",
682
- " axis=0\n",
683
- " ).astype(np.float32)\n",
684
- "\n",
685
- " rgb_median = np.median(\n",
686
- " selected_rgb,\n",
687
- " axis=0,\n",
688
- " ).astype(np.float32)\n",
689
  "\n",
690
  " features = np.concatenate(\n",
691
  " [\n",
692
- " hue_hist,\n",
693
- " saturation_hist,\n",
694
- " value_hist,\n",
695
- " rgb_mean,\n",
696
- " rgb_std,\n",
697
- " rgb_median,\n",
698
  " ]\n",
699
  " ).astype(np.float32)\n",
700
  "\n",
701
  " if features.shape[0] != COLOR_FEATURE_DIM:\n",
702
- " raise ValueError(\n",
703
- " f\"Expected {COLOR_FEATURE_DIM} color features, \"\n",
704
- " f\"got {features.shape[0]}\"\n",
705
- " )\n",
706
- "\n",
707
  " return features\n",
708
  "\n",
709
- "\n",
710
  "class ComparisonDataset(Dataset):\n",
711
- " def __init__(\n",
712
- " self,\n",
713
- " source_dataset,\n",
714
- " indices,\n",
715
- " processor,\n",
716
- " label_maps,\n",
717
- " ):\n",
718
  " self.source_dataset = source_dataset\n",
719
  " self.indices = list(map(int, indices))\n",
720
  " self.processor = processor\n",
@@ -726,14 +609,12 @@
726
  " def __getitem__(self, index):\n",
727
  " global_index = self.indices[index]\n",
728
  " item = self.source_dataset[global_index]\n",
729
- "\n",
730
  " image = item[\"image\"]\n",
731
  "\n",
732
  " if not isinstance(image, Image.Image):\n",
733
  " image = Image.open(image)\n",
734
  "\n",
735
  " image = image.convert(\"RGB\")\n",
736
- "\n",
737
  " pixel_values = self.processor(\n",
738
  " images=image,\n",
739
  " return_tensors=\"pt\",\n",
@@ -764,12 +645,8 @@
764
  "\n",
765
  "def collate_batch(batch):\n",
766
  " return {\n",
767
- " \"pixel_values\": torch.stack(\n",
768
- " [item[\"pixel_values\"] for item in batch]\n",
769
- " ),\n",
770
- " \"color_features\": torch.stack(\n",
771
- " [item[\"color_features\"] for item in batch]\n",
772
- " ),\n",
773
  " \"labels\": {\n",
774
  " task: torch.stack(\n",
775
  " [item[\"labels\"][task] for item in batch]\n",
@@ -799,7 +676,7 @@
799
  " collate_fn=collate_batch,\n",
800
  ")\n",
801
  "\n",
802
- "print(\"Test samples:\", len(test_dataset))\n"
803
  ]
804
  },
805
  {
@@ -812,7 +689,7 @@
812
  },
813
  {
814
  "cell_type": "code",
815
- "execution_count": 8,
816
  "id": "65d75793",
817
  "metadata": {
818
  "execution": {
@@ -827,15 +704,8 @@
827
  "outputs": [],
828
  "source": [
829
  "class ClassificationHead(nn.Module):\n",
830
- " def __init__(\n",
831
- " self,\n",
832
- " embedding_dim,\n",
833
- " num_classes,\n",
834
- " hidden_dim=512,\n",
835
- " dropout=0.2,\n",
836
- " ):\n",
837
  " super().__init__()\n",
838
- "\n",
839
  " self.net = nn.Sequential(\n",
840
  " nn.LayerNorm(embedding_dim),\n",
841
  " nn.Linear(embedding_dim, hidden_dim),\n",
@@ -857,15 +727,8 @@
857
  " dropout=0.2,\n",
858
  " ):\n",
859
  " super().__init__()\n",
860
- "\n",
861
- " self.clip = CLIPModel.from_pretrained(\n",
862
- " model_name\n",
863
- " )\n",
864
- "\n",
865
- " embedding_dim = (\n",
866
- " self.clip.config.projection_dim\n",
867
- " )\n",
868
- "\n",
869
  " self.heads = nn.ModuleDict(\n",
870
  " {\n",
871
  " task: ClassificationHead(\n",
@@ -880,17 +743,8 @@
880
  " )\n",
881
  "\n",
882
  " def forward(self, pixel_values):\n",
883
- " image_features = (\n",
884
- " self.clip.get_image_features(\n",
885
- " pixel_values=pixel_values\n",
886
- " )\n",
887
- " )\n",
888
- "\n",
889
- " image_features = F.normalize(\n",
890
- " image_features,\n",
891
- " dim=-1,\n",
892
- " )\n",
893
- "\n",
894
  " return {\n",
895
  " task: head(image_features)\n",
896
  " for task, head in self.heads.items()\n",
@@ -907,15 +761,8 @@
907
  " color_feature_dim=37,\n",
908
  " ):\n",
909
  " super().__init__()\n",
910
- "\n",
911
- " self.clip = CLIPModel.from_pretrained(\n",
912
- " model_name\n",
913
- " )\n",
914
- "\n",
915
- " embedding_dim = (\n",
916
- " self.clip.config.projection_dim\n",
917
- " )\n",
918
- "\n",
919
  " self.heads = nn.ModuleDict(\n",
920
  " {\n",
921
  " task: ClassificationHead(\n",
@@ -964,11 +811,7 @@
964
  " ),\n",
965
  " )\n",
966
  "\n",
967
- " def forward(\n",
968
- " self,\n",
969
- " pixel_values,\n",
970
- " color_features,\n",
971
- " ):\n",
972
  " image_features = (\n",
973
  " self.clip.get_image_features(\n",
974
  " pixel_values=pixel_values\n",
 
219
  },
220
  {
221
  "cell_type": "code",
222
+ "execution_count": null,
223
  "id": "1ac434ae",
224
  "metadata": {
225
  "execution": {
 
249
  "\n",
250
  "def safe_torch_load(path, map_location=\"cpu\"):\n",
251
  " try:\n",
252
+ " return torch.load(path, map_location=map_location, weights_only=True)\n",
 
 
 
 
253
  " except (TypeError, RuntimeError):\n",
254
+ " return torch.load(path, map_location=map_location)\n",
 
 
 
255
  "\n",
256
  "\n",
257
  "def download_repo_artifacts(repo_id, include_rules=False):\n",
 
280
  " }\n",
281
  "\n",
282
  " if include_rules:\n",
283
+ " artifacts[\"consistency_rules\"] = load_json(paths[\"consistency_rules.json\"])\n",
 
 
284
  "\n",
285
  " return artifacts\n",
286
  "\n",
287
  "\n",
288
  "v1_artifacts = download_repo_artifacts(V1_REPO_ID)\n",
289
+ "v2_artifacts = download_repo_artifacts(V2_REPO_ID,include_rules=True)\n",
 
 
 
290
  "\n",
291
  "if v1_artifacts[\"label_maps\"] != v2_artifacts[\"label_maps\"]:\n",
292
+ " raise ValueError(\"V1 and V2 label maps are different. \")\n",
 
 
 
293
  "\n",
294
  "label_maps = v2_artifacts[\"label_maps\"]\n",
295
  "v1_config = v1_artifacts[\"config\"]\n",
 
310
  "}\n",
311
  "\n",
312
  "print(\"Base model:\", MODEL_NAME)\n",
313
+ "print(\"Task classes:\", task_num_classes)"
314
  ]
315
  },
316
  {
 
325
  },
326
  {
327
  "cell_type": "code",
328
+ "execution_count": null,
329
  "id": "bf1f57de",
330
  "metadata": {
331
  "execution": {
 
363
  }
364
  ],
365
  "source": [
366
+ "raw_dataset = load_dataset(DATASET_NAME, split=\"train\")\n",
 
 
 
 
367
  "missing_columns = [\n",
368
  " task\n",
369
  " for task in TASKS\n",
 
374
  " raise ValueError(\"Dataset must contain an image column.\")\n",
375
  "\n",
376
  "if missing_columns:\n",
377
+ " raise ValueError(f\"Dataset is missing task columns: {missing_columns}\")\n",
 
 
378
  "\n",
379
  "\n",
380
  "def is_valid_row(row):\n",
 
383
  "\n",
384
  " for task in TASKS:\n",
385
  " value = row.get(task)\n",
 
386
  " if value is None:\n",
387
  " return False\n",
388
  "\n",
389
  " value = str(value).strip()\n",
 
390
  " if not value:\n",
391
  " return False\n",
392
  "\n",
 
397
  "\n",
398
  "\n",
399
  "clean_dataset = raw_dataset.filter(is_valid_row)\n",
 
400
  "print(\"Raw samples:\", len(raw_dataset))\n",
401
  "print(\"Clean samples:\", len(clean_dataset))\n",
402
  "print(\"Dataset fingerprint:\", clean_dataset._fingerprint)\n"
 
414
  },
415
  {
416
  "cell_type": "code",
417
+ "execution_count": null,
418
  "id": "2f6aa87a",
419
  "metadata": {
420
  "execution": {
 
450
  "df = pd.DataFrame(metadata)\n",
451
  "df[\"dataset_idx\"] = np.arange(len(clean_dataset))\n",
452
  "\n",
 
453
  "def make_safe_stratify_labels(series):\n",
454
  " counts = series.value_counts()\n",
 
455
  " return series.apply(\n",
456
+ " lambda value: (value if counts[value] >= 2 else \"__rare__\")\n",
 
 
 
 
457
  " )\n",
458
  "\n",
459
  "\n",
460
  "all_indices = df.index.to_numpy()\n",
 
461
  "try:\n",
462
  " train_idx, temporary_idx = train_test_split(\n",
463
  " all_indices,\n",
464
  " test_size=VAL_RATIO + TEST_RATIO,\n",
465
  " random_state=SEED,\n",
466
+ " stratify=make_safe_stratify_labels(df[\"articleType\"])\n",
 
 
467
  " )\n",
468
  "except ValueError:\n",
469
  " train_idx, temporary_idx = train_test_split(\n",
 
473
  " )\n",
474
  "\n",
475
  "temporary_df = df.loc[temporary_idx]\n",
 
476
  "try:\n",
477
  " val_idx, test_idx = train_test_split(\n",
478
  " temporary_idx,\n",
479
  " test_size=TEST_RATIO / (VAL_RATIO + TEST_RATIO),\n",
480
  " random_state=SEED,\n",
481
+ " stratify=make_safe_stratify_labels(temporary_df[\"articleType\"])\n",
 
 
482
  " )\n",
483
  "except ValueError:\n",
484
  " val_idx, test_idx = train_test_split(\n",
 
495
  "assert set(train_idx).isdisjoint(test_idx)\n",
496
  "assert set(val_idx).isdisjoint(test_idx)\n",
497
  "\n",
498
+ "train_df.to_csv(PROCESSED_DIR / \"train_v2.csv\", index=False)\n",
499
+ "val_df.to_csv(PROCESSED_DIR / \"val_v2.csv\", index=False)\n",
500
+ "test_df.to_csv(PROCESSED_DIR / \"test_v2.csv\", index=False)\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
501
  "\n",
502
+ "test_index_bytes = np.asarray(sorted(test_idx), dtype=np.int64).tobytes()\n",
503
+ "test_split_sha256 = hashlib.sha256(test_index_bytes).hexdigest()\n",
 
504
  "\n",
505
  "print(\"Train:\", len(train_df))\n",
506
  "print(\"Validation:\", len(val_df))\n",
 
518
  },
519
  {
520
  "cell_type": "code",
521
+ "execution_count": null,
522
  "id": "ee239b3e",
523
  "metadata": {
524
  "execution": {
 
540
  }
541
  ],
542
  "source": [
543
+ "processor = CLIPImageProcessor.from_pretrained(MODEL_NAME)\n",
 
 
 
 
 
 
 
 
 
 
 
544
  "\n",
545
+ "def extract_color_features(image, image_size=COLOR_IMAGE_SIZE):\n",
546
+ " image = image.convert(\"RGB\").resize((image_size, image_size))\n",
547
  " margin = int(image_size * 0.10)\n",
 
548
  " image = image.crop(\n",
549
  " (\n",
550
+ " margin, margin,\n",
551
+ " image_size - margin, image_size - margin,\n",
 
 
552
  " )\n",
553
  " )\n",
554
  "\n",
555
+ " rgb = np.asarray(image, dtype=np.float32) / 255.0\n",
556
+ " hsv = np.asarray(image.convert(\"HSV\"), dtype=np.float32) / 255.0\n",
 
 
 
 
 
 
 
557
  "\n",
558
  " rgb_flat = rgb.reshape(-1, 3)\n",
559
  " hsv_flat = hsv.reshape(-1, 3)\n",
 
561
  " saturation = hsv_flat[:, 1]\n",
562
  " value = hsv_flat[:, 2]\n",
563
  "\n",
564
+ " foreground_mask = ((saturation > 0.08) | (value < 0.92))\n",
 
 
 
 
565
  " if foreground_mask.sum() < 256:\n",
566
+ " foreground_mask = np.ones(len(hsv_flat), dtype=bool)\n",
 
 
 
567
  "\n",
568
  " selected_rgb = rgb_flat[foreground_mask]\n",
569
  " selected_hsv = hsv_flat[foreground_mask]\n",
570
  "\n",
571
+ " hue_hist, _ = np.histogram(selected_hsv[:, 0], bins=12, range=(0.0, 1.0))\n",
572
+ " saturation_hist, _ = np.histogram(selected_hsv[:, 1], bins=8, range=(0.0, 1.0))\n",
573
+ " value_hist, _ = np.histogram(selected_hsv[:, 2], bins=8, range=(0.0, 1.0))\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
574
  "\n",
575
  " hue_hist = hue_hist.astype(np.float32)\n",
576
  " saturation_hist = saturation_hist.astype(np.float32)\n",
577
  " value_hist = value_hist.astype(np.float32)\n",
578
  "\n",
579
  " hue_hist /= max(hue_hist.sum(), 1.0)\n",
580
+ " saturation_hist /= max(saturation_hist.sum(), 1.0)\n",
 
 
 
581
  " value_hist /= max(value_hist.sum(), 1.0)\n",
582
  "\n",
583
+ " rgb_mean = selected_rgb.mean(axis=0).astype(np.float32)\n",
584
+ " rgb_std = selected_rgb.std(axis=0).astype(np.float32)\n",
585
+ " rgb_median = np.median(selected_rgb, axis=0).astype(np.float32)\n",
 
 
 
 
 
 
 
 
 
586
  "\n",
587
  " features = np.concatenate(\n",
588
  " [\n",
589
+ " hue_hist, saturation_hist,\n",
590
+ " value_hist, rgb_mean,\n",
591
+ " rgb_std, rgb_median,\n",
 
 
 
592
  " ]\n",
593
  " ).astype(np.float32)\n",
594
  "\n",
595
  " if features.shape[0] != COLOR_FEATURE_DIM:\n",
596
+ " raise ValueError(f\"Expected {COLOR_FEATURE_DIM} color features, \")\n",
 
 
 
 
597
  " return features\n",
598
  "\n",
 
599
  "class ComparisonDataset(Dataset):\n",
600
+ " def __init__(self, source_dataset, indices, processor, label_maps):\n",
 
 
 
 
 
 
601
  " self.source_dataset = source_dataset\n",
602
  " self.indices = list(map(int, indices))\n",
603
  " self.processor = processor\n",
 
609
  " def __getitem__(self, index):\n",
610
  " global_index = self.indices[index]\n",
611
  " item = self.source_dataset[global_index]\n",
 
612
  " image = item[\"image\"]\n",
613
  "\n",
614
  " if not isinstance(image, Image.Image):\n",
615
  " image = Image.open(image)\n",
616
  "\n",
617
  " image = image.convert(\"RGB\")\n",
 
618
  " pixel_values = self.processor(\n",
619
  " images=image,\n",
620
  " return_tensors=\"pt\",\n",
 
645
  "\n",
646
  "def collate_batch(batch):\n",
647
  " return {\n",
648
+ " \"pixel_values\": torch.stack([item[\"pixel_values\"] for item in batch]),\n",
649
+ " \"color_features\": torch.stack([item[\"color_features\"] for item in batch]),\n",
 
 
 
 
650
  " \"labels\": {\n",
651
  " task: torch.stack(\n",
652
  " [item[\"labels\"][task] for item in batch]\n",
 
676
  " collate_fn=collate_batch,\n",
677
  ")\n",
678
  "\n",
679
+ "print(\"Test samples:\", len(test_dataset))"
680
  ]
681
  },
682
  {
 
689
  },
690
  {
691
  "cell_type": "code",
692
+ "execution_count": null,
693
  "id": "65d75793",
694
  "metadata": {
695
  "execution": {
 
704
  "outputs": [],
705
  "source": [
706
  "class ClassificationHead(nn.Module):\n",
707
+ " def __init__(self, embedding_dim, num_classes, hidden_dim=512, dropout=0.2,):\n",
 
 
 
 
 
 
708
  " super().__init__()\n",
 
709
  " self.net = nn.Sequential(\n",
710
  " nn.LayerNorm(embedding_dim),\n",
711
  " nn.Linear(embedding_dim, hidden_dim),\n",
 
727
  " dropout=0.2,\n",
728
  " ):\n",
729
  " super().__init__()\n",
730
+ " self.clip = CLIPModel.from_pretrained(model_name)\n",
731
+ " embedding_dim = (self.clip.config.projection_dim)\n",
 
 
 
 
 
 
 
732
  " self.heads = nn.ModuleDict(\n",
733
  " {\n",
734
  " task: ClassificationHead(\n",
 
743
  " )\n",
744
  "\n",
745
  " def forward(self, pixel_values):\n",
746
+ " image_features = (self.clip.get_image_features(pixel_values=pixel_values))\n",
747
+ " image_features = F.normalize(image_features, dim=-1)\n",
 
 
 
 
 
 
 
 
 
748
  " return {\n",
749
  " task: head(image_features)\n",
750
  " for task, head in self.heads.items()\n",
 
761
  " color_feature_dim=37,\n",
762
  " ):\n",
763
  " super().__init__()\n",
764
+ " self.clip = CLIPModel.from_pretrained(model_name)\n",
765
+ " embedding_dim = (self.clip.config.projection_dim)\n",
 
 
 
 
 
 
 
766
  " self.heads = nn.ModuleDict(\n",
767
  " {\n",
768
  " task: ClassificationHead(\n",
 
811
  " ),\n",
812
  " )\n",
813
  "\n",
814
+ " def forward(self,pixel_values,color_features,):\n",
 
 
 
 
815
  " image_features = (\n",
816
  " self.clip.get_image_features(\n",
817
  " pixel_values=pixel_values\n",