مقدمة Recurrent Neural Networks بالعربى

202

حينما نقرأ مقالاً فلا نفكر في كل كلمة وحدها، بل نفهم تتابع الكلمات لنكون معنى الجمل والفقرات. لا ننسى معنى ما قرأناه عند بداية كل الجملة. فالأفكار التي نستوعبها تبقى في ذاكرتنا لتمكننا من فهم معاني أكبر.

ال Neural Networks التقليدية ليس لديها هذه القدرة مما يجعلها محدودة في كثير من التطبيقات. مثلاً، لو أردنا تصنيف نوع الحدث في كل مشهد من فيديو، كيف نمكن ال neural network التقليدية من تعلم وحل هذه المشكلة؟ ستحتاج الاستفادة من المشاهد السابقة لتصنيف التالية.

تقدم ال Recurrent Neural Networks حلاً لهذه المشكلة. تستخدم دوائر loops في داخلها، مما يمكنها من استخدام المعلومات لاحقاً.

في الرسم السابق، نرى جزء من ال neural network في المستطيل A الذي يأخذ المدخل xt ويخرج قيمة ht. وجود الدائرة تمكننا من نقل المعلومات من خطوة للتالية. لنفهم أكثر ما تفعله يمكن أن نفكر فيها أنها neural network تقليدية ولكن ال weights عند كل خطوة هي نفس ال weights عند باقي الخطوات.

هذه الصورة تبين طبيعة ال recurrent neural networks التي تتعامل بسهولة مع المسلسلات والقوائم. في السنوات الأخيرة أثبت ال RNN كفاءتها في التطبيقات التي تستخدم داتا في صورة تسلسل مثل الترجمة الآلية، وتوصيف الصور بالكلام، والتلخيص الآلي، و speech recognition.

تعريف ال Recurrent Neural Networks

هناك خاصية في ال neural network التقليدية وال convolutional تجعلها محدودة في كثير من التطبيقات: تتعامل مع مدخلات من حجم محدد ثابت وتصدر مخرجات من حجم محدد ثابت! وكذلك تقوم بمعالجة المدخلات في خطوات ثابتة (كعدد الطبقات).

تكمن قوة ال RNN في أنها تتعامل من تسلسلات من المدخلات والمخرجات. الرسم التالي يوضح الحالات المختلفة لنوع المدخل والمخرج من حيث التسلسل.

كل مستطيل يمثل متجه vector والأسهم تمثل دوال (مثل ضرب المصفوفات). المدخلات لونها أحمر، والمخرجات أزرق، والأخضر يمثل حالة ال RNN الداخلية. من اليسار:

  1. أبسط الأنواع، حجم المدخل والمخرج ثابتين (مثل تصنيف الصور).
  2. المخرج متسلسل (مثل توصيف الصور بالكلام)
  3. المدخل متسلسل (مثل تصنيف جمل من الكلام)
  4. المدخل والمخرج متسلسلان (مثل الترجمة الآلية)

نلاحظ أنه لا توجد قيود على طول التسلسلات لأننا يمكن إدخال أي عدد من المتجهات على ال RNN.

حسابات ال RNN

ندخل على ال RNN متجه x ونخرج متجه y. ولكن نلاحظ أن y يتأثر بكل المدخلات التي سبقت.

تحفظ ال RNN بمتجه h يمثل الحالة الداخلية التي تحتوي معلومات عن المدخلات السابقة.

يمكننا تخيل أن ال RNN لها دالة step تتقدم خطوة في تسلسل المدخلات أو المخرجات.

مثال كود يطبق هذه الدالة:

y1 = rnn1.step(x)
y = rnn2.step(y1)
class RNN:
  # ...
  def step(self, x):
     # update the hidden state
     self.h = np.tanh(np.dot(self.W_hh, self.h) + np.dot(self.W_xh, x))
     # compute the output vector
     y = np.dot(self.W_hy, self.h)
     
     return y

نرى أن هناك ثلاث معاملات لل RNN:

  • W_hh: تحول من الحالة الداخلية h السابقة للتالية
  • W_xh: تحول من المدخل x للحالة الداخلية h
  • W_hy: تحول من الحالة الداخلية h للمخرج y

تبدأ الحالة الداخلية h بقيم أصفار، ونستخدم دالة tanh كدالة غير خطية لتمكننا من تعلم علاقات أكثر تعقيداً.

حيث t تعبر عن الخطوة في التسلسل، الخطوة الحالية تعتمد على الحالة من الخطوة السابقة.

إذا تصورنا ال RNN في صورة مفكوكة، فكأنها عند كل خطوة هي neural network تأخذ المدخل من السابقة وهكذا.

هناك اختلافات في تمثيل الحالة الداخلية ودالة ال non-linearity، عادة نستخدم LSTM أو GRU في كثير من التطبيقات لأنها تعطي نتائج أفضل وتحل بعض مشاكل ال RNN التقليدية.

تطبيق: Character-Level Language Model

سنقوم بتعلم RNN كنموذج لغوي language model. فكرة النموذج اللغوي أن نتنبأ باحتمالية الكلمة التالية في الجملة. في هذه الحالة ال RNN ستتمكن من إعطاءنا احتمالية الحرف القادم بعد تسلسل من الكلام في الجملة. هذا سيمكننا أيضاً من توليد الكلام حرف بحرف.

