Few shot classification - iffatAGheyas/computer-vision-handbook GitHub Wiki

πŸ§ͺ Few-Shot Image Classification with a Frozen ResNet Backbone


πŸ“Œ What Is Few-Shot Classification?

Few-shot classification refers to the ability of a model to correctly classify images given only a few examples per classβ€”often as few as 1–5 images.

Instead of training a deep classifier from scratch, we:

  • Use a frozen pretrained model (e.g., ResNet50) as a feature extractor
  • Compute embedding vectors (aka β€œfeatures”) for a few support examples
  • Classify test images by comparing their features to the support embeddings

This method is often called a prototypical classifier.

🧠 Key Concepts

Concept Description
πŸ“¦ Backbone Pretrained ResNet50 (frozen) used to generate features
πŸ§ͺ Support Set A few labeled images per class
🎯 Prototypes Average embedding per class
πŸ” Prediction Test image is assigned the label of the nearest prototype

πŸ› οΈ Dataset

trainingset/
β”œβ”€β”€ dog/
└── person/

testset/
β”œβ”€β”€ dog/
└── person/
  • βœ… Support set (few images per class) in trainingset/
  • βœ… Test set to evaluate generalization in testset/

πŸ’» Full Code

Use the following script to:

  • Load a pretrained ResNet50
  • Extract embeddings for training samples
  • Compute prototypes for each class
  • Predict test images by comparing to prototypes
  • Save results as a PDF report
import os
import numpy as np
import tensorflow as tf
from tensorflow.keras.applications import ResNet50, resnet50
from tensorflow.keras.preprocessing import image as keras_image
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages

# ── CONFIG ───────────────────────────────────────────────────
TRAIN_DIR = "trainingset"   # must contain subdirs "dog" and "person"
TEST_DIR  = "testset"       # same structure
IMG_SIZE  = (224, 224)      # ResNet50 default
PDF_OUT   = "fewshot_results.pdf"
# ─────────────────────────────────────────────────────────────

# 1) class names & mapping
class_names = sorted(os.listdir(TRAIN_DIR))
class_map   = {name: idx for idx, name in enumerate(class_names)}

# 2) load backbone (frozen)
backbone = ResNet50(
    weights="imagenet",
    include_top=False,
    pooling="avg",
    input_shape=(*IMG_SIZE, 3)
)
backbone.trainable = False

# 3) helper to load & preprocess a single image
def load_and_prep(path):
    img = keras_image.load_img(path, target_size=IMG_SIZE)
    arr = keras_image.img_to_array(img)
    return resnet50.preprocess_input(arr)

# 4) build support embeddings
support_embeddings = {cls: [] for cls in class_names}
for cls in class_names:
    folder = os.path.join(TRAIN_DIR, cls)
    for fn in sorted(os.listdir(folder)):
        if not fn.lower().endswith((".jpg","jpeg","png")): continue
        img_arr = load_and_prep(os.path.join(folder, fn))
        emb     = backbone.predict(img_arr[None,...], verbose=0)[0]
        support_embeddings[cls].append(emb)

# 5) compute prototypes
prototypes = {
    cls: np.mean(np.stack(embs, axis=0), axis=0)
    for cls, embs in support_embeddings.items()
}

# 6) run on test set & write PDF
with PdfPages(PDF_OUT) as pdf:
    for cls in class_names:
        folder = os.path.join(TEST_DIR, cls)
        for fn in sorted(os.listdir(folder)):
            if not fn.lower().endswith((".jpg","jpeg","png")): continue
            path    = os.path.join(folder, fn)
            img     = keras_image.load_img(path)
            arr     = load_and_prep(path)
            emb     = backbone.predict(arr[None,...], verbose=0)[0]
            # compute distances to each prototype
            dists   = {c: np.linalg.norm(emb - proto)
                       for c, proto in prototypes.items()}
            pred    = min(dists, key=dists.get)

            # plot
            fig, ax = plt.subplots(figsize=(6,6))
            ax.imshow(img)
            ax.axis("off")
            ax.set_title(f"Actual: {cls}  β†’  Pred: {pred}", fontsize=14)
            pdf.savefig(fig, bbox_inches="tight")
            plt.close(fig)

print(f"βœ… Done β†’ wrote few-shot results to {PDF_OUT}")

πŸ–ΌοΈ Visualization of Test Results

Each test image is labeled with:

  • Actual class (from test folder)
  • Predicted class (based on nearest prototype)

All outputs are saved to:

fewshot_results.pdf

πŸ“Œ Sample Predictions (Visualized)

image image image image image image image image image image βœ… Summary Table

Feature Value
Model Type Few-shot classification (nonparametric)
Backbone ResNet50 (frozen, pretrained on ImageNet)
Classes dog, person
Classifier Prototype distance (L2)
Output Format PDF report of predictions

πŸ” Advantages of Few-Shot Learning

  • βœ… Fast setup β€” No training loop required
  • βœ… Robust β€” Works with small datasets
  • βœ… Reusable β€” Easily extended to new classes
  • ❌ Limitation β€” Doesn’t improve unless prototypes are updated or more data is provided