Spaces:
Runtime error
Runtime error
Download predict.py from jitendra25/Image-Classification-Pipeline: direct link, hf CLI and curl.
- Browser
- Download file 4.35 kB
-
https://huggingface.co/spaces/jitendra25/Image-Classification-Pipeline/resolve/main/predict.py
- Command line
-
hf download hf://spaces/jitendra25/Image-Classification-Pipeline/predict.py
-
curl -L -o predict.py https://huggingface.co/spaces/jitendra25/Image-Classification-Pipeline/resolve/main/predict.py
4.35 kB
| #!/usr/bin/env python3 | |
| """ | |
| Advanced command-line image classifier. | |
| Usage | |
| ----- | |
| python predict.py path/to/image.jpg | |
| python predict.py path/to/image.jpg --top_k 10 | |
| python predict.py path/to/image.jpg --model efficientnet_b0 | |
| Prints a clean, formatted ASCII table of the top-k predictions. | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import sys | |
| import time | |
| from pathlib import Path | |
| from typing import List, Tuple | |
| import torch | |
| import torch.nn.functional as F | |
| from PIL import Image | |
| from torchvision import models, transforms | |
| def load_model(model_name: str) -> Tuple[torch.nn.Module, transforms.Compose, List[str]]: | |
| """Load a pretrained model with its canonical preprocessing and labels.""" | |
| model_name = model_name.lower() | |
| if model_name == "efficientnet_b0": | |
| weights = models.EfficientNet_B0_Weights.IMAGENET1K_V1 | |
| model = models.efficientnet_b0(weights=weights) | |
| elif model_name == "mobilenet_v3_large": | |
| weights = models.MobileNet_V3_Large_Weights.IMAGENET1K_V2 | |
| model = models.mobilenet_v3_large(weights=weights) | |
| else: | |
| raise ValueError( | |
| f"Unknown model '{model_name}'. " | |
| "Choose from: mobilenet_v3_large, efficientnet_b0" | |
| ) | |
| model.eval() | |
| return model, weights.transforms(), list(weights.meta["categories"]) | |
| def classify( | |
| image_path: Path, model_name: str, top_k: int | |
| ) -> Tuple[List[Tuple[str, float]], float]: | |
| """Return (list of (label, confidence), inference_ms).""" | |
| model, preprocess, categories = load_model(model_name) | |
| image = Image.open(image_path).convert("RGB") | |
| tensor = preprocess(image).unsqueeze(0) | |
| t0 = time.perf_counter() | |
| with torch.inference_mode(): | |
| probs = F.softmax(model(tensor), dim=1)[0] | |
| inference_ms = (time.perf_counter() - t0) * 1000 | |
| top_k = max(1, min(top_k, probs.numel())) | |
| confidences, indices = torch.topk(probs, top_k) | |
| predictions = [ | |
| (categories[idx], float(conf)) | |
| for conf, idx in zip(confidences.tolist(), indices.tolist()) | |
| ] | |
| return predictions, inference_ms | |
| def render_table(predictions: List[Tuple[str, float]]) -> str: | |
| """Render predictions as a bordered ASCII table with confidence bars.""" | |
| rank_w, label_w, conf_w, bar_w = 4, 28, 10, 22 | |
| def row(rank: str, label: str, conf: str, bar: str) -> str: | |
| return ( | |
| f"| {rank:<{rank_w}} | {label:<{label_w}} | " | |
| f"{conf:<{conf_w}} | {bar:<{bar_w}} |" | |
| ) | |
| border = ( | |
| "+" + "-" * (rank_w + 2) + "+" + "-" * (label_w + 2) | |
| + "+" + "-" * (conf_w + 2) + "+" + "-" * (bar_w + 2) + "+" | |
| ) | |
| lines = [border, row("#", "Class", "Conf.", "Confidence"), border] | |
| for i, (label, conf) in enumerate(predictions, start=1): | |
| pct = conf * 100 | |
| filled = int(round((bar_w) * conf)) | |
| bar = "#" * filled + "." * (bar_w - filled) | |
| lines.append(row(str(i), label[:label_w], f"{pct:6.2f}%", bar)) | |
| lines.append(border) | |
| return "\n".join(lines) | |
| def main(argv: List[str] | None = None) -> int: | |
| parser = argparse.ArgumentParser( | |
| description="Classify an image from the command line using a pretrained CNN.", | |
| formatter_class=argparse.ArgumentDefaultsHelpFormatter, | |
| ) | |
| parser.add_argument("image", type=Path, help="Path to the image file.") | |
| parser.add_argument( | |
| "--top_k", type=int, default=5, help="Number of top predictions to display." | |
| ) | |
| parser.add_argument( | |
| "--model", | |
| default="mobilenet_v3_large", | |
| choices=["mobilenet_v3_large", "efficientnet_b0"], | |
| help="Model architecture to use.", | |
| ) | |
| args = parser.parse_args(argv) | |
| if not args.image.exists(): | |
| print(f"Error: file not found -> {args.image}", file=sys.stderr) | |
| return 1 | |
| print(f"\n Model : {args.model}") | |
| print(f" Image : {args.image}\n") | |
| try: | |
| predictions, inference_ms = classify(args.image, args.model, args.top_k) | |
| except Exception as exc: # noqa: BLE001 | |
| print(f"Error during inference: {exc}", file=sys.stderr) | |
| return 1 | |
| print(render_table(predictions)) | |
| print(f"\n Top prediction : {predictions[0][0]} ({predictions[0][1] * 100:.2f}%)") | |
| print(f" Inference time : {inference_ms:.1f} ms\n") | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |