Условие
Тренируем classifier для медицинских снимков рентгена. Какие augmentations применять, какие нет?
Решение
Подход
Augmentation — синтетическое расширение train set через transformations, сохраняющие label. Помогает generalization, особенно при малой выборке.
Базовые
- Horizontal flip: ✅ для природы, лиц с обеих сторон; ❌ для рентгена (left/right asymmetric anatomy!), текстов, цифр (3 ≠ ε).
- Vertical flip: редко применим. ❌ для рентгена.
- Rotation (±15°): ✅ для рентгена (небольшая).
- Crop / Resize: ✅ почти всегда.
- Color jitter (brightness, contrast): ✅ для рентгена (variability сканеров).
- Saturation / Hue: ❌ для рентгена (greyscale).
Продвинутые
- Mixup:
x = λ·x_1 + (1−λ)·x_2,y = λ·y_1 + (1−λ)·y_2. Регуляризует, сглаживает loss landscape. - CutMix: вырезаем patch из image_1 и вклеиваем в image_2; y пропорционально площади.
- Cutout: вырезаем случайный square. Регуляризует.
- RandAugment: автоматически выбирает K из M трансформаций.
- AugMix: смешивает несколько chains augmentations.
Реализация (Albumentations)
import albumentations as A
# Для рентгена
transform_train = A.Compose([
A.Resize(256, 256),
A.Rotate(limit=15, p=0.5),
A.RandomCrop(224, 224),
A.RandomBrightnessContrast(brightness_limit=0.2, contrast_limit=0.2, p=0.5),
A.GaussNoise(var_limit=(10, 30), p=0.3),
A.Normalize(mean=[0.485], std=[0.229]),
])
transform_val = A.Compose([
A.Resize(256, 256),
A.CenterCrop(224, 224),
A.Normalize(mean=[0.485], std=[0.229]),
])Mixup в PyTorch
def mixup_data(x, y, alpha=0.2):
lam = np.random.beta(alpha, alpha)
idx = torch.randperm(x.size(0))
mixed_x = lam * x + (1 - lam) * x[idx]
return mixed_x, y, y[idx], lam
def mixup_loss(criterion, pred, y_a, y_b, lam):
return lam * criterion(pred, y_a) + (1 - lam) * criterion(pred, y_b)Test-time augmentation (TTA)
На inference: применяем несколько augmentations к test image, усредняем predictions. Boost метрик 0.5-2%.
Подводные камни
- Label-changing augmentation: rotation 180° на цифре 6 → 9. Hflip на тексте/рентгене. Проверяйте semantic invariance.
- Domain mismatch: натренировались с heavy augmentation, на проде «чистые» снимки → модель видит чуть другую distribution.
- Слишком сильная augmentation → underfit. Постепенное увеличение во время training.
- Augmentation не делается на val/test (кроме TTA). Часто баг: общий transform на train и val.
- На сегментации augmentations должны применяться одинаково к image и mask — Albumentations поддерживает это.
- Med imaging: нормализация по window/level специфична. Не cliping в [0, 255] прямо как RGB.
Эталонный ответ
Augmentation — синтетическое расширение train, сохраняющее label. Для рентгена: rotation ±15, crops, brightness/contrast; ❌ hflip (left/right), saturation. Продвинутые: Mixup (λ·x1+(1−λ)·x2), CutMix, RandAugment. TTA на inference. Не augmentировать val. Проверять semantic invariance.