EfficientNet-B0 — Clasificación de Lesiones Cutáneas ISIC 2018
Modelo de clasificación multiclase de lesiones cutáneas dermoscópicas entrenado sobre HAM10000 (ISIC 2018 Task 3) mediante fine-tuning progresivo. Segunda etapa del pipeline de análisis de lesiones cutáneas — clasifica la región segmentada por U-Net en 7 categorías clínicas.
Repositorio: skin-lesion-analysis
Modelo de segmentación (primera etapa): unet-resnet34-isic2018-segmentation
Métricas
| Métrica | Valor |
|---|---|
| F1 macro (val) | 0.7700 |
| F1 weighted (val) | 0.7877 |
| AUC macro (val) | 0.9719 |
| Accuracy (val) | 0.77 |
Split 80/20 estratificado sobre HAM10000 (10.015 imágenes). 8.012 imágenes de entrenamiento, 2.003 de validación.
Métricas por clase
| Clase | Precision | Recall | F1 | Soporte |
|---|---|---|---|---|
| MEL — Melanoma | 0.40 | 0.82 | 0.54 | 223 |
| NV — Melanocytic nevus | 0.98 | 0.73 | 0.84 | 1341 |
| BCC — Basal cell carcinoma | 0.77 | 0.92 | 0.84 | 103 |
| AKIEC — Actinic keratosis | 0.71 | 0.74 | 0.72 | 65 |
| BKL — Benign keratosis | 0.62 | 0.82 | 0.71 | 220 |
| DF — Dermatofibroma | 0.81 | 0.91 | 0.86 | 23 |
| VASC — Vascular lesion | 0.82 | 0.96 | 0.89 | 28 |
Nota sobre MEL: precision 0.40 con recall 0.82 indica que el modelo genera falsos positivos de melanoma. En contexto clínico este comportamiento es aceptable — mejor sobrediagnosticar que infradiagnosticar — pero refleja la dificultad intrínseca de distinguir melanoma de nevus en imágenes ambiguas del dataset.
Uso
import torch
import timm
import albumentations as A
from albumentations.pytorch import ToTensorV2
from huggingface_hub import hf_hub_download
import numpy as np
from PIL import Image
CLASES = ["MEL", "NV", "BCC", "AKIEC", "BKL", "DF", "VASC"]
# 1. Descargar el checkpoint
ruta = hf_hub_download(
repo_id="Jesusrodriguezf90/efficientnet-b0-isic2018-classification",
filename="best_efficientnet_b0.pth"
)
# 2. Reconstruir el modelo
model = timm.create_model(
"efficientnet_b0",
pretrained=False,
num_classes=7,
)
model.load_state_dict(torch.load(ruta, map_location="cpu"))
model.eval()
# 3. Preprocesamiento — mismo pipeline que en entrenamiento
transform = A.Compose([
A.Resize(256, 256),
A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)),
ToTensorV2(),
])
# 4. Inferencia
img = np.array(Image.open("imagen_dermoscopica.jpg").convert("RGB"))
tensor = transform(image=img)["image"].unsqueeze(0)
with torch.no_grad():
logits = model(tensor)
probs = torch.softmax(logits, dim=1).squeeze()
pred = probs.argmax().item()
print(f"Predicción: {CLASES[pred]} ({probs[pred]:.3f})")
Arquitectura y entrenamiento
Fine-tuning progresivo
El entrenamiento se divide en dos fases para preservar los pesos preentrenados en ImageNet:
Fase 1 — encoder congelado (5 épocas, lr=1e-3): solo se entrenan los 8.967 parámetros del clasificador final. El encoder está congelado para evitar que los gradientes erráticos del clasificador recién inicializado destruyan las representaciones aprendidas en ImageNet.
Fase 2 — modelo completo descongelado (30 épocas máx, lr=1e-4): se descongela todo el modelo con lr reducido para afinar los pesos del encoder sin sobreescribir el conocimiento previo. Early stopping con paciencia=5 sobre F1 macro val.
Estrategia contra el desbalance (ratio 58.3x entre NV y DF)
Doble estrategia complementaria:
- WeightedRandomSampler — sobremuestrea clases minoritarias en cada batch
- CrossEntropyLoss con pesos de clase — penaliza más los errores en clases minoritarias
Proceso experimental
Se realizaron tres experimentos para determinar la configuración óptima:
| Experimento | Configuración | F1 macro | AUC |
|---|---|---|---|
| E1 — baseline | epochs_unfrozen=20 |
0.7493 | 0.9704 |
| E2 — regularización | + drop_rate=0.2 + label_smoothing=0.1 + epochs_unfrozen=30 |
~0.50 | ~0.96 |
| E3 — configuración final ✓ | Solo epochs_unfrozen=30 |
0.7700 | 0.9719 |
E2 demostró que combinar dropout adicional y label smoothing con un dataset fuertemente desbalanceado ralentiza la convergencia sin beneficio neto. La configuración final (E3) amplía el margen de entrenamiento para que el early stopping pueda actuar correctamente.
| Parámetro | Valor |
|---|---|
| Dataset | HAM10000 / ISIC 2018 Task 3 |
| Imágenes entrenamiento | 8.012 |
| Split | 80/20 estratificado (seed=42) |
| Resolución entrada | 256×256 |
| Épocas fase 1 (frozen) | 5 |
| Épocas fase 2 (unfrozen) | 30 máx (early stopping paciencia=5) |
| Épocas ejecutadas | 35 |
| lr fase 1 | 1e-3 |
| lr fase 2 | 1e-4 |
| Weight decay | 1e-4 |
| Loss | CrossEntropyLoss con pesos de clase |
| Optimizer | AdamW |
| Scheduler | ReduceLROnPlateau (factor=0.1, patience=3) |
| Parámetros totales | 4.016.515 |
| Hardware | Kaggle GPU T4 |
Limitaciones
- El dataset HAM10000 está fuertemente desbalanceado — NV representa el 66.9% de las muestras. A pesar de la doble estrategia de balanceo, el modelo tiende a favorecer NV
- MEL presenta precision baja (0.40) — el modelo genera falsos positivos de melanoma al confundirlo con nevus en imágenes ambiguas
- Entrenado exclusivamente con imágenes dermoscópicas estándar — no aplicable a fotografías clínicas convencionales ni fotos de smartphone sin dermatoscopio
- La clasificación en el pipeline completo se realiza sobre la imagen completa — en inferencia con U-Net, EfficientNet clasifica sobre la región enmascarada, lo que puede diferir del comportamiento en entrenamiento
Dataset
HAM10000 — ISIC 2018 Task 3
International Skin Imaging Collaboration (ISIC)
🔗 https://challenge.isic-archive.com/data/#2018
Tschandl et al. (2018). The HAM10000 dataset, a large collection of multi-source dermatoscopic images of common pigmented skin lesions. Scientific Data
Licencia
MIT
Model tree for Jesusrodriguezf90/efficientnet-b0-isic2018-classification
Base model
timm/efficientnet_b0.ra_in1k