Deep Learning

⚡ PyTorch

Základní pojmy, training loop, MLP kostra. Základ pro CNN a další architektury.

📄 PYTORCH_POJMY.mdživě načítáno z repozitáře

PyTorch pojmy

Základní kostra každého projektu

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
import numpy as np
import pandas as pd

# GPU pokud dostupné, jinak CPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# Model a data musí být na stejném zařízení
model = MujModel().to(device)
X_batch = X_batch.to(device)
y_batch = y_batch.to(device)

# Training loop
optimizer = optim.Adam(model.parameters(), lr=1e-3)
loss_fn = nn.CrossEntropyLoss()

for epoch in range(10):
    model.train()
    for X_batch, y_batch in loader:
        X_batch, y_batch = X_batch.to(device), y_batch.to(device)
        pred = model(X_batch)
        loss = loss_fn(pred, y_batch)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    print(f"Epoch {epoch+1}, loss: {loss.item():.4f}")

# Predikce
model.eval()
with torch.no_grad():
    preds = model(X_test.to(device)).argmax(dim=1).cpu().numpy()

Pravidla:

  • model.train() před tréninkem, model.eval() před predikcí
  • .to(device) — model i data musí být na stejném místě (GPU/CPU)
  • .cpu().numpy() — tensor z GPU zpět na CPU před numpy konverzí
  • optimizer.zero_grad() vždy před loss.backward()

X, y

X = vstupní data (pixely obrázků). Velké X = matice (každý řádek = jeden obrázek, každý sloupec = jeden pixel).
y = správné odpovědi (labely, čísla 0-9). Malé y = vektor (jedna hodnota na obrázek).

Tensor

Zobecnění matice do libovolného počtu dimenzí.

  • 0D = jedno číslo (scalar)
  • 1D = vektor: [1, 2, 3]
  • 2D = matice: X_train má shape (42000, 784)
  • 3D+ = batch obrázků, video atd.

PyTorch počítá nad tensory, může je poslat na GPU.

Epoch

Jedno průchod přes všechna trénovací data. 10 epoch = model viděl každý obrázek 10x.
Víc epoch = víc učení, ale hrozí overfit — model si zapamatuje trénovací data místo aby se naučil obecné vzory.

Jak poznat overfit

Rozděl data: 80% train, 20% validace. Po každé epoše měř loss na obou. Když train loss klesá ale val loss roste = overfit začal. Ideální počet epoch = kdy val loss přestane klesat.

Batch

Podmnožina dat (např. 64 obrázků). Místo počítat gradient z 1 vzorku nebo všech 42000 najednou, vezmeš 64.

  • 1 vzorek = gradient moc "zašuměný"
  • Všechna data = nevejdou do paměti GPU, čekáš dlouho
  • 64 = kompromis: stabilní gradient, rychlý update

Gradient

Sklon loss funkce v aktuálním bodě, pro každou váhu zvlášť. Říká: "když zvětším tuto váhu, loss se změní o X."

Představ si hledání nejnižšího bodu v mlze. Gradient = sklon pod nohama. Jdeš opačným směrem = loss klesá.

loss.backward() spočítá gradient přes celou síť (backpropagation) a uloží ho do .grad atributu každé váhy.

ReLU (Rectified Linear Unit)

Aktivační funkce: f(x) = max(0, x). Záporné vstupy → 0, kladné → beze změny.

Bez aktivace by celá síť byla jen jedna velká lineární funkce — nedokáže se naučit složité vzory. ReLU přidá nelinearitu. Různé neurony se aktivují pro různé vzory (detektor "horního oblouku", detektor "svislé čáry" atd.).

Používá se mezi každou Linear vrstvou, kromě poslední.

Loss (CrossEntropyLoss)

Číslo = vzdálenost od správné odpovědi. Čím blíž nule, tím líp.

CrossEntropy: model vyplivne 10 čísel (pro každou cifru jedno), loss porovná se správnou odpovědí.

  • Model říká "90% šance že je to 3" a správně je to 3 → nízký loss
  • Model říká "90% šance že je to 7" ale je to 3 → vysoký loss

Cíl tréninku = minimalizovat loss.

optimizer.zero_grad()

PyTorch gradienty akumuluje — každý loss.backward() přičte nové gradienty k předchozím. Bez nulování by se gradienty sčítaly napříč batchi → špatný směr updatu.

zero_grad() před každým batchem smaže staré gradienty.

loss.backward()

Spočítá gradienty. Projde sítí pozpátku (backpropagation) — od lossu přes každou vrstvu zpět až k vahám. Výsledek uloží do .grad atributu každé váhy.

Optimizer (Adam)

Algoritmus který updatuje váhy podle gradientů.

optimizer.step() = vezme gradienty a posune každou váhu o kousek v opačném směru → loss klesá.

Adam vs základní SGD: Adam si pamatuje historii gradientů a adaptivně mění velikost kroku pro každou váhu zvlášť. Váhy které se mění hodně → menší kroky. Váhy které se mění málo → větší kroky. Konverguje rychleji.

lr=1e-3 = learning rate = jak velký krok. Moc velký → přeskakuješ přes minimum. Moc malý → trénink trvá věčně.

Logits

Surový výstup poslední vrstvy. Pro jeden obrázek = 10 čísel, jedno pro každou cifru.
Např: [-1.2, 0.3, 8.1, 0.5, -0.8, 1.2, 0.1, 2.3, 0.9, 0.4]
Největší číslo = co si model myslí že to je. Nejsou to pravděpodobnosti (mohou být záporné).

argmax

"Argument of maximum" — vrátí index největšího čísla.

logits.argmax(dim=1) = pro každý obrázek najdi index největšího logitu = predikovaná cifra.
Z příkladu výše: index 2 = cifra "2".

model.eval() + torch.no_grad()

Dva různé věci:

model.eval() — přepne model do režimu predikce. Některé vrstvy (Dropout, BatchNorm) se chovají jinak při tréninku vs predikci. Dobrý zvyk vždy napsat před predikcí.

torch.no_grad() — PyTorch neukládá gradienty. Při predikci nepotřebuješ .backward(), takže PyTorch nemusí pamatovat výpočetní graf. Ušetří paměť a zrychlí predikci.