Reference patterns for PyTorch training, evaluation, and deployment. Use when you need help with skill pytorch patterns.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add anubhavg-icpl/vibe --skill skill-pytorch-patterns --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Skill Pytorch Patterns?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-skill-pytorch-patterns)More formats (shields.io, HTML) on the badges page.
---
name: skill-pytorch-patterns
description: Reference patterns for PyTorch training, evaluation, and deployment. Use when you need help with skill pytorch patterns.
license: CC-BY-NC-SA-4.0
phase: 03
lesson: 11
metadata:
version: 1.0.0
tags: [pytorch, training, deep-learning, gpu, patterns]
---
## Canonical Training Loop
```python
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = Model().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=0.01)
for epoch in range(num_epochs):
model.train()
for inputs, targets in train_loader:
inputs, targets = inputs.to(device), targets.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, targets)
loss.backward()
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
optimizer.step()
model.eval()
with torch.no_grad():
for inputs, targets in val_loader:
inputs, targets = inputs.to(device), targets.to(device)
outputs = model(inputs)
```
## Mixed Precision Training
```python
from torch.amp import autocast, GradScaler
scaler = GradScaler()
for inputs, targets in train_loader:
inputs, targets = inputs.to(device), targets.to(device)
optimizer.zero_grad()
with autocast(device_type="cuda"):
outputs = model(inputs)
loss = criterion(outputs, targets)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
```
Use when: training on GPU with float16-capable hardware (V100, A100, H100, RTX 3090+). Expect ~1.5-2x speedup and ~50% memory reduction.
## Gradient Accumulation
```python
accumulation_steps = 4
optimizer.zero_grad()
for i, (inputs, targets) in enumerate(train_loader):
inputs, targets = inputs.to(device), targets.to(device)
outputs = model(inputs)
loss = criterion(outputs, targets) / accumulation_steps
loss.backward()
if (i + 1) % accumulation_steps == 0:
optimizer.step()
optimizer.zero_grad()
```
Use when: effective batch size needs to be larger than GPU memory allows. Dividing loss by accumulation_steps keeps gradient scale consistent.
## Save and Load
```python
torch.save({
"epoch": epoch,
"model_state_dict": model.state_dict(),
"optimizer_state_dict": optimizer.state_dict(),
"loss": loss.item(),
}, "checkpoint.pt")
checkpoint = torch.load("checkpoint.pt", weights_only=True)
model.load_state_dict(checkpoint["model_state_dict"])
optimizer.load_state_dict(checkpoint["optimizer_state_dict"])
```
Always save optimizer state for resuming training. For inference-only, save just `model.state_dict()`.
## Custom Dataset
```python
class CustomDataset(torch.utils.data.Dataset):
def __init__(self, data_dir, transform=None):
self.samples = self._load_samples(data_dir)
self.transform = transform
def __len__(self):
return len(self.samples)
def __getitem__(self, idx):
x, y = self.samples[idx]
if self.transform:
x = self.transform(x)
return x, y
def _load_samples(self, data_dir):
...
```
## DataLoader Configuration
```python
train_loader = torch.utils.data.DataLoader(
dataset,
batch_size=64,
shuffle=True,
num_workers=4,
pin_memory=True,
drop_last=True,
persistent_workers=True,
)
```
| Parameter | What it does | When to use |
|-----------|-------------|-------------|
| num_workers=4 | Parallel data loading | Always on multi-core machines |
| pin_memory=True | Page-locked CPU memory | When training on GPU |
| drop_last=True | Drop incomplete final batch | When using BatchNorm |
| persistent_workers=True | Keep workers alive across epochs | When num_workers > 0 |
## Learning Rate Schedules
```python
scheduler = torch.optim.lr_scheduler.OneCycleLR(
optimizer,
max_lr=1e-3,
total_steps=num_epochs * len(train_loader),
pct_start=0.1,
)
for epoch in range(num_epochs):
for inputs, targets in train_loader:
...
optimizer.step()
scheduler.step()
```
OneCycleLR: best default for most tasks. Warms up to max_lr, then cosine decays. Call `scheduler.step()` after every batch, not every epoch.
## Weight Initialization
```python
def init_weights(module):
if isinstance(module, nn.Linear):
nn.init.kaiming_normal_(module.weight, nonlinearity="relu")
if module.bias is not None:
nn.init.zeros_(module.bias)
elif isinstance(module, nn.Conv2d):
nn.init.kaiming_normal_(module.weight, mode="fan_out", nonlinearity="relu")
model.apply(init_weights)
```
## Inference Mode
```python
model.eval()
with torch.inference_mode():
outputs = model(inputs)
```
`torch.inference_mode()` is faster than `torch.no_grad()` because it disables autograd entirely rather than just suppressing gradient computation.
## Common Mistakes Checklist
1. Applying softmax before CrossEntropyLoss (it includes log_softmax internally)
2. Forgetting to call model.eval() during validation
3. Forgetting to move tensors to the same device as the model
4. Not calling optimizer.zero_grad() (gradients accumulate by default)
5. Using torch.no_grad() during training (disables gradient computation)
6. Setting num_workers too high (spawns too many processes, thrashes memory)
7. Not using pin_memory=True when training on GPU
8. Saving the entire model object instead of state_dict (breaks on refactor)
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!