- Geri yayılım (backpropagation) sinir ağı eğitiminin temelidir; ancak iç işleyişi anlaşılmazsa beklenmedik hatalara yol açan bir “sızdıran soyutlama (leaky abstraction)” yapısıdır
- Sigmoid ve tanh aktivasyon fonksiyonları, ağırlık başlatma yanlış olduğunda gradyan sönmesi (vanishing gradient) nedeniyle eğitimin durmasına yol açabilir
- ReLU, girdi 0 veya daha küçük olduğunda nöronun kalıcı olarak devre dışı kalmasına neden olan ölü ReLU (dead ReLU) olgusunu tetikleyebilir
- RNN'lerde tekrarlanan matris çarpımları nedeniyle gradyan patlaması (exploding gradient) ortaya çıkabilir; bunu önlemek için gradient clipping ya da LSTM kullanmak gerekir
- Geri yayılımın nasıl çalıştığını anlamazsanız, framework bunu otomatik olarak yapsa bile debug etme ve modeli iyileştirme beceriniz ciddi biçimde düşer
Geri yayılımı anlamanın gerekliliği
- Stanford'un CS231n dersinde öğrencilere ileri yayılım ve geri yayılımı doğrudan uygulamalarını isteyen ödevler verilir
- Bazı öğrenciler, TensorFlow gibi framework'ler geri yayılımı otomatik hesapladığı için bunun gereksiz olduğundan şikâyet eder
- Ancak geri yayılım tam bir soyutlama değil, sızdıran bir soyutlamadır; iç işleyiş bilinmezse eğitimin neden başarısız olduğunu anlamak zordur
- Sadece “framework halleder” yaklaşımı, model tasarlama ve debug etme becerisinin zayıflamasına yol açar
Sigmoid'de gradyan sönmesi
- Sigmoid ve tanh doğrusal olmayan fonksiyonlarında giriş değeri büyüdüğünde çıktı 0 ya da 1'e yaklaşır ve doyum (saturation) durumu oluşur
- Bu durumda yerel gradyan z(1-z)*, 0 olur ve geri yayılım sırasında gradyanın aktarımı kesilir
- Sigmoid'in maksimum gradyanı 0.25'tir; yani her geçişte sinyal 1/4 veya daha aza düşer
- Sonuç olarak alt katmanların öğrenme hızı, üst katmanlara göre belirgin biçimde yavaşlar
- Bu nedenle sigmoid katmanları kullanılırken ağırlık başlatma ve veri ön işleme konusunda özellikle dikkatli olunmalıdır
Ölü ReLU problemi
- ReLU, girdi 0 veya daha küçük olduğunda çıktıyı 0 yapan bir fonksiyondur
- İleri yayılımda nöron çıktısı 0 ise geri yayılım sırasında gradyan da 0 olur ve ilgili nöron kalıcı olarak devre dışı kalabilir
- Eğitim sırasında büyük ağırlık güncellemeleri veya yüksek öğrenme oranı nedeniyle nöron “ölü durum”a sabitlenebilir
- Eğitim sonrasında tüm nöronların kayda değer bir kısmının 0 ürettiği durumlar da görülebilir
- Bu yüzden ReLU kullanırken öğrenme oranı ayarı ve başlatma stratejisi önemlidir
RNN'lerde gradyan patlaması
- Basit RNN'lerde her zaman adımında aynı gizli durum matrisi (Whh) tekrar tekrar çarpılır
- Geri yayılım sırasında bu matrisin özdeğerinin (eigenvalue) büyüklüğüne göre gradyan ya 0'a yakınsar ya da sonsuza doğru büyür
- |b| < 1 ise gradyan sönmesi, |b| > 1 ise gradyan patlaması oluşur
- Bunu önlemek için genellikle gradient clipping uygulanır veya LSTM mimarisi kullanılır
DQN kodunda hatalı clipping örneği
- TensorFlow tabanlı bir DQN implementasyonunda
tf.clip_by_value ile delta'nın (Q hatası) doğrudan clip edildiği bir kod bulundu
- Bu yöntemde delta aralığın dışına çıktığında gradyan 0 olur ve eğitim durur
- Asıl amaç gradyan clipping olduğundan, bunun yerine Huber loss kullanılmalıdır
- Örnek kodda, koşullu olarak
tf.square ve tf.abs birleştirilerek Huber kaybı uygulanır
- Bu sorun GitHub issue'su olarak raporlandı ve hemen düzeltildi
Sonuç
- Geri yayılım, basit bir otomasyon aracı değil; bir credit assignment sistemidir ve karmaşık sonuçlar doğurur
- İç işleyiş anlaşılmazsa model kararsızlığı, eğitim başarısızlığı ve debug sınırları ile karşılaşılır
- Geri yayılım matematiksel olarak çok zor değildir; CS231n dersi ve ödevleri üzerinden sezgisel biçimde öğrenilebilir
- Geri yayılımı anlamak, sinir ağı tasarlama ve problem çözme becerisini büyük ölçüde geliştirir
- Framework'lerin otomatik türev alma özelliklerine dayanmak yerine geri yayılımın gerçek akışını kavramak önemlidir
1 yorum
Hacker News görüşleri
Burada backpropagation sanki haksız yere kötü bir üne sahipmiş gibi geliyor
Aslında bu tartışma, backpropagation’ın kendisinden çok gradient ve gradient descent türevlerinin optimizasyon sürecinde ne kadar kusurlu bir soyutlama olduğu ile ilgili
Backpropagation yalnızca bileşik fonksiyonların türevini hesaplayan bir algoritmadır; sigmoid’i üst üste yığmaktan doğan gradient sönmesi gibi sorunlar backpropagation’ın değil, fonksiyonun kendisinin özelliğidir
İnsanlara backward pass’i doğrudan uygulatmanın nedeni, türevi bizzat hesaplayarak üstel terimlerin nasıl etkilediğini sezgisel olarak kavramalarını sağlamaktır
Asıl nokta, bazı durumlarda backpropagation’ın ayrıntılarını (gradient hesabı dahil) soyutlamanın mümkün olmamasıdır
Özellikle gradient descent kullandığında bu geçerli; başka küresel optimizasyon algoritmalarında sorun daha az olabilir
Şu anda pratikte derin öğrenmede gradient hesaplamanın tek yolu backpropagation olduğu için, bu soyutlamadaki sızıntı gerçektir
Karpathy’nin katkılarına saygım var ama yazıları ve konuşmaları sık sık kavramsal ayrımları bulanıklaştırıyor ve yanlış anlamalara yol açıyor
Onun seviyesindeki birinden daha yüksek doğruluk beklenir
Karpathy’nin derin öğrenme eğitimine katkısı gerçekten muazzam
Kısa yazılardan RNN üzerine klasik bir metne kadar, ayrıca YouTube dersleri ve GitHub projeleri de çok iyi
Yakın zamanda yayımlanan nanochat da bunun harika bir örneği; küçük, net ve tam örnekler öğrenenler için çok değerlidir
Sonradan fark ettim ki onların ilgisi LLM’leri anlamaktan çok onlara güvenip kullanmaya yönelikti
Aslında LLM’lerin nasıl çalıştığından çok, “zeki makinelerin her şeyi yaptığı bir toplum” gibi spekülatif tartışmalar ilgilerini çekiyordu
O, sadece “ChatGPT’ye sormak” yerine bizzat arama yapıyor, kod okuyor ve bug buluyor
İşte gerçek öğrenme böyle bir araştırmacı yaklaşım ile oluyor
Yüksek lisan sırasında, bir makaleye dayanarak backpropagation’ı doğrudan uygulama ödevi yapmıştım
Sadece matematiksel işlemlerle forward ve backward pass yazıyorduk; o yılın en iyi öğrenme deneyimiydi
İnsan böyle bir şeyi kendi başına pek yapmıyor ama zorunlu olunca inanılmaz faydalı oluyor
Bir de ağırlıkların ve bias’ların eğitim sırasında nasıl değiştiğini görselleştiren bir UI yapmıştım
Backpropagation ile optimizer arasındaki ilişkiyi merak ediyordum
SGD gradient yönünde basitçe ilerler ama Adam gibi gelişmiş optimizer’lar gradient’i doğrudan kullanmak yerine normalizasyon, momentum, clipping gibi işlemler uygular
O halde gerçekten tam doğru gradient hesabına ihtiyaç var mı, yoksa yalnızca yaklaşık yönü bilmek yeterli mi?
İlgili çalışmalar arasında SGD gürültüsü makaleleri, görselleştirme çalışması gibi kaynaklar var
Ama yönü kabaca tahmin etmek tehlikelidir — çünkü loss fonksiyonunun eğriliği (Hessian) hızla değişebilir
Aslında stochastic gradient descent böyle fikirlerden doğdu; daha sonra Direct Feedback Alignment gibi yaklaşımlar da ortaya çıktı
Ben Recht’in optimizasyon ile reinforcement learning ilişkisini özetlediği yazı da ilginçtir
Burada önemli olan loss fonksiyonunun değerinden çok gradient ve eğriliğin şeklidir
Adam gibi optimizer’lar, birinci dereceden yaklaşıklarla her parametrenin ölçek duyarlılığını tahmin edip gradient’i buna göre ayarlar
Daha yüksek dereceden optimizasyon, ReLU gibi doğrusal olmayan fonksiyonlarda mümkün değildir
Bu, vanishing gradient sorununu çözmek için gerekli bir önlemdir
Yüksek boyutlu uzaylarda küçük hatalar bile büyük etki yaratabildiği için, doğru gradient hesabı çok önemlidir
Sorun, “yaklaşık yönü” nasıl hesaplayacağını belirlemekte başlıyor
AdamW gibi gelişmiş optimizer’lar bile hâlâ merkezde gradient kullanır
2016 civarında gradient clipping gibi numaraların çok daha sık kullanıldığını hatırlıyorum
Örneğin Alex Graves’in 2013 tarihli Sequence Generation with RNNs makalesinde de LSTM’de gradient patlamasını önlemek için clipping kullanıldığını açıkça söylüyor
Ben de backpropagation’ın önemini o kadar hissediyordum ki, yalnızca PyTorch autograd üzerine olan uzmanlaşmış bir ders bile almıştım
Şimdi framework’ler clipping desteği veriyor ve eğitim sorunlarına dair anlayış da arttı
Ama sorun tamamen ortadan kalkmış değil — ReLU ve GELU hâlâ temel aktivasyon fonksiyonları, LLM eğitimi de hâlâ bir tür “black art” sayılır
Hugging Face’in Smol Training Playbook’u bunun kanıtı
Uzun vadede, aktivasyon fonksiyonu çeşitliliğine dayanıklı modeller eğitmenin avantajlı olabileceğini düşünüyorum
Örneğin ReLU, Swish, GELU gibi fonksiyonları rastgele değiştirerek eğitirsen, dropout’a benzer bir regularization etkisi elde edebilirsin
Böylece inference sırasında hesaplama maliyeti en düşük olan fonksiyona geçmek de mümkün olabilir
Orijinal başlık olan “Yes you should understand backprop” çok daha açık ve daha iyi
Kodu çok fazla şeyi senin yerine yapmaya bırakırsan, “sihirli biçimde çalışıyor” yanılgısına düşmek kolaydır
Lisansüstünde convolution ve backpropagation’ı elle hesaplamış olmam bana çok yardımcı oldu
“Framework backward pass’i otomatik hesaplıyorsa neden bunu kendimiz yazalım ki?” sorusu,
“Hesap makinesi varken neden toplama öğrenelim?” mantığına benzediği için kaygı verici
Derleyicileri, sıralama algoritmalarını ya da transistörlerin nasıl çalıştığını anlamanın yararlı olması gibi, backpropagation öğrenmek de değerlidir
Ancak öğrenme süresi sınırlıdır; dolayısıyla asıl soru bunun başka konulara göre daha faydalı olup olmadığıdır
Backpropagation, iç işleyiş bilinmediğinde gizli başarısızlık modlarını fark etmeyi zorlaştırdığı için öğrenmeye değer
Ben de bunu birkaç kez kendim uyguladım; yeni bir dili değerlendirmek için tam kararında bir karmaşıklığa sahip
Derin öğrenmeyi ilk öğrenirken backpropagation bana adeta sihir gibi gelmişti
Ama kendim uygulayınca bunun sadece ardışık hesaplamalardan ibaret olduğunu gördüm; bu da debug yaparken ya da loss’un neden takıldığını anlamaya çalışırken bana çok daha fazla güven verdi
Derin öğrenme öğrenen herkesin en az bir kez doğrudan uygulamasını tavsiye ederim
Karşı görüş de var
Öğrencilerin illa NumPy ile backpropagation uygulaması gerektiğini düşünmüyorum
BackProp’taki sızıntı sorununu araştırmacılar yeni optimizer’larla çözer, geliştiriciler ise sadece iyi hyperparameter bulur
Sorunun bir kısmı model tasarımı veya eğitim döngüsünden kaynaklanır
Örneğin gradient clipping çoğu framework’te varsayılan olarak açık değildir
Bu yazı, araştırmacı ya da akademik bakış açısındaki okurları hedefliyor
Sigmoid veya ReLU gibi fonksiyonların gradient davranışını anlamazsan, patlama ya da sönme sorunlarını çözemezsin
Yeni model mimarileri kurmak istiyorsan backpropagation’ın nasıl çalıştığını anlamalısın; aksi takdirde eğitim başarısız olabilir ya da performans düşer
Soyutlamanın içine girip bakmadan, gerçekten bilmediğin alanları (unknown unknowns) fark etmek mümkün olmuyor