#rnn-lstm — التعلّم العميق
RNN وLSTM: تذكُّر تسلسل.
ما ستُجرّبه
- مرحبًا بك في #rnn-lstm. على الشاشة، شبكة متكرّرة مبسوطة في الزمن: صندوق لكل رمز في التسلسل
10110، يُقرأ من اليسار إلى اليمين. أسفل كل صندوق، المدخلx_t؛ فوقه، الحالة المخفيّةh_t— ستّة أعمدة، الأزرق موجب والأحمر سالب — وسهم يُسلّمها إلى الخطوة التالية:h_t = tanh(W·x_t + U·h_{t−1} + b)، معh_0 = 0. إنها الخلية نفسها، الأوزان نفسها، منسوخة عند كل خطوة: ذاكرتها الوحيدة هيh. الخطوة الحالية مُبرَزة، والخطوات اللاحقة معتّمة؛/advanceيتقدّم خطوةً واحدة. سؤال هذه القناة: ماذا يبقى من الرمز الأوّل حين نبلغ النهاية؟ - أعطها تسلسل فخّ — واحد، ثم سبعة أصفار، ثم واحد آخر:
/sequence 100000001. المهمّة هي «الذاكرة»: عند النهاية، على الشبكة أن تتذكّر الرمز الأوّل. - اقفز مباشرةً إلى النهاية:
/step 9. قارنh_9بما يمكن أن يكون لو بدأ التسلسل بصفر — تلك هي «الفجوة إلى الرمز الأوّل» المذكورة في الرد. - لِمَ لا يُصلح التدريب هذا؟ لأن إشارة الخطأ تسلك المسار نفسه، معكوسًا. أظهر معيار التدرّج المنتشِر خلفيًا عبر الزمن، خطوةً خطوة:
/gradient. - غيِّر الخلية:
/cell lstm. LSTM يضيف ذاكرة ثانية، حالة الخليةc_t— الشريط الأخضر أعلى الشاشة — وثلاث بوّابات سيغمويدية، مرسومة كصمّامات داخل كل صندوق. - أبرِز بوّابة النسيان:
/gate forget. تقرّر، في كل خطوة، ما القدر الذي ينجو منc_{t−1}. - وماذا عن التدرّج؟ اطلب المنحنى مجدّدًا:
/gradient. - حان دورك:
/task counter(عُدَّ الآحاد) ثم/length 12لتسلسل عشوائي طويل،/gate inputأو/gate outputلقراءة الصمّامات الأخرى،/advanceلتتبُّعh_tوc_tخطوةً خطوة،/sequence abcabcلأحرف (متحرّك = 1، ساكن = 0)،/seed 42لأوزان مختلفة،/cell rnnو/gradientللمقارنة من جديد،/resetللبدء من جديد. التالي: قناة #autoencoder، حيث تتعلّم الشبكة ضغط مدخلاتها ثم إعادة بنائها.
أوامر القناة
/cell <rnn|lstm>— تغيير الخلية المتكرّرة (أوزان البذرة نفسها)؛ يُخفي منحنى التدرّج والبوّابة المُبرَزة./sequence <كلمة>— تسلسل جديد من 3 إلى 12 رمزًا: 0/1 أو أحرف (متحرّك = 1، ساكن = 0). العودة إلى الخطوة 1./length <3..12>— يسحب تسلسلًا عشوائيًا بهذا الطول (بالأبجدية نفسها للتسلسل الحالي). العودة إلى الخطوة 1./step <1..12>— الانتقال إلى الخطوة t (التسلسل مبسوط بالكامل: نختار ما ننظر إليه فقط)./advance— الانتقال إلى الخطوة التالية (t + 1)؛ بعد الأخيرة، يعود إلى الخطوة 1./gate <forget|input|output|none>— إبراز إحدى بوّابات LSTM في كل خلية (الصمّامات = سيغمويدات) وتفصيل قيمتها عند الخطوة الحالية./gradient— إظهار أو إخفاء منحنى (بمقياس لوغاريتمي) لمعيار التدرّج المنتشِر خلفيًا في الزمن، من الخطوة T إلى الخطوة 1./task <memory|counter|parity>— تغيير المهمّة اللعوب المقروءة من h_t: تذكّر الرمز الأوّل ، عدّ الآحاد، التماثل. تُعاد ملاءمة القراءة الخطّية./seed <1..9999>— إعادة سحب الأوزان الثابتة للخلية (W, U, الانحيازات) والتسلسلات الاختبارية من بذرة أخرى./reset— العودة إلى RNN بسيطة، التسلسل 10110، مهمّة الذاكرة، الخطوة 1، البذرة 7، بلا منحنى تدرّج.
المسرد
- الشبكة العصبية المتكرّرة (RNN)
- شبكة تقرأ تسلسلًا عنصرًا عنصرًا بإعادة استخدام الخلية نفسها (الأوزان نفسها) عند كل خطوة، وتُمرّر حالةً من خطوة إلى أخرى:
h_t = tanh(W·x_t + U·h_{t−1} + b). النصوص، الصوت، السلاسل الزمنية: كل ما له ترتيب. - الحالة المخفيّة (hidden state)
- الشعاع
h_tالذي تعيد الخلية حسابه عند كل خطوة: ذاكرتها العاملة، وكل ما «تعرفه» عن التسلسل المقروء حتى الآن. في RNN بسيطة، تُعاد كتابتها بالكامل عند كل خطوة، ومن ثَمّ ذاكرتها القصيرة. - البسط في الزمن (unrolling in time)
- تمثيل الشبكة المتكرّرة كسلسلة من نسخ الخلية، نسخة لكل خطوة زمنية، مربوطة بالحالة المخفيّة. هذا ما يعرضه المشهد: RNN من T خطوة هي شبكة عميقة من T طبقة تتقاسم أوزانها.
- الانتشار الخلفي عبر الزمن (BPTT)
- الانتشار الخلفي مطبَّقًا على الشبكة المبسوطة: يتدفّق تدرّج الخسارة من
h_Tإلىh_1بالضرب، عند كل خطوة، بالمصفوفة اليعقوبية∂h_{t+1}/∂h_t. تصحيحات كل خطوة تتراكم على الأوزان المشتركة نفسها. - تلاشي التدرّج (vanishing gradient)
- حين يكون معيار المصفوفات اليعقوبية المتتالية أقلّ من 1، يقترب حاصل ضربها من الصفر أُسّيًا: التدرّج الذي يبلغ الخطوات الأولى ضئيل ولا تستطيع الشبكة تعلّم التبعيات الطويلة. هذا هو المنحنى الذي ينهار لـ RNN.
- انفجار التدرّج (exploding gradient)
- المشكلة المتناظرة: مصفوفات يعقوبية معيارها > 1 تجعل التدرّج ينمو أُسّيًا على طول التسلسل، إلى تحديثات عبثية. العلاج الشائع: قصّ التدرّج (gradient clipping)، الذي يحدّ من معياره قبل التحديث.
- LSTM
- Long Short-Term Memory (Hochreiter & Schmidhuber, 1997): خلية متكرّرة مُزوَّدة بحالة خلية جَمْعية
c_tوثلاث بوّابات مُتعلَّمة (النسيان، المدخل، المخرج). يتدفّق التدرّج على طولcدون المرور بأي tanh، مما يُصلح التلاشي عمليًا. - بوّابات النسيان والمدخل والمخرج
- ثلاثة أشعّة سيغمويدية، بين 0 (مغلقة) و1 (مفتوحة)، محسوبة من
x_tوh_{t−1}. f تقرّر ما القدر الذي ينجو منc_{t−1}، i ما القدر الذي يُضاف من المرشّحg_t، o ما القدر المكشوف منtanh(c_t)فيh_t. هذه هي الصمّامات في المشهد. - حالة الخلية (cell state)
- الشريط
c_t = f_t ⊙ c_{t−1} + i_t ⊙ g_tفي LSTM: ذاكرة طويلة تُحدَّث بـ الجمع، لا بإعادة الكتابة. مع بوّابة نسيان قريبة من 1، تبقى المعلومة المكتوبة عند الخطوة 1 حاضرةً عند الخطوة 12 — ويقوم التدرّج بالرحلة العكسية بالجودة نفسها. - GRU
- Gated Recurrent Unit (Cho et al., 2014): صيغة أخفّ من LSTM ببوّابتين (التحديث والتصفير)، بلا حالة خلية منفصلة. مُعاملات أقلّ، نتائج قابلة للمقارنة غالبًا؛ كلاهما استُبدلا إلى حدٍّ كبير بنماذج transformers للنصوص، لكنهما لا يزالان مستعملَين في السلاسل الزمنية والأجهزة المدمَجة.
قنوات أخرى في التعلّم العميق
- #optimizers — SGD وMomentum وAdam: سباق إلى الأدنى.
- #batch-normalization — تطبيع الحُزَم: إبقاء التفعيلات في المدى الصحيح.
- #rnn-lstm — RNN وLSTM: تذكُّر تسلسل.
- #autoencoder — المرمّز التلقائي: اضغط ثم أعِد البناء.
- #transfer-learning — التعلّم بالنقل: انطلق من شبكة مدرَّبة سلفًا.
- #gan — GAN: مزوِّر ضدّ مفتِّش