Dataaugmentering i praktiken
Kunna välja augmenteringar som matchar domänen och mäta effekten.
Förkunskaper
Intuition
Augmentering skapar fler träningsexempel genom att ändra befintliga på sätt som inte ändrar etiketten. Det är den effektivaste regulariseringen som finns när data är begränsad.
Den avgörande frågan för varje augmentering: bevarar den etiketten?
| Augmentering | Katt/hund | Siffror (MNIST) | Medicinska bilder |
|---|---|---|---|
| Horisontell spegling | ja | nej (2 blir inte 2) | ofta nej (vänster/höger organ) |
| Rotation ±15° | ja | ja | ja |
| Rotation 180° | ja | nej (6 blir 9) | nej |
| Färgjitter | ja | irrelevant | nej (färg är diagnostisk) |
| Beskärning | ja | delvis | nej (kan klippa bort lesionen) |
Den vanligaste tabben är att kopiera ett augmenteringsrecept från ImageNet till en domän där det inte gäller. Horisontell spegling är standard i bildklassificering och direkt skadlig för sifferigenkänning.
Formellt
Augmenteringar som blandar exempel — en egen kategori, och de starkaste:
| Metod | Hur | Effekt |
|---|---|---|
| Mixup | , samma på etiketterna | mjukare beslutsgränser, bättre kalibrering |
| CutMix | klipp ut en ruta ur en bild, klistra in från en annan; etiketter viktas efter area | behåller lokala detaljer |
| RandAugment | välj slumpmässiga operationer med styrka | två parametrar i stället för tjugo |
| TrivialAugment | en slumpmässig operation med slumpmässig styrka | noll parametrar, ofta lika bra |
Den sista raden är värd att notera: TrivialAugment visade att hela sökandet efter augmenteringspolicyer till stor del kunde ersättas av ren slump, med jämförbart resultat.
Var i pipelinen:
| Steg | Augmentering |
|---|---|
| Träning | ja — slumpmässigt per epok |
| Validering | nej — annars mäter du på förvrängd data |
| Test | nej, utom vid medveten TTA |
Test-time augmentation (TTA) är undantaget: augmentera testbilden några gånger, kör modellen på varje och medelvärdesbilda. Ger typiskt 0,5–2 procentenheter för ökad inferenskostnad.
Mät, anta inte. Effekten varierar enormt med domän och datamängd:
| Datamängd | Typisk effekt av kraftig augmentering |
|---|---|
| Hundratals bilder | mycket stor — ofta avgörande |
| Tiotusentals | måttlig |
| Miljontals | liten, ibland negativ |
Andra modaliteter:
| Modalitet | Vad som fungerar |
|---|---|
| Text | synonymbyte, tillbakaöversättning, ordborttagning — försiktigt, ordföljd bär mening |
| Ljud | brus, tidssträckning, tonhöjd, SpecAugment |
| Tidsserier | jitter, skalning, fönsterförskjutning — aldrig spegling i tid |
| Tabell | SMOTE för minoritetsklassen, brus på numeriska |
Raden om tidsserier är viktig: att spegla i tid vänder på orsak och verkan.
Kontrollen som avslöjar dåliga augmenteringar: titta på 20 augmenterade exempel med egna ögon. Kan du fortfarande avgöra rätt etikett? Kan inte du det, kan inte modellen heller.
Kod
import torch, torch.nn as nn
from torchvision.transforms import v2
# Bild: träning och utvärdering är OLIKA pipelines
train_tf = v2.Compose([
v2.RandomResizedCrop(224, scale=(0.6, 1.0)),
v2.RandomHorizontalFlip(), # BARA om spegling bevarar etiketten
v2.TrivialAugmentWide(), # noll parametrar, stark baslinje
v2.ToDtype(torch.float32, scale=True),
v2.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
v2.RandomErasing(p=0.25),
])
eval_tf = v2.Compose([
v2.Resize(256), v2.CenterCrop(224), # deterministiskt — ingen slump
v2.ToDtype(torch.float32, scale=True),
v2.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
])
# Mixup: blanda både bilder och etiketter
def mixup(x, y, n_klasser, alfa=0.2):
lam = float(torch.distributions.Beta(alfa, alfa).sample())
perm = torch.randperm(x.size(0), device=x.device)
xm = lam * x + (1 - lam) * x[perm]
y1 = nn.functional.one_hot(y, n_klasser).float()
return xm, lam * y1 + (1 - lam) * y1[perm]
def mjuk_korsentropi(logits, mjuka_mal):
return -(mjuka_mal * torch.log_softmax(logits, dim=-1)).sum(dim=-1).mean()
# Test-time augmentation
def tta(modell, bild, transformer, n=5):
modell.eval()
with torch.no_grad():
p = torch.stack([torch.softmax(modell(t(bild).unsqueeze(0)), -1)
for t in transformer[:n]])
return p.mean(0)
# MÄT effekten — anta den inte
def jamfor_augmentering(trana_och_utvardera, recept: dict, fron=(0, 1, 2)):
import numpy as np
for namn, tf in recept.items():
v = [trana_och_utvardera(tf, frö=f) for f in fron]
print(f" {namn:<18} {np.mean(v):.4f} ± {np.std(v):.4f}")
# Titta på 20 augmenterade exempel med egna ögon
def granska(dataset, tf, n=20, ut="granska.png"):
from torchvision.utils import make_grid, save_image
bilder = torch.stack([tf(dataset[i][0]) for i in range(n)])
save_image(make_grid(bilder, nrow=5, normalize=True), ut)
print(f"sparade {ut} — kan DU fortfarande se rätt etikett?")
granska är den billigaste kvalitetskontrollen som finns. En augmentering som gör bilden obegriplig för dig gör den obegriplig för modellen också, och då tränar du på brus.
Behärskning innebär
- Väljer augmenteringar som bevarar etiketten
- Mäter effekten i stället för att anta
- Vet vilka som hör hemma i träning respektive utvärdering
Logga in för att göra övningarna och bygga upp din behärskning.
Källor
- arXiv — mixup: Beyond Empirical Risk Minimization — arXiv (öppen åtkomst; licens per artikel)
- arXiv — TrivialAugment: Tuning-free Yet State-of-the-Art Data Augmentation — arXiv (öppen åtkomst; licens per artikel)
- PyTorch — tutorials (BSD-3) — BSD-3-Clause