Garfield
YZF Admin
Gradyan kırpmayı, modelin gradyanları hesaplandıktan sonra ancak parametreler güncellenmadan önce uygulayın. PyTorch'ta en yaygın yöntem,
Gradyan kırpma özellikle RNN, LSTM, Transformer veya derin ağlarda gradyanların aşırı büyümesini sınırlamak için kullanılır. Kırpma, hatayı veya kaybı doğrudan düzeltmez; gradyanların büyüklüğünü sınırlar. Adam gibi uyarlamalı veya momentumlu iyileştiricilerde parametre güncellemesinin normuna doğrudan aynı üst sınırı koymaz.
Ön koşul olarak model, kayıp işlevi ve iyileştirici oluşturulmuş olmalı; eğitim döngüsünde
Burada
Önemli bilgi: Kırpma çağrısı
Seçim, kırpmak istediğiniz davranışa bağlıdır:
Çoğu standart eğitim döngüsünde önce norm kırpma denenir. Değer kırpma kullanacaksanız, yine
Norm kırpma eğitimdeki taşmaları azaltabilir; ancak çok düşük bir sınır, yararlı gradyanları da aşırı küçülterek öğrenmeyi yavaşlatabilir. Bu nedenle
Kırpma öncesindeki normu izlemek için dönen değeri geçici olarak yazdırabilirsiniz:
Norm sürekli olarak sınırın çok üstündeyse kırpma yalnızca belirtidir; öğrenme oranı, veri ölçekleri, kayıp hesabı veya model mimarisi de incelenmelidir. Norm çoğu adımda sınırın çok altındaysa seçtiğiniz değer eğitim davranışını neredeyse hiç değiştirmiyor olabilir. Kırpma,
Karışık hassasiyet kullanıyorsanız gradyanları kırpmadan önce ölçeklenmiş gradyanların gerçek büyüklüğe çevrilmesi gerekir.
Kırpma,
loss.backward() sonrasında torch.nn.utils.clip_grad_norm_ çağırmak ve ardından optimizer.step() çalıştırmaktır. Böylece gradyan normu belirlediğiniz üst sınırı aşarsa ölçeklenir; eğitim döngüsünün geri kalanı aynı kalır.Temel uygulama
Gradyan kırpma özellikle RNN, LSTM, Transformer veya derin ağlarda gradyanların aşırı büyümesini sınırlamak için kullanılır. Kırpma, hatayı veya kaybı doğrudan düzeltmez; gradyanların büyüklüğünü sınırlar. Adam gibi uyarlamalı veya momentumlu iyileştiricilerde parametre güncellemesinin normuna doğrudan aynı üst sınırı koymaz.
Ön koşul olarak model, kayıp işlevi ve iyileştirici oluşturulmuş olmalı; eğitim döngüsünde
loss.backward() çağrısı bulunmalıdır.- Gradyanları hesaplayın. İleri geçişten sonra kaybı hesaplayıp
loss.backward()çağrısını çalıştırın. Bu aşamada model parametrelerinin gradyanları oluşur. - Gradyan normunu kırpın.
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm)çağrısını,loss.backward()ileoptimizer.step()arasına yerleştirin.max_norm, izin verilen en yüksek toplam gradyan normudur. - Parametreleri güncelleyin. Kırpma işleminden sonra
optimizer.step()çağrısını çalıştırın. Güncelleme artık kırpılmış gradyanlarla yapılır. - Bir sonraki adıma geçin.
optimizer.zero_grad()çağrısını yeni ileri geçişten önce veya kullandığınız eğitim döngüsünün düzenine göre her güncellemeden sonra çalıştırarak eski gradyanların birikmesini önleyin.
Python:
import torch
model = MyModel()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
criterion = torch.nn.CrossEntropyLoss()
for inputs, targets in train_loader:
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, targets)
loss.backward()
grad_norm = torch.nn.utils.clip_grad_norm_(
model.parameters(),
max_norm=1.0
)
optimizer.step()
Burada
max_norm=1.0, toplam gradyan normu 1,0 değerini aşarsa gradyanların ortak bir katsayıyla küçültülmesini sağlar. Fonksiyonun döndürdüğü grad_norm değeri, kırpma uygulanmadan önceki toplam normu gösterir. Örneğin değer 0,4 ise gradyanlar sınırı aşmamıştır; değer 8,0 ise gradyanlar güncellemeden önce ölçeklenmiştir.Önemli bilgi: Kırpma çağrısı
optimizer.step() sonrasına konulursa mevcut güncellemeyi etkilemez; bir sonraki adıma ait gradyanları da geriye dönük olarak düzeltemez.Norm kırpma ile değer kırpmayı ayırma
clip_grad_norm_, tüm gradyanları toplam normlarına göre birlikte ölçekler. Bu, gradyanların yönünü büyük ölçüde korur. Alternatif olarak torch.nn.utils.clip_grad_value_, her gradyan elemanını ayrı ayrı belirlediğiniz aralıkta tutar.Seçim, kırpmak istediğiniz davranışa bağlıdır:
| Yöntem | Nasıl çalışır? | Ne zaman düşünülür? |
|---|---|---|
| clip_grad_norm_ | Toplam norm sınırı aşılırsa gradyanları ortak katsayıyla küçültür. | Genel eğitim kararlılığı ve patlayan gradyanları sınırlamak için. |
| clip_grad_value_ | Her gradyan değerini ayrı ayrı alt ve üst sınırda tutar. | Tek tek aşırı büyük gradyan değerlerini sınırlamak gerektiğinde. |
loss.backward() sonrasında ve optimizer.step() öncesinde çağırın:
Python:
torch.nn.utils.clip_grad_value_(
model.parameters(),
clip_value=0.5
)
optimizer.step()
Norm kırpma eğitimdeki taşmaları azaltabilir; ancak çok düşük bir sınır, yararlı gradyanları da aşırı küçülterek öğrenmeyi yavaşlatabilir. Bu nedenle
max_norm değerini değiştirirken yalnızca kaybın düşüp düşmediğine değil, gradyan normlarının ne sıklıkla sınıra takıldığına ve doğrulama sonuçlarına da bakın.Gradyan kırpmanın işe yarayıp yaramadığını kontrol etme
Kırpma öncesindeki normu izlemek için dönen değeri geçici olarak yazdırabilirsiniz:
Python:
grad_norm = torch.nn.utils.clip_grad_norm_(
model.parameters(),
max_norm=1.0
)
if not torch.isfinite(grad_norm):
raise RuntimeError("Gradyan normu sonlu değil.")
print(f"Kırpma öncesi gradyan normu: {grad_norm.item():.4f}")
optimizer.step()
Norm sürekli olarak sınırın çok üstündeyse kırpma yalnızca belirtidir; öğrenme oranı, veri ölçekleri, kayıp hesabı veya model mimarisi de incelenmelidir. Norm çoğu adımda sınırın çok altındaysa seçtiğiniz değer eğitim davranışını neredeyse hiç değiştirmiyor olabilir. Kırpma,
NaN üreten hatalı kayıp hesabını veya sayısal taşmayı tek başına çözmez; sonlu olmayan gradyanlarda veri, kayıp ve öğrenme ayarlarını ayrıca kontrol etmek gerekir.Karışık hassasiyet kullanıyorsanız gradyanları kırpmadan önce ölçeklenmiş gradyanların gerçek büyüklüğe çevrilmesi gerekir.
GradScaler kullanılan döngülerde scaler.unscale_(optimizer) çağrısından sonra kırpma yapılır:
Python:
scaler.scale(loss).backward()
scaler.unscale_(optimizer)
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
scaler.step(optimizer)
scaler.update()
Kırpma,
scaler.unscale_(optimizer) sonrasında ve scaler.step(optimizer) öncesinde kalmalıdır. Ölçek kaldırılmadan yapılan kırpma yanlış büyüklükteki gradyanlara uygulanır; güncellemeden sonra yapılan kırpma ise tamamlanmış güncellemeyi değiştirmez.
Son düzenleme: