--- license: mit tags: - image-classification - multi-label-image-classification - pytorch - timm - dermatology - acne library_name: timm pipeline_tag: image-classification --- # Multi-Label Acne Type Classifier (efficientnet_b0) Predicts which of five acne lesion types are **present** in a full-face photograph. This is a multi-label presence task: it does not count lesions and does not localise them. **Classes:** Whitehead, Blackhead, Papule, Pustule, Nodule ## Intended use and limitations Research and educational use only. **This model is not a medical device and must not be used for diagnosis or treatment decisions.** It was trained on a limited academic dataset and has not been clinically validated. Performance across skin tones, ages, lighting conditions and camera hardware has not been audited and is very likely uneven; treat any output on under-represented skin tones as unreliable. ## Architecture - Backbone: `efficientnet_b0` (timm, ImageNet-pretrained) - Head: single linear layer, 5 logits, sigmoid activation at inference - Input: 320 x 320 RGB, ImageNet normalisation - Loss: BCEWithLogitsLoss with per-class `pos_weight` - Optimiser: AdamW, warmup + cosine decay, mixed precision - Per-class decision thresholds tuned on validation (see `thresholds.json`) ## Training data 3,231 train / 693 validation / 693 test images, multi-label stratified. Sources include the public Kaggle dataset `tiswan14/acne-dataset-image` plus project-specific annotations. ## Test-set results | Metric | Value | |---|---| | Subset (exact-match) accuracy | 0.9798 | | Label-wise accuracy | 0.9951 | | Macro F1 | 0.9889 | | Micro F1 | 0.9877 | | Macro ROC-AUC | 0.9993 | | Macro Average Precision | 0.9978 | | Class | Support | Precision | Recall | F1 | ROC-AUC | |---|---|---|---|---|---| | Whitehead | 45 | 1.000 | 1.000 | 1.000 | 1.000 | | Blackhead | 186 | 1.000 | 0.995 | 0.997 | 1.000 | | Papule | 155 | 0.987 | 0.955 | 0.971 | 0.998 | | Pustule | 151 | 0.974 | 0.980 | 0.977 | 0.998 | | Nodule | 156 | 1.000 | 1.000 | 1.000 | 1.000 | ## Usage ```python import torch, timm, numpy as np, cv2 from huggingface_hub import hf_hub_download ckpt_path = hf_hub_download("charuka0/acne-multilabel-classifier", "best_model.pth") ckpt = torch.load(ckpt_path, map_location="cpu", weights_only=False) model = timm.create_model(ckpt["backbone"], pretrained=False, num_classes=5) model.load_state_dict(ckpt["model_state_dict"]); model.eval() img = cv2.cvtColor(cv2.imread("face.jpg"), cv2.COLOR_BGR2RGB) img = cv2.resize(img, (ckpt["img_size"], ckpt["img_size"])) / 255.0 img = (img - [0.485, 0.456, 0.406]) / [0.229, 0.224, 0.225] x = torch.tensor(img).permute(2, 0, 1).unsqueeze(0).float() probs = torch.sigmoid(model(x))[0].detach().numpy() present = probs >= np.array(ckpt["thresholds"]) print(dict(zip(ckpt["classes"], zip(probs.round(3), present)))) ``` ## Citation Final Year Research Project, 2026. Trained on Kaggle free-tier GPU.