AtharvaRJ/few-shot-object-identification
0
1"""2run_classification.py3 4Sprint 1 deliverable: end-to-end few-shot classification on real5Caltech-256 container classes.6"""7from confidence_drift import build_prediction_log, print_drift_summary8from tracking import init_tracking, log_class_addition9from drift_metrics import print_drift_report10from clip_embedder import ClipEmbedder11from prototype_classifier import PrototypeClassifier12from data_loader import load_class_split13 14DATA_ROOT = "data/caltech256/256_ObjectCategories"15 16CLASS_CONFIG = [17 ("010.beer-mug", "beer mug"),18 ("041.coffee-mug", "coffee mug"),19 ("195.soda-can", "soda can"),20 ("246.wine-bottle", "wine bottle"),21]22 23N_SHOTS = 324N_TEST = 1025 26 27def main():28 print("Loading CLIP model (first run downloads ~600MB, then caches)...")29 embedder = ClipEmbedder()30 init_tracking()31 clf = PrototypeClassifier(confidence_threshold=0.22)32 33 splits = {}34 print(f"\nLoading and splitting {len(CLASS_CONFIG)} classes "35 f"(n_shots={N_SHOTS}, n_test={N_TEST})...")36 for folder_name, display_name in CLASS_CONFIG:37 split = load_class_split(38 root=DATA_ROOT,39 class_folder_name=folder_name,40 display_name=display_name,41 n_shots=N_SHOTS,42 n_test=N_TEST,43 )44 splits[display_name] = split45 print(f" '{display_name}': {len(split.shot_images)} shots, "46 f"{len(split.test_images)} test images")47 48 print("\nBuilding prototypes...")49 for display_name, split in splits.items():50 shot_embeddings = embedder.embed_images(split.shot_images)51 text_embedding = embedder.embed_text(f"a photo of a {split.display_name}")52 clf.add_class(display_name, shot_embeddings, text_embedding=text_embedding)53 log_class_addition(clf, display_name, n_examples=len(split.shot_images))54 print(f" Registered '{display_name}' from {len(split.shot_images)} examples")55 56 print_drift_report(clf, z_score_threshold=1.0)57 print("\nEvaluating on held-out test images...")58 print("=" * 70)59 total_correct = 060 total_count = 061 62 for true_class, split in splits.items():63 correct = 064 for img, path in zip(split.test_images, split.test_paths):65 q_emb = embedder.embed_image(img)66 result = clf.predict(q_emb)67 if result.predicted_class == true_class:68 correct += 169 else:70 print(f" MISCLASSIFIED [{path.name}] "71 f"true='{true_class}' predicted='{result.predicted_class}' "72 f"scores={ {k: round(v, 3) for k, v in result.all_scores.items()} }")73 accuracy = correct / len(split.test_images)74 total_correct += correct75 total_count += len(split.test_images)76 print(f" {true_class:20s}: {correct}/{len(split.test_images)} correct "77 f"({accuracy*100:.1f}%)")78 79 print("=" * 70)80 overall_acc = total_correct / total_count81 print(f"OVERALL ACCURACY: {total_correct}/{total_count} ({overall_acc*100:.1f}%)")82 83 print("\nBuilding prediction log for drift monitoring...")84 prediction_log = build_prediction_log(embedder, clf, splits)85 print_drift_summary(prediction_log)86 87 88 89if __name__ == "__main__":90 main()