Instructions to use charuka0/acne-multilabel-classifier with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- timm
How to use charuka0/acne-multilabel-classifier with timm:
import timm model = timm.create_model("hf_hub:charuka0/acne-multilabel-classifier", pretrained=True) - Notebooks
- Google Colab
- Kaggle
| 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. | |