من الـ architecture للتطبيق
الدرسين اللي فاتوا بنوا الآلية: الـ recurrent connections اللي بتشيل الـ memory على الـ time steps، وآليات الـ gates اللي بتحمي العلاقات البعيدة من الـ vanishing gradients. والدرس ده بيشغّل الآلية دي. الـ recurrent networks (الشبكات المتكررة) والـ LSTM والـ GRU مش مجرد تراكيب نظرية، دول كانوا المحرك ورا عشر سنين من الإنجازات في اللغة والـ time series والكلام واتخاذ القرارات المتتالية. وإنك تفهم إزاي توصّل الـ architecture بكل مسألة هي المهارة الأساسية لتطبيق models الـ sequences عمليًا.
هنفحص خمس مجالات تطبيقية ملموسة: الـ language modeling، والـ text classification، وترجمة الـ sequence-to-sequence، والـ time series forecasting، والـ speech recognition. كل مجال بيوضّح طريقة مختلفة لصياغة مسألة متسلسلة، بأشكال inputs وoutputs وloss functions وإجراءات inference مختلفة. وهنختم بنظرة على آلية الـ attention (الانتباه)، الابتكار الأساسي اللي وصّل في الآخر للـ transformers وعدّى الـ recurrence الخالص في مهام كتير.
الـ language modeling: التنبؤ بالكلمة الجاية
الـ language model (نموذج اللغة) بيدّي احتمال لكل sequence من الـ tokens. والصياغة المعتادة بتستخدم الـ chain rule للاحتمال: P(w1, w2, …, wT) = ∏t=1T P(wt | w1, …, wt−1). والتدريب بيتلخّص في مهمة التنبؤ بالـ token الجاي: تدّيله الـ sequence لحد دلوقتي، يتنبأ بالـ token اللي بعده. والـ recurrent network مناسبة طبيعيًا لده لأن الـ hidden state ht−1 بتضغط كل الـ tokens اللي فاتت في vector حجمه ثابت، وlayer الـ softmax بتحوّل التمثيل ده لتوزيع احتمالي على الـ vocabulary.
وفي كل time step، الـ cross-entropy loss بتقيس الفرق بين التوزيع اللي الـ model اتنبأ بيه والـ token الجاي الحقيقي (وهو vector one-hot، صفر في كل حتة ما عدا مكان الـ token الصح). وبعدين الـ loss بتتحسب كمتوسط على كل الأماكن وكل الـ sequences في الـ mini-batch. أما وقت الـ inference فالـ tokens بتتسحب من التوزيع المتوقع بشكل autoregressive (انحداري ذاتي): الـ token اللي اتسحب بيبقى الـ input اللي بعده، والعملية بتتكرّر لحد ما يتولّد token نهاية الـ sequence أو نوصل لأقصى طول.
الـ language models على مستوى الحرف بتقسم النص لحروف مفردة، فالـ model يقدر يولّد أي نص ويتعامل مع كلمات مشافهاش في التدريب. أما اللي على مستوى الكلمة فبتقسم لكلمات أو subwords (بالـ byte-pair encoding مثلًا)، فبتطلّع نص متماسك أكتر في المعنى بس بـ vocabulary أكبر بكتير. والـ RNNs على مستوى الحرف كانت من أوائل الإثباتات المقنعة إن models الـ sequences العصبية تقدر تولّد نص متماسك وcode وبيانات منظّمة.
الـ perplexity (PPL) هي المقياس المعتاد للـ language models: PPL = exp(الـ loss). وperplexity قدها k معناها إن الـ model، في المتوسط، محتار كأنه لازم يختار بالتساوي بين k احتمال متكافئين في كل خطوة. model عشوائي على vocabulary من 50,000 كلمة الـ perplexity بتاعته 50,000. والـ RNN المتدرّبة كويس بتوصل لـ perplexity 60–100 على معيار Penn Treebank. والـ transformers الحديثة بتوصل لأقل من 20 على نفس المعيار.
الـ text classification: تشفير الـ sequence في label
الـ text classification (تصنيف النصوص) بيوصّل sequence طولها متغيّر بـ label فئوي ثابت: إيجابي أو سلبي في تحليل المشاعر، spam ولا لأ، موضوع مقالة. والصياغة الطبيعية للـ RNN إنك تشغّل الـ sequence على الـ RNN وتستخدم آخر hidden state hT كتمثيل ملخّص للـ sequence كلها. وclassification head fully connected فوق hT بيحوّل الـ vector اللي حجمه ثابت ده لاحتمالات الفئات عن طريق softmax.
المفتاح إن hT هو ملخّص بيتعلّم للـ input sequence كلها، مضغوط عن طريق الانتقالات التكرارية وآليات الـ gates. وفي الـ LSTM، الـ cell state cT كتير بتشيل إشارة مكمّلة، فبتتوصّل مع hT قبل الـ classification head. أما في الـ models اللي في الاتجاهين فآخر hidden stateين بيتوصّلوا [&overrightarrow;hT ; &overleftarrow;h1]، فبيمسكوا السياق من قدام ومن ورا مع بعض.
وهنا مسألة عملية مهمة: إزاي تتعامل مع sequences أطوالها مختلفة جوه نفس الـ mini-batch؟ الحل هو الـ padding (التبطين) — كل الـ sequences بتتمد لنفس الطول بـ token padding خاص PAD — مع آلية masking (إخفاء) بتستخدم mask عشان تضمن إن الـ loss بتتحسب على الـ tokens الحقيقية بس مش على الـ padding. والـ hidden state الأخيرة بتتاخد من آخر مكان حقيقي في كل sequence، مش من آخر الـ padding. والـ frameworks الحديثة بتوفّر تمثيلات "packed sequences" بتتجنّب الحساب على الـ padding من الأساس.
الـ sequence-to-sequence: الترجمة وأكتر
مهام كتير محتاجة تولّد output sequence طولها متغيّر من input sequence طولها متغيّر: الترجمة الآلية (إنجليزي ← فرنساوي)، والتلخيص (مستند طويل ← ملخّص قصير)، والحوار (كلام المستخدم ← رد النظام). ومينفعش تحل المهام دي بـ RNN واحدة، لأن طول الـ output مش بيتحدّد بطول الـ input.
وarchitecture الـ encoder–decoder (المشفر–فك الشفرة) (Sutskever وزمايله، 2014) بتعالج ده بإنها تقسم الـ model لـ recurrent networkين. الـ encoder بيقرا الـ input sequence كلها ويضغطها في context vector (متجه سياق) c حجمه ثابت، وعادةً بيبقى آخر hidden state بتاعته. وبعدين الـ decoder بيبدأ بـ c ويولّد الـ output sequence token واحد كل مرة بشكل autoregressive، فبيدخّل كل token بيولّده كـ input للخطوة اللي بعدها، ويكمّل لحد ما يولّد token نهاية الـ sequence الخاص.
بس الـ architecture دي فيها عنق زجاجة واضح: الـ context vector الواحد. الـ input sequence كلها — جملة من عشرين أو خمسين كلمة — لازم تتضغط في vector واحد حجمه ثابت. ومع الـ sequences الطويلة، آخر hidden state للـ encoder ببساطة مبتقدرش تحتفظ بكل اللي يهم. والعنق ده بالظبط هو اللي زق لـ آلية الـ attention، اللي بتخلّي الـ decoder يبص على كل hidden states الـ encoder بدل ما يعتمد على ملخّص واحد.
الـ greedy decoding بيختار دايمًا الـ token الأكتر احتمال في كل خطوة، بس كتير بيطلّع sequences أقل من الأمثل، لأن اختيار greedy بدري ممكن يقفل الطريق على نهايات أحسن. أما الـ beam search (البحث الحزمي) فبيحتفظ بأحسن k sequence مرشّحة (ودي الـ beam) في كل خطوة، فبيوسّع كل المرشّحات وبعدين يفضّل الـ sequences الجزئية الأعلى احتمال وعددها k. وعرض beam بين 4 و10 بيحسّن جودة الترجمة بشكل ملموس قصاد الـ greedy decoding، بتمن إنك تضرب حساب الـ inference في k. والـ length normalization (قسمة لوغاريتم الاحتمال على طول الـ sequence) بيمنع الـ beam search إنه ينحاز للـ outputs الأقصر.
الـ time series forecasting
الـ recurrent networks متقصرتش على اللغة، دي اتطبّقت على الـ time series الرقمية: التنبؤ بقيم جاية لإشارة من تاريخها. سعر سهم بعد يوم، والطلب على الكهربا في الساعة الجاية، والعمر الباقي المفيد لماكينة صناعية — كلها مهام forecasting بتوصّل sequence من المشاهدات اللي فاتت بقيمة جاية واحدة أو أكتر.
في الـ one-step-ahead forecasting، الـ model بياخد x1, …, xT كـ input ويتنبأ بـ xT+1. والـ output قيمة مستمرة، فالـ loss هي الـ MSE أو الـ MAE مش الـ cross-entropy. والـ architecture تقريبًا هي نفسها بتاعة RNN classifier، بس الـ output layer بتبقى linear regression بدل softmax. أما في الـ multi-step forecasting، فيا إما الـ decoder يولّد القيم الجاية بشكل autoregressive، يا إما output layer واحدة تتنبأ بكل الـ H خطوات الجاية مرة واحدة (ودي الاستراتيجية المباشرة).
وأكبر تحدّي في الـ time series هو الـ non-stationarity (عدم الاستقرارية): الخصائص الإحصائية للسلسلة — المتوسط والـ variance والموسمية — بتتغيّر مع الزمن. والـ preprocessing المعتاد فيه الـ differencing (طرح القيمة اللي فاتت عشان تشيل الاتجاه العام)، والـ normalization (متوسط صفر وvariance واحد)، والـ seasonal decomposition. والـ LSTMs أثبتت فعالية خاصة في الـ multivariate time series، اللي لازم تمسك فيها الارتباطات بين إشارات كتير مع بعض — زي الحرارة والرطوبة وسرعة الهوا مع بعض عشان تتنبأ بالطلب على الطاقة.
الـ speech recognition
الـ automatic speech recognition (التعرف التلقائي على الكلام) (ASR) بيوصّل sequence من frames الـ features الصوتية — عادةً vectors log-mel filterbank طولها 25 مللي ثانية، بتتطلّع كل 10 مللي ثانية — بـ sequence من الحروف أو الكلمات. وطولين الـ input والـ output مختلفين: جملة مدتها تلات ثواني ممكن تطلّع 300 frame صوتي و40 حرف بس. والأسوأ إن الـ alignment بين الـ frames وtokens الـ output مش معروف وقت التدريب.
والـ connectionist temporal classification (CTC) loss، اللي قدّمها Graves وزمايله سنة 2006، حلّت مشكلة الـ alignment من غير ما تحتاج transcripts متعلّم عليها بالإيد على مستوى الـ frame. الـ CTC بتدخّل blank token خاص، وبعدين بتعمل marginalization على كل الـ alignments الصحيحة الممكنة بين الـ output sequence وframes الـ input، فبتحسب الاحتمال الكلي للـ output sequence الصح على كل توزيعات الـ frames على الـ tokens. وبكده التدريب من النصوص المكتوبة بس بيبقى ممكن، والـ model بيتعلّم الـ alignment ضمنيًا.
الـ deep bidirectional LSTMs المتدرّبة بالـ CTC وصلت مع سنة 2015 لـ word error rates (WER) قريبة من مستوى البني آدم على معايير الكلام النضيف. والـ architecture المعتادة كانت بترص من خمس لسبع layers bidirectional LSTM فوق الـ features الصوتية، مع batch normalization وdropout للـ regularization. والـ speech recognition كان من أوائل التطبيقات الحقيقية اللي أثبتت إن الـ deep recurrent networks، لو اتدرّبت على آلاف الساعات من الصوت، تقدر تجاري دقة البني آدم في المهام الضيقة وتعدّيها.
الـ attention: نظرة أولى
عنق زجاجة الـ encoder–decoder، والتسلسلية اللي في طبيعة الـ recurrent networks، كانوا بيشاوروا على نفس الحد: المعلومة المهمة ممكن تبقى بعيدة جدًا في سلسلة الـ hidden states لدرجة إنها متترجعش بثقة. وآلية الـ attention، اللي قدّمها Bahdanau وزمايله سنة 2015 للـ neural machine translation، عالجت الحد ده على طول.
بدل ما تضغط الـ input في context vector واحد، آلية الـ attention بتخلّي الـ decoder يحسب مجموع موزون على كل hidden states الـ encoder في كل خطوة decoding. والـ weights (درجات الـ attention) بتتحسب بشبكة توافق صغيرة بتتعلّم بتقارن حالة الـ decoder الحالية st بكل حالة encoder hj. والـ context vector اللي بيطلع ct هو في جوهره بحث ناعم وينفع يتفاضل في memory الـ encoder، مركّز على أجزاء الـ input الأكتر صلة بالـ token اللي بيتولّد دلوقتي.
الـ attention حسّن جودة الترجمة جامد في الجمل الطويلة، اللي كان الـ context vector الثابت فيها مش كفاية. ولو رسمت matrix الـ attention weights هتشوف patterns alignment مفهومة للعين: في الترجمة من الإنجليزي للفرنساوي، الـ model غالبًا بينتبه للكلمة المصدر الصح وهو بيولّد كل كلمة هدف، حتى لو ترتيب الكلمات مختلف بين اللغتين. وكمان الـ attention خلّى الـ model يتعامل مع جمل بأي طول من غير ما الأداء يقع، لأن الـ decoder دايمًا عنده وصول مباشر لكل hidden states الـ encoder مهما كان طول الـ sequence.
وبعدين فكرة "الاسترجاع الموزون" دي اتعمّمت أبعد من كده: طب لو الـ attention مكانش إضافة على الـ recurrent networks، لكن كان هو الآلية الأساسية؟ architecture الـ transformer (المحوّل) (الوحدة 9) بتشيل الـ recurrence خالص وبتحط مكانها الـ self-attention (الانتباه الذاتي) — كل مكان بينتبه لكل الأماكن التانية في نفس الـ sequence في نفس الوقت. والنتيجة model بيقبل التوازي أثناء التدريب (لأنه مفضلش اعتماد تسلسلي بين الأماكن)، وبيكبر لـ sequences أطول بكتير، وبقى الأساس لتقريبًا كل large language model حديث.
الـ transformers عدّت الـ recurrent networks في أغلب المهام اللي الـ sequence فيها موجودة كلها (الترجمة، والـ NLP، وتحليل الـ time series على شبابيك ثابتة). بس الـ recurrent networks لسه ليها مزايا عملية في الـ inference الـ streaming: معالجة خطوة واحدة كل مرة بحساب O(1) لكل خطوة وmemory محدودة. sensor IoT بيصنّف الأحداث في الـ real-time، أو نظام توليد كلام لازم يولّد عيّنات صوت من غير ما يقف، أو controller روبوت بيعالج تدفّقات الـ sensors — كلهم بيستفيدوا من الكفاءة التسلسلية للـ recurrent networks. ولما البيانات تبقى قليلة أو الحساب متقيّد، عدد الـ parameters الأصغر في الـ GRU والـ LSTM بيبقى ميزة تانية قصاد الـ transformers الكبيرة.
- الـ language models بتتدرّب بالتنبؤ بالـ token الجاي (الـ cross-entropy loss) وبتتقيّم بالـ perplexity. والـ hidden state بتاعة الـ recurrent network بتضغط الـ prefix في vector حجمه ثابت، بيطلّع توزيع على الـ tokens عن طريق softmax. والسحب الـ autoregressive بيولّد sequences جديدة.
- الـ text classification بيستخدم آخر hidden state كتمثيل للـ sequence، بيدخل على classification head. والـ sequences اللي أطوالها متغيّرة بتتعالج بالـ padding والـ masking. والـ loss هي cross-entropy على labels الفئات.
- models الـ sequence-to-sequence بتستخدم encoder يضغط الـ input في context vector وdecoder يولّد الـ outputs بشكل autoregressive. وعنق الزجاجة اللي فيه vector واحد بيحدّ الأداء على الـ sequences الطويلة. والـ beam search بيحسّن جودة الـ inference.
- الـ time series forecasting بيعامل الإشارات الرقمية كـ sequences، باستخدام MSE/MAE loss وoutput layers خطية. والـ LSTMs بتمسك العلاقات الزمنية اللي على كذا خطوة والارتباطات بين المتغيرات بفعالية، والـ preprocessing (الـ differencing والـ normalization) بيتولّى الـ non-stationarity.
- الـ speech recognition بيوصّل sequences الـ frames الصوتية بحروف باستخدام الـ CTC loss، اللي بتعمل marginalization على كل الـ alignments الصحيحة. والـ deep BiLSTMs وصلت لـ word error rates قريبة من مستوى البني آدم مع سنة 2015.
- آلية الـ attention بتخلّي الـ decoder يحسب مجموع موزون على كل حالات الـ encoder في كل خطوة، فبتعدّي عنق الزجاجة. وتعميم الـ attention للـ self-attention — اللي كل مكان فيه بينتبه لكل الأماكن التانية — وصّل على طول لـ architecture الـ transformer اللي في الوحدة 9.