CodeBlanks Logo Icon CodeBlanks

backward()

The backward() method computes gradients from the loss.

backward() in training

In training, kayip.backward() fills the .grad of every parameter in the model. Gradient sizes say something about the health of training: if very small, learning has stalled (vanishing gradient); if very large, there is a risk of explosion:

kayip.backward()
for ad, p in model.named_parameters():
    print(ad, p.grad.norm().item())
norm = torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)

clip_grad_norm_ limits the total gradient norm; it prevents explosions especially when training RNNs and transformers.

Gradient accumulation

If memory isn't enough for a large batch, the gradients of a few small batches can be accumulated and applied in one step. Gradient accumulation is used deliberately here:

biriktir = 4
for i, (xb, yb) in enumerate(yukleyici):
    kayip = kayip_fn(model(xb), yb) / biriktir   # keep the mean
    kayip.backward()
    if (i + 1) % biriktir == 0:
        opt.step()
        opt.zero_grad()

The result is roughly equal to training with a batch four times larger.

Practice Gradient clipping

Do one forward and backward pass with the given model and data. Call clip_grad_norm_(model.parameters(), max_norm=0.5); print on one line that the returned (pre-clipping) norm is above 0.5 and that the total norm after clipping doesn't exceed 0.5 (<= 0.5 + 1e-6).

Starter code

model.py
import torch
from torch import nn
from torch.utils.data import TensorDataset, DataLoader

torch.manual_seed(0)
X = torch.randn(200, 2)
y = (X[:, 0] + X[:, 1] > 0).long()
model = nn.Sequential(nn.Linear(2, 16), nn.ReLU(), nn.Linear(16, 2))
kayip_fn = nn.CrossEntropyLoss()
opt = torch.optim.SGD(model.parameters(), lr=0.1)

with torch.no_grad():
    model[2].weight.mul_(20)

# buraya yaz

Sample solution

model.py
import torch
from torch import nn
from torch.utils.data import TensorDataset, DataLoader

torch.manual_seed(0)
X = torch.randn(200, 2)
y = (X[:, 0] + X[:, 1] > 0).long()
model = nn.Sequential(nn.Linear(2, 16), nn.ReLU(), nn.Linear(16, 2))
kayip_fn = nn.CrossEntropyLoss()
opt = torch.optim.SGD(model.parameters(), lr=0.1)

with torch.no_grad():
    model[2].weight.mul_(20)

kayip_fn(model(X), y).backward()
once = torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=0.5)
sonra = torch.sqrt(sum((p.grad ** 2).sum() for p in model.parameters()))
print(once.item() > 0.5, sonra.item() <= 0.5 + 1e-6)

Expected output

True True

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 When should gradient clipping be called?

  • Before the forward pass
  • After training
  • Between backward() and step() Correct answer
  • Before zero_grad()

Explanation: The gradients are limited after they are computed and before they are used.

2 Limit the total gradient norm to 1.

Question
torch.nn.utils.____(model.parameters(), max_norm=1.0)
Answer
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)

Explanation: clip_grad_norm_ scales all gradients together.

3 Match the concepts.

Term Meaning
p.grad.norm() Gradient size
vanishing gradient Learning stalls
clip_grad_norm_ Prevents explosion
accumulation Virtual large batch

All lessons in Advanced