RNN وLSTM وGRU — نمذجة التسلسلات
“تعليم الشبكات التذكر — من النسيان الكارثي إلى الذاكرة البوابية الانتقائية”
الشبكات المتكررة للتسلسلات: RNN الأساسية وLSTM (بوابات النسيان والإدخال والإخراج وحالة الخلية) وGRU (بوابات مُبسَّطة) وBi-LSTM للسياق ثنائي الاتجاه.
المتطلبات الأساسية
المفاهيم المغطاة
∑الصيغ الرئيسية
الحالة الخفية RNN
يجمع الذاكرة السابقة مع المدخل الحالي — يعاني من النسيان الكارثي في التسلسلات الطويلة
حالة خلية LSTM
حالة الخلية مُحدَّثة بوابة النسيان ووابة الإدخال — 'الطريق السريع للتدرج'
خرج LSTM
تتحكم وابة الخرج في ما يُكشَف من حالة الخلية — اختيار انتقائي للذاكرة
تحديث GRU
بوابة تحديث وحيدة تُقحِّم الحالة الخفية القديمة والجديدة — أبسط من LSTM، غالباً بنفس الجودة
▶محاكاة تفاعلية
⬡هندسة النموذج
لماذا التسلسلات صعبة
اللغة، السلاسل الزمنية، الصوت، الحمض النووي — كل هذه لها تبعيات زمنية. 'قال إنه سيأتي' — 'هو' و'سيأتي' مفصولان بـ5 كلمات لكنهما مرتبطان ارتباطاً وثيقاً. الشبكة الأمامية تعالج كل خطوة زمنية بشكل مستقل. تتشارك RNNs المعاملات عبر الزمن وتحافظ على حالة خفية تلخص المدخلات السابقة — مما يتيح سياقاً غير محدود.
اختفاء التدرج عبر الزمن
في BPTT (الانتشار الخلفي عبر الزمن)، تُضرب التدرجات بمصفوفة الأوزان W في كل خطوة زمنية. إذا كانت أكبر قيمة ذاتية لـW < 1، تتناقص التدرجات أسياً. لتسلسل من 100 خطوة، يُضرب التدرج من الخطوة 1 بـW¹⁰⁰. تحل LSTMs هذا بالحالة الخلوية — 'طريق سريع' يحمل المعلومات بتحديثات جمعية فقط (لا ضربية).
تتدفق تدرجات LSTM عبر c_t = f_t ⊙ c_{t-1} + i_t ⊙ c̃_t. بوابة النسيان f_t تمنع تدرجات c من الاختفاء — إنها جمعيات مشروطة، لا ضروب مصفوفية.
معادلات بوابات LSTM
أربعة حسابات للبوابات تحدد ما يجب نسيانه وتعلمه وإنتاجه في كل خطوة. جميع البوابات تستخدم sigmoid (مخرج 0-1 = 'كم تسمح بالمرور'). حالة الخلية المرشحة تستخدم tanh (مخرج -1 إلى 1 = المحتوى الفعلي).
LSTM لتوقع السلاسل الزمنية
import torch import torch.nn as nn from torch.utils.data import TensorDataset, DataLoader # ── Sample sequential dataloader ─────────────────────────────────────── # Shape: (n_samples, seq_len, features) → predict next value X_seq = torch.randn(500, 20, 10) # 500 samples, seq_len=20, 10 features y_seq = torch.randn(500) # 500 scalar targets dataloader = DataLoader(TensorDataset(X_seq, y_seq), batch_size=32, shuffle=True) class LSTMForecaster(nn.Module): def __init__(self, input_dim, hidden_dim, num_layers, output_dim, dropout=0.2): super().__init__() self.lstm = nn.LSTM( input_dim, hidden_dim, num_layers, batch_first=True, dropout=dropout, bidirectional=False ) self.fc = nn.Linear(hidden_dim, output_dim) self.dropout = nn.Dropout(dropout) def forward(self, x, h0=None, c0=None): # x: (batch, seq_len, features) out, (hn, cn) = self.lstm(x, (h0, c0) if h0 is not None else None) # Use last timestep's output return self.fc(self.dropout(out[:, -1, :])) # Training with teacher forcing + scheduled sampling model = LSTMForecaster(input_dim=10, hidden_dim=128, num_layers=2, output_dim=1) optimizer = torch.optim.Adam(model.parameters(), lr=1e-3) # Gradient clipping is ESSENTIAL for RNN training for x, y in dataloader: pred = model(x) loss = nn.MSELoss()(pred.squeeze(), y) optimizer.zero_grad() loss.backward() nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) optimizer.step()
?اختبار المعرفة
يتم حفظ التقدم في متصفحك — لا حاجة لحساب.
Need a Data Scientist or AI Engineer?
I build custom ML models, RAG chatbots, data pipelines, and production APIs — from analysis to deployment.