على سبيل المثال، إذا اعتبرنا أن لدينا 4 حروف فقط: “م ر ح ب”، ونريد تعليم RNN على كلمة “مرحب”. نرى أنه في هذه الكلمة ثلاث أمثلة للتعلم:

  1. يجب أن تكون احتمالية “ر” بعد “م” عالية
  2. “ح” يجب أن تكون عالية الاحتمال في سياق “مر”
  3. كذلك تكون احتمالية “ب” عالية في سياق “مرح”

أي أن الكلمات الممكنة الأخرى مثل “حربم” أو “مرحر” أو “ربحب” تكون أقل احتمالاً عند النموذج اللغوي.

يمكن تمثيل المدخلات في صورة متجهات one-hot vectors، أي أنها لها قيمة 1 عند الحرف المذكور وقيمة صفر لباقي الحروف. يوضح الرسم مثل هذا التمثيل:

في أول خطوة نغذي ال RNN بحرف “م”، ثم تعطي ثقة لكون الحرف التالي كلا من “م ر ح ب” قيم “1.0 2.2 -3.0 4.1”. في حالتنا الحرف “الصحيح” هو “ر”، إذا نريد أن نزيد الثقة فيه عند ال RNN ونقلل الثقة في باقي الحروف. وهكذا في باقي الخطوات “م” -> “ر”، “ر” -> “ح”، “ح” -> “ب”.

نستخدم طرق تعليم ال neural network مثل ال back propagation حتى نعدل ال RNN كي تعطي القيم التي نريد تعلمها.

لتحويل قيم الثقة إلى قيم احتماليات نستخدم دالة ال softmax.

نعرض كود يقوم بتعليم RNN لتتنبأ بالحرف التالي، نستخدم PyTorch ونتعلم على داتا من ويكيبيديا العربية.

نقوم بتحميل مقالات موسوعة ويكيبيديا للغة العربية من هنا:

https://dumps.wikimedia.org/arwiki/latest/arwiki-latest-pages-articles.xml.bz2

أولاً كود يقوم باستخراج النص الكلامي فقط والتخلص من ال xml markdown والروابط والأرقام وغيرها.

import xml.etree.ElementTree as etree
import re

def clean(s):
    s = re.sub(r'[^ابةتثجحخدذرزسشصضطظعغفقكلمنهوىي \n\.\,]+', ' ', s)
    s = re.sub(r'\s+', ' ', s)
    return s

fout = open('extracted_arwiki.txt', 'w', encoding='utf-8')
i=0
for event, elem in etree.iterparse('arwiki-latest-pages-articles.xml'):
    i+=1
    if (elem.tag[-4:] == 'text' or elem.tag[:-5] == 'title') and elem.text is not None:
        s = clean(elem.text)
        fout.write(s)
    if i % 10000 == 0:
        print(i)
fout.close()

ثم نستخدم كود من Karpathy:

https://gist.github.com/karpathy/d4dee566867f8291f086

نرى أمثلة للنصوص المولدة بعد التعلم:

----
iter 202400, loss: 53.686588, 62.647867
----
تلية وكالج المورية ال لا د لغيال للطبق انحظكا يهوم بن سلا يم المدينة وانت والتخدانات ققد سلاهولة هعوب منص الدبنرلا صدعة
م ن مدراجط من بال لنعاس النهامسطي لكن الفيينه الجي ال سفسية ال نابق الم
----
iter 202500, loss: 53.123674, 45.644316
----
غول و نوب منتحاع ونوبي السبحي كان عهد سن واللال من الدوب وصرف وفل حن نزا تة انشير فقلى عن الخبد الحلجه العلمانل من في حاشك وزون . عبدة للمانهة بنا لب ان قمام ضايس عمران محمك ضفة عكة تقدد البرح يساجه
----
iter 202600, loss: 53.611565, 53.234811
----
غرية المنحب ننجيل ة من المحرعة و ه زهم السقب ومين من شتشوب سفنهع مقتاسين . زنتانة بولى وعدمة بال نقية قطون خلال بحظهوته حن ن ودال المسيخبحوته ممرى شعديثة مين طبر ن ينبا قت بوصحد الكنوحة الحولتطو
----

نرى أن بعض الكلمات متناسقة وأحياناً عدة كلمات متتالية، ولكن الجملة تفتقد تركيبا لغويا سليما، وأحيانا نرى كلمات مصطنعة.

يمكن ضبط إعدادات التعلم والتوليد من أجل تحسين كفاءة النصوص المولدة. غالبا ما نستخدم نماذج وطرق أكثر تعقيداً في التطبيقات مثل الترجمة وال chatbots، ولكن هنا عرضنا فكرة بسيطة لنتعلم كيف نستخدم هذه النماذج ونفهم أساسيات عملها.

المصادر:

https://medium.com/explore-artificial-intelligence/an-introduction-to-recurrent-neural-networks-72c97bf0912

http://karpathy.github.io/2015/05/21/rnn-effectiveness

تعليقات