28 Tahák NumPy a PyTorch
Rychlý přehled nejpoužívanějších příkazů pro práci s NumPy a PyTorch.
28.1 NumPy - Základy
28.1.1 Import a vytváření polí
import numpy as np
# Vytvoření polí
a = np.array([1, 2, 3]) # 1D pole
b = np.array([[1, 2], [3, 4]]) # 2D pole (matice)
# Speciální pole
np.zeros((3, 4)) # Nulová matice 3x4
np.ones((2, 3)) # Matice jedniček 2x3
np.eye(4) # Jednotková matice 4x4
np.full((2, 2), 7) # Matice samých 7
# Sekvence
np.arange(0, 10, 2) # [0, 2, 4, 6, 8]
np.linspace(0, 1, 5) # [0, 0.25, 0.5, 0.75, 1]
# Náhodná čísla
np.random.rand(3, 4) # Uniformní [0, 1)
np.random.randn(3, 4) # Normální N(0, 1)
np.random.randint(0, 10, (3, 4)) # Celá čísla [0, 10)
np.random.seed(42) # Nastavení seedu28.1.2 Vlastnosti polí
a.shape # Rozměry (tuple)
a.ndim # Počet dimenzí
a.size # Celkový počet prvků
a.dtype # Datový typ
len(a) # Délka první dimenze28.1.3 Změna tvaru
a.reshape(3, 4) # Změna tvaru na 3x4
a.flatten() # Zploštění na 1D
a.ravel() # Zploštění (view)
a.T # Transpozice
a.transpose(1, 0, 2) # Přeházení os
np.expand_dims(a, axis=0) # Přidání dimenze
np.squeeze(a) # Odstranění dimenzí velikosti 128.1.4 Indexování a slicing
a[0] # První prvek
a[-1] # Poslední prvek
a[1:4] # Prvky 1-3
a[::2] # Každý druhý
a[::-1] # Obrácené pořadí
# 2D indexování
b[0, 1] # Řádek 0, sloupec 1
b[0, :] # Celý řádek 0
b[:, 1] # Celý sloupec 1
b[1:3, 0:2] # Podmatice
# Boolean indexování
a[a > 5] # Prvky větší než 5
a[a % 2 == 0] # Sudé prvky
# Fancy indexování
a[[0, 2, 4]] # Prvky na indexech 0, 2, 428.1.5 Aritmetické operace
# Po prvcích (element-wise)
a + b # Sčítání
a - b # Odčítání
a * b # Násobení
a / b # Dělení
a ** 2 # Mocnina
np.sqrt(a) # Odmocnina
np.exp(a) # Exponenciála
np.log(a) # Přirozený logaritmus
# Maticové operace
a @ b # Maticové násobení
np.dot(a, b) # Dot product
np.matmul(a, b) # Maticové násobení
a * b # Hadamardův součin (po prvcích)28.1.6 Agregační funkce
np.sum(a) # Součet všech prvků
np.sum(a, axis=0) # Součet přes osu 0
np.mean(a) # Průměr
np.std(a) # Směrodatná odchylka
np.var(a) # Rozptyl
np.min(a), np.max(a) # Minimum, maximum
np.argmin(a), np.argmax(a) # Index min/max
np.cumsum(a) # Kumulativní součet
np.prod(a) # Součin všech prvků28.1.7 Lineární algebra
np.linalg.norm(a) # L2 norma
np.linalg.norm(a, ord=1) # L1 norma
np.linalg.inv(A) # Inverze matice
np.linalg.det(A) # Determinant
np.linalg.eig(A) # Vlastní čísla a vektory
np.linalg.svd(A) # Singulární rozklad
np.linalg.solve(A, b) # Řešení Ax = b28.1.8 Spojování a rozdělování
np.concatenate([a, b], axis=0) # Spojení podle osy
np.vstack([a, b]) # Vertikální stack
np.hstack([a, b]) # Horizontální stack
np.stack([a, b], axis=0) # Stack s novou osou
np.split(a, 3) # Rozdělení na 3 části
np.array_split(a, 3) # Nerovnoměrné rozdělení28.1.9 Broadcasting
# NumPy automaticky rozšíří menší pole
a = np.array([[1], [2], [3]]) # Shape (3, 1)
b = np.array([10, 20, 30]) # Shape (3,)
a + b # Shape (3, 3)
# Pravidla:
# 1. Menší pole se rozšíří přidáním 1 na začátek
# 2. Dimenze velikosti 1 se "natáhne"28.2 PyTorch - Základy
28.2.1 Import a vytváření tensorů
import torch
import torch.nn as nn
import torch.nn.functional as F
# Vytvoření tensorů
x = torch.tensor([1, 2, 3])
x = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32)
# Speciální tensory
torch.zeros(3, 4)
torch.ones(2, 3)
torch.eye(4)
torch.full((2, 2), 7)
torch.empty(3, 4) # Neinicializované
# Sekvence
torch.arange(0, 10, 2)
torch.linspace(0, 1, 5)
# Náhodné tensory
torch.rand(3, 4) # Uniformní [0, 1)
torch.randn(3, 4) # Normální N(0, 1)
torch.randint(0, 10, (3, 4)) # Celá čísla
torch.manual_seed(42) # Seed
# Z NumPy a zpět
torch.from_numpy(np_array)
tensor.numpy() # Pouze CPU tensor28.2.2 Vlastnosti tensorů
x.shape # Rozměry
x.size() # Rozměry (metoda)
x.ndim # Počet dimenzí
x.numel() # Počet prvků
x.dtype # Datový typ
x.device # cpu nebo cuda
x.requires_grad # Sledování gradientů28.2.3 Změna tvaru
x.view(3, 4) # Změna tvaru (sdílí data)
x.reshape(3, 4) # Změna tvaru (může kopírovat)
x.flatten() # Zploštění
x.squeeze() # Odstranění dimenzí 1
x.unsqueeze(0) # Přidání dimenze
x.T # Transpozice 2D
x.transpose(0, 1) # Prohození dimenzí
x.permute(2, 0, 1) # Přeházení dimenzí
x.contiguous() # Zajištění spojitosti v paměti28.2.4 Operace s tensory
# Element-wise operace
x + y, torch.add(x, y)
x - y, torch.sub(x, y)
x * y, torch.mul(x, y)
x / y, torch.div(x, y)
x ** 2, torch.pow(x, 2)
torch.sqrt(x)
torch.exp(x)
torch.log(x)
torch.abs(x)
torch.clamp(x, min=0, max=1)
# Maticové operace
x @ y # Maticové násobení
torch.matmul(x, y)
torch.mm(x, y) # 2D matice
torch.bmm(x, y) # Batch maticové násobení
torch.dot(x, y) # Dot product (1D)
# Porovnání
x == y, torch.eq(x, y)
x > y, torch.gt(x, y)
torch.allclose(x, y) # Přibližná rovnost28.2.5 Agregace
x.sum()
x.sum(dim=0)
x.mean()
x.std()
x.var()
x.min(), x.max()
x.argmin(), x.argmax()
torch.topk(x, k=3) # Top k hodnot28.2.6 GPU operace
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
x = x.to(device) # Přesun na GPU
x = x.cuda() # Přímý přesun na GPU
x = x.cpu() # Přesun zpět na CPU
# Vytvoření přímo na GPU
x = torch.randn(3, 4, device=device)28.3 PyTorch - Autograd
28.3.1 Automatická derivace
# Zapnutí sledování gradientů
x = torch.tensor([2.0], requires_grad=True)
# Forward pass
y = x ** 2 + 3 * x + 1
# Backward pass
y.backward()
# Gradient
print(x.grad) # dy/dx = 2*x + 3 = 7
# Reset gradientů
x.grad.zero_() # In-place reset
# Kontext bez gradientů
with torch.no_grad():
y = x ** 2 # Nesleduje se
# Detach od grafu
y = x.detach() # Nový tensor bez gradientů28.4 PyTorch - Neuronové sítě
28.4.1 Definice modelu
class MLP(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super().__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.fc2 = nn.Linear(hidden_dim, output_dim)
self.relu = nn.ReLU()
def forward(self, x):
x = self.relu(self.fc1(x))
x = self.fc2(x)
return x
model = MLP(784, 128, 10)28.4.2 Vrstvy (nn.Module)
# Lineární vrstvy
nn.Linear(in_features, out_features)
nn.Bilinear(in1, in2, out)
# Konvoluční vrstvy
nn.Conv1d(in_ch, out_ch, kernel_size)
nn.Conv2d(in_ch, out_ch, kernel_size, stride, padding)
# Normalizace
nn.BatchNorm1d(num_features)
nn.BatchNorm2d(num_features)
nn.LayerNorm(normalized_shape)
# Dropout
nn.Dropout(p=0.5)
nn.Dropout2d(p=0.5)
# Aktivační funkce
nn.ReLU()
nn.LeakyReLU(negative_slope=0.01)
nn.Sigmoid()
nn.Tanh()
nn.Softmax(dim=-1)
nn.GELU()
# Pooling
nn.MaxPool2d(kernel_size)
nn.AvgPool2d(kernel_size)
nn.AdaptiveAvgPool2d(output_size)
# Embedding
nn.Embedding(num_embeddings, embedding_dim)
# RNN
nn.RNN(input_size, hidden_size, num_layers)
nn.LSTM(input_size, hidden_size, num_layers)
nn.GRU(input_size, hidden_size, num_layers)
# Transformer
nn.Transformer(d_model, nhead, num_encoder_layers, num_decoder_layers)
nn.TransformerEncoder(encoder_layer, num_layers)
nn.TransformerDecoder(decoder_layer, num_layers)
nn.MultiheadAttention(embed_dim, num_heads)28.4.3 Funkcionální API
# Aktivace
F.relu(x)
F.leaky_relu(x, negative_slope=0.01)
F.sigmoid(x)
F.tanh(x)
F.softmax(x, dim=-1)
F.log_softmax(x, dim=-1)
F.gelu(x)
# Loss funkce
F.mse_loss(pred, target)
F.cross_entropy(logits, target)
F.binary_cross_entropy(pred, target)
F.nll_loss(log_probs, target)
# Dropout
F.dropout(x, p=0.5, training=True)28.4.4 Loss funkce
nn.MSELoss() # Mean Squared Error
nn.L1Loss() # Mean Absolute Error
nn.CrossEntropyLoss() # Cross-entropy (logity)
nn.NLLLoss() # Negative Log-Likelihood
nn.BCELoss() # Binary Cross-Entropy
nn.BCEWithLogitsLoss() # BCE + sigmoid
nn.KLDivLoss() # KL divergence28.4.5 Optimizéry
import torch.optim as optim
# Základní
optim.SGD(model.parameters(), lr=0.01)
optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
optim.SGD(model.parameters(), lr=0.01, momentum=0.9, weight_decay=1e-4)
# Adaptivní
optim.Adam(model.parameters(), lr=0.001)
optim.Adam(model.parameters(), lr=0.001, betas=(0.9, 0.999))
optim.AdamW(model.parameters(), lr=0.001, weight_decay=0.01)
optim.RMSprop(model.parameters(), lr=0.01)
# Learning rate scheduler
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=100)
scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience=5)28.4.6 Trénovací smyčka
model = MLP(784, 128, 10)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# Trénink
model.train()
for epoch in range(num_epochs):
for batch_x, batch_y in dataloader:
# Forward pass
outputs = model(batch_x)
loss = criterion(outputs, batch_y)
# Backward pass
optimizer.zero_grad()
loss.backward()
optimizer.step()
scheduler.step()
# Evaluace
model.eval()
with torch.no_grad():
outputs = model(test_x)
predictions = outputs.argmax(dim=1)28.4.7 Ukládání a načítání
# Uložení celého modelu
torch.save(model, 'model.pt')
model = torch.load('model.pt')
# Uložení pouze vah (doporučeno)
torch.save(model.state_dict(), 'weights.pt')
model.load_state_dict(torch.load('weights.pt'))
# Uložení checkpointu
checkpoint = {
'epoch': epoch,
'model_state_dict': model.state_dict(),
'optimizer_state_dict': optimizer.state_dict(),
'loss': loss,
}
torch.save(checkpoint, 'checkpoint.pt')28.5 PyTorch - Data
28.5.1 DataLoader
from torch.utils.data import Dataset, DataLoader, TensorDataset
# Jednoduchý dataset z tensorů
dataset = TensorDataset(X_tensor, y_tensor)
# DataLoader
dataloader = DataLoader(
dataset,
batch_size=32,
shuffle=True,
num_workers=4,
pin_memory=True
)
# Iterace
for batch_x, batch_y in dataloader:
...28.5.2 Vlastní Dataset
class MyDataset(Dataset):
def __init__(self, data, labels, transform=None):
self.data = data
self.labels = labels
self.transform = transform
def __len__(self):
return len(self.data)
def __getitem__(self, idx):
x = self.data[idx]
y = self.labels[idx]
if self.transform:
x = self.transform(x)
return x, y28.6 Porovnání NumPy vs PyTorch
| Operace | NumPy | PyTorch |
|---|---|---|
| Vytvoření pole | np.array([1,2,3]) |
torch.tensor([1,2,3]) |
| Nuly | np.zeros((3,4)) |
torch.zeros(3,4) |
| Náhodná | np.random.randn(3,4) |
torch.randn(3,4) |
| Reshape | a.reshape(3,4) |
x.view(3,4) |
| Transpozice | a.T |
x.T |
| Součet | np.sum(a) |
x.sum() |
| Maticové násobení | a @ b |
x @ y |
| Norma | np.linalg.norm(a) |
torch.norm(x) |
| Z NumPy | — | torch.from_numpy(a) |
| Do NumPy | — | x.numpy() |
| GPU | — | x.cuda() |
28.7 Tipy a triky
28.7.1 NumPy
# Vektorizace místo cyklů
# Špatně:
result = []
for i in range(len(a)):
result.append(a[i] ** 2)
# Dobře:
result = a ** 2
# Efektivní paměť
a = np.array([1, 2, 3], dtype=np.float32) # 32-bit místo 64-bit
# Kopírování vs view
b = a.copy() # Nová kopie
b = a.view() # Sdílená paměť28.7.2 PyTorch
# Gradient clipping
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
# Zmrazení vrstev
for param in model.fc1.parameters():
param.requires_grad = False
# Počet parametrů
sum(p.numel() for p in model.parameters())
sum(p.numel() for p in model.parameters() if p.requires_grad)
# Mixed precision training
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
with autocast():
output = model(input)
loss = criterion(output, target)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()