Download inference_example.py from adeIaide/skin-lesion-7class-efficientnet: direct link, hf CLI and curl.
- Browser
- Download file 2.7 kB
-
https://huggingface.co/adeIaide/skin-lesion-7class-efficientnet/resolve/main/inference_example.py
- Command line
-
hf download hf://adeIaide/skin-lesion-7class-efficientnet/inference_example.py
-
curl -L -o inference_example.py https://huggingface.co/adeIaide/skin-lesion-7class-efficientnet/resolve/main/inference_example.py
2.7 kB
| """Standalone inference example for adeIaide/skin-lesion-7class-efficientnet.""" | |
| from __future__ import annotations | |
| import argparse | |
| import json | |
| from pathlib import Path | |
| import torch | |
| from huggingface_hub import hf_hub_download | |
| from PIL import Image | |
| from safetensors.torch import load_file | |
| from torch import nn | |
| from torchvision import models, transforms | |
| REPO_ID = "adeIaide/skin-lesion-7class-efficientnet" | |
| class EfficientNetB0(nn.Module): | |
| def __init__(self, num_classes: int = 7, dropout: float = 0.3) -> None: | |
| super().__init__() | |
| network = models.efficientnet_b0(weights=None) | |
| embedding_dim = network.classifier[1].in_features | |
| self.encoder = nn.Sequential(network.features, network.avgpool, nn.Flatten(1)) | |
| self.dropout = nn.Dropout(dropout) | |
| self.classifier = nn.Linear(embedding_dim, num_classes) | |
| def forward(self, image: torch.Tensor) -> torch.Tensor: | |
| return self.classifier(self.dropout(self.encoder(image))) | |
| def load_model(device: torch.device) -> tuple[nn.Module, dict]: | |
| config_path = hf_hub_download(REPO_ID, "config.json") | |
| weights_path = hf_hub_download(REPO_ID, "model.safetensors") | |
| config = json.loads(Path(config_path).read_text(encoding="utf-8")) | |
| model = EfficientNetB0( | |
| num_classes=int(config["num_classes"]), | |
| dropout=float(config["dropout"]), | |
| ) | |
| model.load_state_dict(load_file(weights_path, device=str(device))) | |
| return model.to(device).eval(), config | |
| def predict(image_path: str | Path) -> dict[str, float]: | |
| device = torch.device("cuda" if torch.cuda.is_available() else "cpu") | |
| model, config = load_model(device) | |
| norm = config["normalization"] | |
| transform = transforms.Compose( | |
| [ | |
| transforms.Resize((config["image_size"], config["image_size"])), | |
| transforms.ToTensor(), | |
| transforms.Normalize(norm["mean"], norm["std"]), | |
| ] | |
| ) | |
| image = Image.open(image_path).convert("RGB") | |
| batch = transform(image).unsqueeze(0).to(device) | |
| with torch.inference_mode(): | |
| probabilities = torch.softmax(model(batch), dim=1)[0].cpu().tolist() | |
| return dict(zip(config["class_names"], probabilities)) | |
| def main() -> None: | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("image", help="Path to one dermoscopic image") | |
| args = parser.parse_args() | |
| probabilities = predict(args.image) | |
| predicted = max(probabilities, key=probabilities.get) | |
| print(f"prediction: {predicted}") | |
| for label, probability in sorted( | |
| probabilities.items(), key=lambda item: item[1], reverse=True | |
| ): | |
| print(f"{label:5s} {probability:.4f}") | |
| if __name__ == "__main__": | |
| main() | |