🏷️sec_bptt
Şimdiye kadar defalarca patlayan gradyanlar, kaybolan gradyanlar, ve RNN'ler için gradyan ayırma ihtiyacı gibi şeyler ima ettik. Örneğin, :numref:sec_rnn_scratch
'te dizi üzerinde detach
işlevini çağırdık. Hızlı bir model inşa edebilmek ve nasıl çalıştığını görmek amacıyla, bunların hiçbiri gerçekten tam olarak açıklanmadı. Bu bölümde, dizi modelleri için geri yaymanın ayrıntılarını ve matematiğin neden (ve nasıl) çalıştığını biraz daha derinlemesine inceleyeceğiz.
RNN'leri ilk uyguladığımızda gradyan patlamasının bazı etkileriyle karşılaştık (:numref:sec_rnn_scratch
). Özellikle, alıştırmaları çözdüyseniz, doğru yakınsamayı sağlamak için gradyan kırpmanın hayati önem taşıdığını görürsünüz. Bu sorunun daha iyi anlaşılmasını sağlamak için, bu bölümde gradyanların dizi modellerinde nasıl hesaplandığını incelenecektir. Nasıl çalıştığına dair kavramsal olarak yeni bir şey olmadığını unutmayın. Sonuçta, biz hala sadece gradyanları hesaplamak için zincir kuralını uyguluyoruz. Bununla birlikte, geri yayma (:numref:sec_backprop
) tekrar gözden geçirmeye değerdir.
:numref:sec_backprop
'te MLP'lerde ileri ve geri yaymayı ve hesaplama çizgelerini tanımladık. Bir RNN'de ileriye yayma nispeten basittir. Zamanda geri yayma aslında RNN'lerde geri yaymanın belirli bir uygulamasıdır :cite:Werbos.1990
. Model değişkenleri ve parametreleri arasındaki bağımlılıkları elde etmek için bir RNN'nin hesaplama çizgesini bir kerede bir adım genişletmemizi gerektirir. Ardından, zincir kuralına bağlı olarak, gradyanları hesaplamak ve depolamak için geri yayma uygularız. Diziler oldukça uzun olabileceğinden, bağımlılık oldukça uzun olabilir. Örneğin, 1000 karakterlik bir dizi için, ilk andıç nihai konumdaki andıç üzerinde potansiyel olarak önemli bir etkiye sahip olabilir. Bu gerçekten hesaplamalı olarak mümkün değildir (çok uzun sürer ve çok fazla bellek gerektirir) ve bizim bu çok zor gradyana ulaşmadan önce 1000'den fazla matrisi çarpamıza gerek duyar. Bu, hesaplamalı ve istatistiksel belirsizliklerle dolu bir süreçtir. Aşağıda neler olduğunu ve bunu pratikte nasıl ele alacağımızı aydınlatacağız.
🏷️subsec_bptt_analysis
Bir RNN'nin nasıl çalıştığını anlatan basitleştirilmiş bir modelle başlıyoruz. Bu model, gizli durumun özellikleri ve nasıl güncellendiği hakkındaki ayrıntıları görmezden gelir. Buradaki matematiksel gösterim, skalerleri, vektörleri ve matrisleri eskiden olduğu gibi açıkça ayırt etmez. Bu ayrıntılar, analiz için önemsizdir ve öbür türlü yalnızca bu alt bölümdeki gösterimi karıştırmaya hizmet edecekti.
Bu basitleştirilmiş modelde, subsec_rnn_w_hidden_states
'teki tartışmalarımızı hatırlayın, girdi ve gizli durum, gizli katmandaki bir ağırlık değişkeni ile çarpılacak şekilde bitiştirilebilir. Böylece, sırasıyla gizli katmanın ve çıktı katmanının ağırlıklarını belirtmek için
$$\begin{aligned}h_t &= f(x_t, h_{t-1}, w_h),\o_t &= g(h_t, w_o),\end{aligned}$$
:eqlabel:eq_bptt_ht_ot
burada
Geri yayma için, özellikle
$$\begin{aligned}\frac{\partial L}{\partial w_h} & = \frac{1}{T}\sum_{t=1}^T \frac{\partial l(y_t, o_t)}{\partial w_h} \& = \frac{1}{T}\sum_{t=1}^T \frac{\partial l(y_t, o_t)}{\partial o_t} \frac{\partial g(h_t, w_o)}{\partial h_t} \frac{\partial h_t}{\partial w_h}.\end{aligned}$$
:eqlabel:eq_bptt_partial_L_wh
Çarpımın :eqref:eq_bptt_partial_L_wh
'teki birinci ve ikinci faktörlerinin hesaplanması kolaydır. eq_bptt_ht_ot
'teki yinelemeli hesaplamaya göre,
eq_bptt_partial_ht_wh_recur
Yukarıdaki gradyanı türetmek için,
eq_bptt_at
:eqref:eq_bptt_partial_ht_wh_recur
'teki gradyan hesaplama eq_bptt_at
'deki, :eqref:eq_bptt_partial_ht_wh_recur
'teki yinelemeli hesaplamayı kaldırabiliriz.
eq_bptt_partial_ht_wh_gen
Açıkçası, :eqref:eq_bptt_partial_ht_wh_gen
'teki tam toplamı hesaplayabiliriz. Fakat, bu çok yavaştır ve gradyanlar patlayabilir, çünkü ilkleme koşullarındaki ince değişiklikler sonucu potansiyel olarak çok etkileyebilir. Yani, ilk koşullardaki minimum değişikliklerin sonuçta orantısız değişikliklere yol açtığı kelebek etkisine benzer şeyler görebiliriz. Bu aslında tahmin etmek istediğimiz model açısından oldukça istenmeyen bir durumdur. Sonuçta, iyi genelleyen gürbüz tahminciler arıyoruz. Bu nedenle bu strateji pratikte neredeyse hiç kullanılmaz.
Alternatif olarak, eq_bptt_partial_ht_wh_gen
'deki toplamı kesebiliriz. Bu aslında şimdiye kadar tartıştığımız şey, örneğin :numref:sec_rnn_scratch
'teki gradyanları ayırdığımız zaman gibi. Bu, toplamı Jaeger.2002
. Bunun sonuçlarından biri, modelin uzun vadeli sonuçlardan ziyade kısa vadeli etkilere odaklanmasıdır. Bu aslında arzu edilendir, çünkü tahminleri daha basit ve daha kararlı modellere yöneltir.
Son olarak, eq_bptt_partial_ht_wh_recur
'teki
Bu Tallec.Ollivier.2017
tarafından önerilmiştir.
:numref:fig_truncated_bptt
, RNN'ler için zamanda geri yayma kullanan Zaman Makinesi kitabının üç stratejideki ilk birkaç karakterini analiz ederek göstermektedir:
- İlk satır, metni farklı uzunluklardaki bölümlere ayıran rasgele kesmedir.
- İkinci satır, metni aynı uzunlukta altdizilere kıran düzenli kesimdir. Bu RNN deneylerinde yaptığımız şeydir.
- Üçüncü satır, hesaplaması mümkün olmayan bir ifadeye yol açan zamanda tam geri yaymadır.
Ne yazık ki, teoride çekici iken, rasgele kesme, büyük olasılıkla bir dizi faktöre bağlı olarak düzenli kesmeden çok daha iyi çalışmaz. Birincisi, bir gözlemin geçmişe birkaç geri yayma adımından sonraki etkisi, pratikteki bağımlılıkları yakalamak için oldukça yeterlidir. İkincisi, artan varyans, gradyanın daha fazla adımla daha doğru olduğu gerçeğine karşı yarışır. Üçüncüsü, aslında sadece kısa bir etkileşim aralığına sahip modeller istiyoruz. Bu nedenle, zamanda düzenli kesilmiş geri yayma, arzu edilebilecek hafif bir düzenlileştirici etkiye sahiptir.
Genel prensibi tartıştıktan sonra, zamanda geriye yaymayı ayrıntılı olarak ele alalım. :numref:subsec_bptt_analysis
'teki analizden farklı olarak, aşağıda, amaç fonksiyonun gradyanlarının tüm ayrıştırılmış model parametrelerine göre nasıl hesaplanacağını göstereceğiz. İşleri basit tutmak için, gizli katmandaki etkinleştirme işlevi olarak birim eşlemelerini kullanan ek girdi parametresiz bir RNN'yi göz önünde bulunduruyoruz (
$$\begin{aligned}\mathbf{h}t &= \mathbf{W}{hx} \mathbf{x}t + \mathbf{W}{hh} \mathbf{h}{t-1},\ \mathbf{o}t &= \mathbf{W}{qh} \mathbf{h}{t},\end{aligned}$$
burada $\mathbf{W}{hx} \in \mathbb{R}^{h \times d}$, $\mathbf{W}{hh} \in \mathbb{R}^{h \times h}$ ve
RNN'nin hesaplanması sırasında model değişkenleri ve parametreleri arasındaki bağımlılıkları görselleştirmek için, model için :numref:fig_rnn_bptt
'te gösterildiği gibi bir hesaplama çizgesi çizebiliriz. Örneğin, 3. zaman adımındaki, $\mathbf{h}3$ gizli durumlarının hesaplanması model parametreleri $\mathbf{W}{hx}$ ve
Az önce belirtildiği gibi, :numref:fig_rnn_bptt
'teki model parametreleri $\mathbf{W}{hx}$, $\mathbf{W}{hh}$ ve $\mathbf{W}{qh}$'dır. Genel olarak, bu modelin eğitimi $\partial L/\partial \mathbf{W}{hx}$, $\partial L/\partial \mathbf{W}{hh}$ ve $\partial L/\partial \mathbf{W}{qh}$ parametrelerine göre gradyan hesaplama gerektirir. :numref:fig_rnn_bptt
'teki bağımlılıklara göre, sırayla gradyanları hesaplamak ve depolamak için okların ters yönünde ilerleyebiliriz. Zincir kuralında farklı şekillerdeki matrislerin, vektörlerin ve skalerlerin çarpımını esnek bir şekilde ifade etmek için :numref:sec_backprop
'te açıklandığı gibi
Her şeyden önce, amaç işlevinin türevini herhangi bir
eq_bptt_partial_L_ot
Şimdi, amaç fonksiyonun gradyanını çıktı katmanındaki $\mathbf{W}{qh}$ parametresine göre hesaplayabiliriz: $\partial L/\partial \mathbf{W}{qh} \in \mathbb{R}^{q \times h}$. :numref:fig_rnn_bptt
temel alınarak amaç fonksiyonu
$$ \frac{\partial L}{\partial \mathbf{W}{qh}} = \sum{t=1}^T \text{prod}\left(\frac{\partial L}{\partial \mathbf{o}t}, \frac{\partial \mathbf{o}t}{\partial \mathbf{W}{qh}}\right) = \sum{t=1}^T \frac{\partial L}{\partial \mathbf{o}_t} \mathbf{h}_t^\top, $$
burada eq_bptt_partial_L_ot
'teki gibi hesaplanır.
Daha sonra, :numref:fig_rnn_bptt
'te gösterildiği gibi,
$$\frac{\partial L}{\partial \mathbf{h}_T} = \text{prod}\left(\frac{\partial L}{\partial \mathbf{o}_T}, \frac{\partial \mathbf{o}_T}{\partial \mathbf{h}T} \right) = \mathbf{W}{qh}^\top \frac{\partial L}{\partial \mathbf{o}_T}.$$
:eqlabel:eq_bptt_partial_L_hT_final_step
$$\frac{\partial L}{\partial \mathbf{h}t} = \text{prod}\left(\frac{\partial L}{\partial \mathbf{h}{t+1}}, \frac{\partial \mathbf{h}_{t+1}}{\partial \mathbf{h}_t} \right) + \text{prod}\left(\frac{\partial L}{\partial \mathbf{o}t}, \frac{\partial \mathbf{o}t}{\partial \mathbf{h}t} \right) = \mathbf{W}{hh}^\top \frac{\partial L}{\partial \mathbf{h}{t+1}} + \mathbf{W}{qh}^\top \frac{\partial L}{\partial \mathbf{o}_t}.$$
:eqlabel:eq_bptt_partial_L_ht_recur
Analiz için, herhangi bir zaman adım
$$\frac{\partial L}{\partial \mathbf{h}t}= \sum{i=t}^T {\left(\mathbf{W}{hh}^\top\right)}^{T-i} \mathbf{W}{qh}^\top \frac{\partial L}{\partial \mathbf{o}_{T+t-i}}.$$
:eqlabel:eq_bptt_partial_L_ht
:eqref:eq_bptt_partial_L_ht
'ten bu basit doğrusal örneğin uzun dizi modellerinin bazı temel problemlerini zaten sergilediğini görebiliyoruz: subsec_bptt_analysis
'te tartışıldığı gibi, zaman adımlarını hesaplama açısından uygun bir boyutta kesmektir. Pratikte, bu kesme, belirli bir sayıda zaman adımından sonra gradyanı ayırarak gerçekleştirilir. Daha sonra uzun ömürlü kısa-dönem belleği gibi daha gelişmiş dizi modellerinin bunu daha da hafifletebileceğini göreceğiz.
Son olarak :numref:fig_rnn_bptt
,
$$ \begin{aligned} \frac{\partial L}{\partial \mathbf{W}{hx}} &= \sum{t=1}^T \text{prod}\left(\frac{\partial L}{\partial \mathbf{h}t}, \frac{\partial \mathbf{h}t}{\partial \mathbf{W}{hx}}\right) = \sum{t=1}^T \frac{\partial L}{\partial \mathbf{h}t} \mathbf{x}t^\top,\ \frac{\partial L}{\partial \mathbf{W}{hh}} &= \sum{t=1}^T \text{prod}\left(\frac{\partial L}{\partial \mathbf{h}t}, \frac{\partial \mathbf{h}t}{\partial \mathbf{W}{hh}}\right) = \sum{t=1}^T \frac{\partial L}{\partial \mathbf{h}t} \mathbf{h}{t-1}^\top, \end{aligned} $$
burada :eqref:eq_bptt_partial_L_hT_final_step
ve :eqref:eq_bptt_partial_L_ht_recur
ile yinelemeli hesaplanan
Zamanda geri yayma, RNN'lerde geri yayma uygulanması olduğundan, :numref:sec_backprop
'te açıkladığımız gibi, RNN'leri eğitmek zamanda geri yayma ile ileriye doğru yaymayı değiştirir. Dahası, zamanda geri yayma yukarıdaki gradyanları hesaplar ve sırayla depolar. Özellikle, depolanan ara değerler yinelemeli hesaplamaları önlemek için yeniden kullanılır, örneğin $\partial L / \partial \mathbf{W}{hx}$ ve $\partial L / \partial \mathbf{W}{hh}$ hesaplamalarında kullanılacak
- Zamanda geriye yayma, sadece geri yaymanın gizli bir duruma sahip dizi modellerindeki bir uygulamasıdır.
- Hesaplama kolaylığı ve sayısal kararlılık için kesme gereklidir, örneğin düzenli kesme ve rasgele kesme gibi.
- Matrislerin yüksek kuvvetleri ıraksayan veya kaybolan özdeğerlere yol açabilir. Bu, patlayan veya kaybolan gradyanlar şeklinde kendini gösterir.
- Verimli hesaplama için ara değerler zamanda geri yayma sırasında önbelleğe alınır.
-
$\lambda_i$ özdeğerleri $\mathbf{v}i$ ($i = 1, \ldots, n$) özvektörlerine karşılık gelen bir simetrik matrisimiz $\mathbf{M} \in \mathbb{R}^{n \times n}$ olduğunu varsayalım. Genelleme kaybı olmadan, $|\lambda_i| \geq |\lambda{i+1}|$ diye sıralanmış olduğunu varsayalım.-
$\lambda_i^k$ 'nin$\mathbf{M}^k$ 'nin özdeğerleri olduğunu gösterin. - Yüksek olasılıkla
$\mathbf{x} \in \mathbb{R}^n$ rastgele vektörü için$\mathbf{M}^k \mathbf{x}$ özvektörünün$\mathbf{M}$ 'deki$\mathbf{v}_1$ özvektörüyle hizalanmış olacağını kanıtlayın. Bu ifadeyi formüle dökün. - Yukarıdaki sonuç RNN'lerdeki gradyanlar için ne anlama geliyor?
-
- Gradyan kırpmanın yanı sıra, yinelemeli sinir ağlarında gradyan patlaması ile başa çıkmak için başka yöntemler düşünebiliyor musunuz?