Masalah Kecerunan Lenyap dalam Langkah Masa Mendalam
Pelajar akan memerhatikan kecerunan yang meletup dan lenyap dalam RNN mendalam melalui perekodan norma kecerunan, serta memahami sebab jujukan panjang menjadikan latihan tidak stabil.
Masalah Kecerunan Lenyap dalam Langkah Masa Mendalam ialah pelajaran Machine Learning Academy percuma di CoddyKit. Ini ialah pelajaran 2 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Machine Learning Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Machine Learning Academy merangkumi sejumlah 4 pelajaran.
Kecerunan Mesti Merentasi Masa
Untuk mempelajari kebergantungan jarak jauh dalam sesuatu jujukan, kecerunan daripada kehilangan pada timestep terakhir mesti bergerak ke belakang melalui setiap timestep bagi mengemas kini parameter yang memproses input awal. Bagi jujukan sepanjang T, ini bermaksud mendarab matriks pemberat W_hh dengan dirinya sendiri sebanyak T kali semasa BPTT. Pendaraban berulang ini ialah punca utama kedua-dua kecerunan yang lenyap (pereputan eksponen) dan kecerunan yang meletup (pertumbuhan eksponen).
import torch
# Conceptual illustration of gradient travel through T steps
# Gradient = dL/dh_T * (W_hh)^T * ...
# If W_hh has spectral radius < 1:
W_small = torch.eye(4) * 0.9
print('W^10 max value:', (W_small @ W_small @ W_small @
W_small @ W_small @ W_small @
W_small @ W_small @ W_small @ W_small).abs().max().item())
# -> very small: gradient vanishes
# If W_hh has spectral radius > 1:
W_big = torch.eye(4) * 1.1
print('W^10 max value:', (W_big ** 10).abs().max().item())
# -> very large: gradient explodesPunca Matematik Kecerunan yang Lenyap
Semasa BPTT, kecerunan kehilangan terhadap keadaan tersembunyi pada timestep t melibatkan hasil darab matriks Jacobian h terhadap h pada setiap langkah dari t hingga T. Jacobian pada setiap langkah melibatkan diag(f'(h_t)) * W_hh, dengan f' ialah terbitan pengaktifan. Bagi tanh, f' dihadkan oleh 1, dan pemberat rawak lazimnya mempunyai jejari spektrum kurang daripada 1 — maka hasil darab T matriks ini mendorong kecerunan menjadi sifar secara eksponen dengan pantas apabila T bertambah.
import torch
# Track gradient norm through BPTT
def simulate_bptt_gradient(T, weight_scale=0.9):
W = torch.eye(8) * weight_scale
grad = torch.ones(8) # gradient at final timestep
norms = [grad.norm().item()]
for t in range(T):
grad = W.T @ grad # one BPTT step
norms.append(grad.norm().item())
return norms
norms = simulate_bptt_gradient(T=20)
print('Gradient norms over 20 steps:')
print([f'{n:.4f}' for n in norms[::5]])
# Decreases from 2.83 -> nearly 0 after 20 stepsMemerhatikan Kecerunan yang Lenyap Secara Eksperimen
Anda boleh memerhatikan kecerunan yang lenyap secara langsung dengan merekodkan norma kecerunan pada setiap timestep semasa BPTT. Daftarkan cangkuk backward pada keadaan tersembunyi setiap langkah RNN untuk menangkap magnitud kecerunan. Dalam RNN asas dengan 50 langkah, kecerunan pada timestep 1 biasanya bernilai 1e-6 atau lebih kecil — secara berkesan sifar — yang bermaksud beberapa token pertama dalam jujukan hampir tidak mempengaruhi parameter model. Model tidak dapat mempelajari bahawa subjek pada permulaan ayat yang panjang menentukan kata kerja pada penghujungnya.
import torch
import torch.nn as nn
rnn = nn.RNN(4, 8, batch_first=True)
X = torch.randn(1, 30, 4, requires_grad=True)
output, h_n = rnn(X)
loss = output[:, -1, :].sum() # loss at last timestep
loss.backward()
# Gradient with respect to early inputs
if X.grad is not None:
per_step_grads = X.grad.abs().mean(dim=-1)
print('Gradient norms per timestep (first 5 vs last 5):')
print(per_step_grads[0, :5].tolist()) # early: tiny
print(per_step_grads[0, -5:].tolist()) # late: largerKecerunan yang Meletup: Ekstrem yang Satu Lagi
Kecerunan yang meletup berlaku apabila jejari spektrum W_hh melebihi 1 — norma kecerunan meningkat secara eksponen mengikut panjang jujukan. Gejalanya ialah nilai kehilangan NaN atau parameter yang dikemas kini menjadi infiniti. Berbeza daripada kecerunan yang lenyap (yang menyebabkan kegagalan pembelajaran secara senyap), kecerunan yang meletup menyebabkan latihan terhenti dengan jelas. Pembetulan piawai ialah pemotongan kecerunan: skalakan semula vektor kecerunan supaya norma L2 maksimumnya ialah 1.0 sebelum langkah pengoptimum. Ini menghalang kemas kini yang membawa bencana tanpa menghapuskan isyarat kecerunan.
import torch
import torch.nn as nn
import torch.optim as optim
rnn = nn.RNN(4, 8, batch_first=True)
optimizer = optim.SGD(rnn.parameters(), lr=0.1)
X = torch.randn(2, 50, 4) # 50-step sequence
output, _ = rnn(X)
loss = output.sum()
loss.backward()
# Check gradient norm before clipping
total_norm = 0
for p in rnn.parameters():
if p.grad is not None:
total_norm += p.grad.data.norm(2) ** 2
total_norm = total_norm ** 0.5
print(f'Gradient norm before clip: {total_norm:.2f}')
# Clip to max_norm=1.0
nn.utils.clip_grad_norm_(rnn.parameters(), max_norm=1.0)
optimizer.step()Memvisualisasikan Norma Kecerunan Merentas Lapisan
Teknik penyahpepijatan yang praktikal ialah merekodkan norma kecerunan bagi semua parameter selepas setiap laluan backward dan memplotkannya sepanjang latihan. Bagi RNN asas, matriks pemberat berulang W_hh biasanya menunjukkan kecerunan yang jauh lebih kecil berbanding pemberat input W_xh, mengesahkan bahawa maklumat jarak jauh tidak sampai kepada parameter terdahulu. Visualisasi ini sering menunjukkan bahawa hanya beberapa timestep terakhir menyumbang secara bermakna kepada pembelajaran, lalu mendorong peralihan kepada seni bina berg get.
import torch
import torch.nn as nn
rnn = nn.RNN(4, 8, batch_first=True, num_layers=1)
X = torch.randn(1, 20, 4)
out, _ = rnn(X)
out.sum().backward()
print('Gradient norms per parameter:')
for name, p in rnn.named_parameters():
if p.grad is not None:
norm = p.grad.norm().item()
print(f' {name}: {norm:.6f}')
# weight_ih_l0 (input weights): larger
# weight_hh_l0 (recurrent weights): often much smallerSebab tanh Memburukkan Kelenyapan
Fungsi pengaktifan tanh dihadkan antara -1 dan 1 dengan terbitan 1 - tanh^2(x). Apabila input besar (tepu), terbitan menghampiri 0 — lalu memotong kecerunan sehingga hampir sifar pada langkah tersebut. Pendaraban banyak terbitan yang hampir sifar melalui BPTT memburukkan lagi masalah kelenyapan. ReLU mempunyai terbitan 1 bagi input positif (tanpa ketepuan), yang membantu aliran kecerunan dalam rangkaian suapan hadapan, tetapi dalam RNN, pendaraban berulang W_hh masih mendominasi dan boleh menyebabkan kecerunan meletup dengan ReLU.
import torch
# Tanh derivative: 1 - tanh(x)^2
x = torch.linspace(-4, 4, 9)
tanh_x = torch.tanh(x)
tanh_deriv = 1 - tanh_x ** 2
print('x: ', x.tolist())
print('tanh(x): ', [f'{v:.2f}' for v in tanh_x.tolist()])
print('tanh_deriv:', [f'{v:.2f}' for v in tanh_deriv.tolist()])
# At x=+/-3: deriv ~0.01 -- 100x smaller than at x=0
# Multiplied over 20 steps: 0.01^20 = 10^-40!BPTT Terpenggal: Penyelesaian Praktikal
BPTT terpenggal mengehadkan penyebaran kecerunan kepada tetingkap tetap sebanyak K timestep, bukannya keseluruhan panjang jujukan. Kecerunan disebarkan ke belakang sebanyak K langkah, kemudian keadaan tersembunyi dipisahkan daripada graf pengiraan (dan menjadi pemalar). Ini menghalang letupan memori dan kecerunan bagi jujukan yang sangat panjang (audio, korpus teks), tetapi menyebabkan kebergantungan yang merentasi lebih daripada K langkah tidak dapat dipelajari. K=20-50 ialah nilai lazim untuk pemodelan bahasa dengan RNN asas.
import torch
import torch.nn as nn
rnn = nn.RNN(4, 8, batch_first=True)
batch_size = 4
h = torch.zeros(1, batch_size, 8) # initial hidden state
# Process a 200-step sequence in chunks of 20
full_sequence = torch.randn(batch_size, 200, 4)
for chunk_start in range(0, 200, 20):
chunk = full_sequence[:, chunk_start:chunk_start+20, :]
out, h = rnn(chunk, h.detach()) # detach: stop grad here
loss = out.sum()
loss.backward()
print(f'Chunk {chunk_start}-{chunk_start+20}: done')Cabaran Kebergantungan Jarak Jauh
Pertimbangkan ayat: 'Trofi yang dimenangi oleh lelaki itu adalah besar.' Kata kerja 'adalah' mesti sepadan dengan 'trofi', bukan dengan 'lelaki'. Ini memerlukan maklumat tentang 'trofi' dibawa merentasi 5 perkataan sehingga ke tempat 'adalah' muncul. RNN asas yang dilatih melalui BPTT pada asasnya tidak dapat melakukan perkara ini dengan boleh dipercayai bagi jurang yang lebih panjang daripada 5–10 token. Inilah batasan teras yang mendorong pembangunan LSTM (1997) dan kemudiannya Transformer (2017), yang kedua-duanya mempunyai mekanisme khusus untuk mengekalkan maklumat jarak jauh.
# Classic long-range dependency examples:
examples = [
'The trophy ... man ... was [big/big] -- which subject?',
'The cat ... [sat/sat] -- past vs present?',
'The key [was/were] -- singular subject far away'
]
for ex in examples:
print('Example:', ex)
# Vanilla RNN performance on long-range deps:
print('\nVanishing gradient effect on learning:')
for gap in [1, 5, 10, 20, 50]:
ability = 'easy' if gap < 5 else ('hard' if gap < 20 else 'nearly impossible')
print(f' {gap}-step gap: {ability} for vanilla RNN')Teknik Pengasalan Pemberat untuk RNN
Beberapa teknik pengasalan meningkatkan latihan RNN asas pada jujukan yang sederhana panjang. Mengasalkan W_hh sebagai matriks ortogon (jejari spektrum tepat 1) menghalang kelenyapan atau letupan pada peringkat awal. Menambahkan sambungan pintasan daripada input terus ke output memintas beberapa pendaraban matriks. Pengasalan matriks identiti bagi W_hh dengan pengaktifan ReLU (IRNN) terbukti menyamai LSTM dalam sesetengah tugasan, menunjukkan bahawa pengasalan sahaja boleh menangani sebahagian masalah kecerunan yang lenyap.
import torch
import torch.nn as nn
rnn = nn.RNN(4, 8, batch_first=True)
# Orthogonal init for hidden-to-hidden weights
nn.init.orthogonal_(rnn.weight_hh_l0)
# Identity init (IRNN) for W_hh
nn.init.eye_(rnn.weight_hh_l0) # identity matrix
print('Spectral radius after orthogonal init:')
eigvals = torch.linalg.eigvals(rnn.weight_hh_l0)
print(eigvals.abs().max().item()) # should be ~1.0Sebab LSTM Dicipta
Masalah kecerunan yang lenyap dalam RNN didokumentasikan oleh Hochreiter pada tahun 1991. Penyelesaiannya, rangkaian Long Short-Term Memory (LSTM) yang diperkenalkan pada tahun 1997, menggantikan satu keadaan tersembunyi dengan keadaan sel yang dilindungi oleh get. Keadaan sel mengalir merentasi masa dengan hanya pengubahsuaian tambah (bukan darab), lalu mewujudkan lebuh raya kecerunan yang membolehkan kecerunan mengalir ke belakang tanpa had tanpa lenyap. Inovasi seni bina tunggal ini membolehkan latihan praktikal bagi jujukan dengan kebergantungan 100+ timestep.
# The core difference between RNN and LSTM gradient flow:
# Vanilla RNN: h_t = tanh(W_hh * h_{t-1} + W_xh * x_t)
# Gradient must pass through tanh and W_hh MULTIPLICATIVELY
# -> vanishes after ~10 steps
# LSTM: c_t = f_t * c_{t-1} + i_t * g_t
# Cell state c_t is updated ADDITIVELY
# Forget gate f_t can be near 1 (keep everything)
# -> gradient flows back cleanly
print('LSTM key insight: additive cell state update')
print('Gradient highway: constant error carousel')
print('Forget gate f_t controls information retention')Membandingkan Kestabilan Latihan RNN dan LSTM
Perbezaan kestabilan latihan antara RNN asas dan LSTM menjadi ketara bagi jujukan yang lebih panjang daripada 20–30 timestep. Dalam tugasan salin klasik (menghasilkan semula jujukan input selepas kelewatan yang panjang), RNN asas gagal sepenuhnya bagi kelewatan melebihi 10 langkah, manakala LSTM berjaya bagi kelewatan 100+ langkah. Penanda aras praktikal ini menunjukkan secara nyata bahawa masalah kecerunan yang lenyap mengehadkan RNN asas secara asasnya, dan penyelesaian seni bina LSTM diperlukan untuk pemodelan jujukan sebenar.
import torch
import torch.nn as nn
# Compare RNN vs LSTM on a 30-step sequence
models = {
'RNN': nn.RNN(4, 16, batch_first=True),
'LSTM': nn.LSTM(4, 16, batch_first=True)
}
X = torch.randn(8, 30, 4) # 30-step sequence
for name, model in models.items():
out, _ = model(X)
loss = out.sum()
loss.backward()
# Check gradient of first input vs last input
total_grad_norm = sum(
p.grad.norm().item() for p in model.parameters()
if p.grad is not None
)
print(f'{name} total grad norm: {total_grad_norm:.4f}')Semakan Pantas
Uji pemahaman anda tentang konsep Pembelajaran Mesin dengan Python daripada pelajaran ini.
Imbas Kembali Pelajaran
Dalam pelajaran ini, anda telah mempelajari bahawa: kecerunan yang lenyap berlaku apabila pendaraban berulang dengan W_hh (dengan jejari spektrum < 1) mendorong kecerunan menjadi sifar secara eksponen sepanjang jujukan yang panjang, kecerunan yang meletup berlaku apabila jejari spektrum > 1 dan ditangani dengan pemotongan kecerunan, dan LSTM dicipta khusus untuk menyelesaikan masalah kecerunan yang lenyap melalui kemas kini keadaan sel secara tambah yang menyediakan lebuh raya kecerunan. Seterusnya, kita akan meneliti seni bina sel LSTM dengan terperinci.
Pelajari Python dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 30
- Pelajaran
- 120
Soalan Lazim
Adakah pelajaran “Masalah Kecerunan Lenyap dalam Langkah Masa Mendalam” percuma?
Ya — teks penuh “Masalah Kecerunan Lenyap dalam Langkah Masa Mendalam” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Machine Learning Academy, tingkat taraf kepada CoddyKit PRO. Kursus Machine Learning Academy merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Masalah Kecerunan Lenyap dalam Langkah Masa Mendalam”?
Pelajar akan memerhatikan kecerunan yang meletup dan lenyap dalam RNN mendalam melalui perekodan norma kecerunan, serta memahami sebab jujukan panjang menjadikan latihan tidak stabil. Anda berlatih Machine Learning Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Machine Learning Academy?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Machine Learning Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 2 daripada 4.
Berapa lamakah pelajaran “Masalah Kecerunan Lenyap dalam Langkah Masa Mendalam” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Machine Learning Academy ini?
Ya. Setiap pelajaran Machine Learning Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- RNN Asas: Keadaan Tersembunyi dan Pengembangan Jujukan
- Masalah Kecerunan Lenyap dalam Langkah Masa Mendalam
- Sel LSTM: Get Input, Lupa dan Output
- Jujukan-ke-Satu: Analisis Sentimen dengan LSTM