CodeBlanks Logo Icon CodeBlanks

backward()

backward() metodu, loss'tan gradyanları hesaplar.

backward() eğitimde

Eğitimde kayip.backward(), modeldeki her parametrenin .grad'ını doldurur. Gradyan büyüklükleri eğitimin sağlığı hakkında bilgi verir: çok küçükse öğrenme durmuştur (sönen gradyan), çok büyükse patlama riski vardır:

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_ toplam gradyan normunu sınırlar; özellikle RNN ve transformer eğitiminde patlamaları önler.

Gradyan biriktirme

Bellek büyük toplu veriye yetmiyorsa, birkaç küçük toplu verinin gradyanı biriktirilip tek adımda uygulanabilir. Gradyanların birikmesi burada bilerek kullanılır:

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

Sonuç, dört kat büyük bir toplu veriyle eğitime yaklaşık eşittir.

Uygulama Gradyan kırpma

Hazır model ve veriyle bir ileri ve geri yayılım yap. clip_grad_norm_(model.parameters(), max_norm=0.5) çağır; dönen (kırpma öncesi) normun 0.5'ten büyük olduğunu ve kırpma sonrası toplam normun 0.5'i aşmadığını (<= 0.5 + 1e-6) aynı satırda yazdır.

Başlangıç kodu

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

Örnek çözüm

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)

Beklenen çıktı

True True

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Gradyan kırpma ne zaman çağrılmalıdır?

  • İleri yayılımdan önce
  • Eğitimden sonra
  • backward() ile step() arasında Doğru cevap
  • zero_grad()'dan önce

Açıklama: Gradyanlar hesaplandıktan sonra, kullanılmadan önce sınırlanır.

2 Toplam gradyan normunu 1 ile sınırla.

Soru
torch.nn.utils.____(model.parameters(), max_norm=1.0)
Cevap
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)

Açıklama: clip_grad_norm_ tüm gradyanları birlikte ölçekler.

3 Kavramları eşleştir.

Kavram Anlamı
p.grad.norm() Gradyan büyüklüğü
sönen gradyan Öğrenme durur
clip_grad_norm_ Patlamayı önler
biriktirme Sanal büyük toplu veri

İleri seviye bölümündeki tüm dersler