You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/ar/8-Reinforcement/2-Gym
leestott e4050807fb
🌐 Update translations via Co-op Translator
3 weeks ago
..
solution 🌐 Update translations via Co-op Translator 3 weeks ago
README.md 🌐 Update translations via Co-op Translator 3 weeks ago
assignment.md 🌐 Update translations via Co-op Translator 3 weeks ago
notebook.ipynb 🌐 Update translations via Co-op Translator 3 weeks ago

README.md

التزلج على CartPole

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

اختبار ما قبل المحاضرة

المقدمة

في هذا الدرس، سنطبق نفس مبادئ التعلم باستخدام Q-Learning على مشكلة ذات حالة مستمرة، أي حالة يتم تحديدها بواسطة رقم حقيقي أو أكثر. سنتعامل مع المشكلة التالية:

المشكلة: إذا أراد بيتر الهروب من الذئب، يجب أن يكون قادرًا على التحرك بسرعة أكبر. سنرى كيف يمكن لبيتر تعلم التزلج، وبالتحديد الحفاظ على التوازن، باستخدام Q-Learning.

الهروب الكبير!

بيتر وأصدقاؤه يبدعون للهروب من الذئب! الصورة بواسطة Jen Looper

سنستخدم نسخة مبسطة من التوازن تُعرف بمشكلة CartPole. في عالم CartPole، لدينا شريط أفقي يمكنه التحرك إلى اليسار أو اليمين، والهدف هو الحفاظ على توازن عمود رأسي فوق الشريط.

المتطلبات الأساسية

في هذا الدرس، سنستخدم مكتبة تُسمى OpenAI Gym لمحاكاة بيئات مختلفة. يمكنك تشغيل كود هذا الدرس محليًا (مثلًا من Visual Studio Code)، وفي هذه الحالة ستفتح المحاكاة في نافذة جديدة. عند تشغيل الكود عبر الإنترنت، قد تحتاج إلى إجراء بعض التعديلات على الكود كما هو موضح هنا.

OpenAI Gym

في الدرس السابق، كانت قواعد اللعبة والحالة تُحدد بواسطة الفئة Board التي قمنا بتعريفها بأنفسنا. هنا سنستخدم بيئة محاكاة خاصة، والتي ستقوم بمحاكاة الفيزياء وراء العمود المتوازن. واحدة من أشهر بيئات المحاكاة لتدريب خوارزميات التعلم المعزز تُسمى Gym، والتي يتم صيانتها بواسطة OpenAI. باستخدام هذه البيئة يمكننا إنشاء بيئات مختلفة من محاكاة CartPole إلى ألعاب Atari.

ملاحظة: يمكنك رؤية البيئات الأخرى المتاحة من OpenAI Gym هنا.

أولاً، دعنا نقوم بتثبيت Gym واستيراد المكتبات المطلوبة (كتلة الكود 1):

import sys
!{sys.executable} -m pip install gym 

import gym
import matplotlib.pyplot as plt
import numpy as np
import random

تمرين - تهيئة بيئة CartPole

للعمل مع مشكلة توازن CartPole، نحتاج إلى تهيئة البيئة المناسبة. كل بيئة مرتبطة بـ:

  • مساحة الملاحظة التي تُحدد هيكل المعلومات التي نتلقاها من البيئة. بالنسبة لمشكلة CartPole، نتلقى موقع العمود، السرعة وبعض القيم الأخرى.

  • مساحة الحركة التي تُحدد الإجراءات الممكنة. في حالتنا، مساحة الحركة منفصلة، وتتكون من إجراءين - يسار و يمين. (كتلة الكود 2)

  1. للتهيئة، اكتب الكود التالي:

    env = gym.make("CartPole-v1")
    print(env.action_space)
    print(env.observation_space)
    print(env.action_space.sample())
    

لرؤية كيفية عمل البيئة، دعنا نقوم بتشغيل محاكاة قصيرة لمدة 100 خطوة. في كل خطوة، نقدم أحد الإجراءات التي يجب اتخاذها - في هذه المحاكاة نختار إجراءً عشوائيًا من action_space.

  1. قم بتشغيل الكود أدناه وشاهد النتائج.

    تذكر أنه يُفضل تشغيل هذا الكود على تثبيت Python محلي! (كتلة الكود 3)

    env.reset()
    
    for i in range(100):
       env.render()
       env.step(env.action_space.sample())
    env.close()
    

    يجب أن ترى شيئًا مشابهًا لهذه الصورة:

    CartPole غير متوازن

  2. أثناء المحاكاة، نحتاج إلى الحصول على الملاحظات لتحديد كيفية التصرف. في الواقع، تُرجع وظيفة الخطوة الملاحظات الحالية، دالة المكافأة، وعلامة الانتهاء التي تشير إلى ما إذا كان من المنطقي متابعة المحاكاة أم لا: (كتلة الكود 4)

    env.reset()
    
    done = False
    while not done:
       env.render()
       obs, rew, done, info = env.step(env.action_space.sample())
       print(f"{obs} -> {rew}")
    env.close()
    

    ستنتهي برؤية شيء مثل هذا في إخراج الدفتر:

    [ 0.03403272 -0.24301182  0.02669811  0.2895829 ] -> 1.0
    [ 0.02917248 -0.04828055  0.03248977  0.00543839] -> 1.0
    [ 0.02820687  0.14636075  0.03259854 -0.27681916] -> 1.0
    [ 0.03113408  0.34100283  0.02706215 -0.55904489] -> 1.0
    [ 0.03795414  0.53573468  0.01588125 -0.84308041] -> 1.0
    ...
    [ 0.17299878  0.15868546 -0.20754175 -0.55975453] -> 1.0
    [ 0.17617249  0.35602306 -0.21873684 -0.90998894] -> 1.0
    

    يحتوي متجه الملاحظة الذي يتم إرجاعه في كل خطوة من خطوات المحاكاة على القيم التالية:

    • موقع العربة
    • سرعة العربة
    • زاوية العمود
    • معدل دوران العمود
  3. احصل على الحد الأدنى والحد الأقصى لتلك الأرقام: (كتلة الكود 5)

    print(env.observation_space.low)
    print(env.observation_space.high)
    

    قد تلاحظ أيضًا أن قيمة المكافأة في كل خطوة من خطوات المحاكاة دائمًا 1. هذا لأن هدفنا هو البقاء لأطول فترة ممكنة، أي الحفاظ على العمود في وضع عمودي بشكل معقول لأطول فترة ممكنة.

    في الواقع، تُعتبر محاكاة CartPole محلولة إذا تمكنا من الحصول على متوسط مكافأة قدره 195 على مدى 100 تجربة متتالية.

تقسيم الحالة إلى قيم منفصلة

في Q-Learning، نحتاج إلى بناء جدول Q الذي يُحدد ما يجب فعله في كل حالة. لكي نتمكن من القيام بذلك، يجب أن تكون الحالة منفصلة، وبشكل أكثر دقة، يجب أن تحتوي على عدد محدود من القيم المنفصلة. لذلك، نحتاج بطريقة ما إلى تقسيم ملاحظاتنا، وربطها بمجموعة محدودة من الحالات.

هناك عدة طرق يمكننا القيام بذلك:

  • التقسيم إلى مجموعات. إذا كنا نعرف نطاق قيمة معينة، يمكننا تقسيم هذا النطاق إلى عدد من المجموعات، ثم استبدال القيمة برقم المجموعة التي تنتمي إليها. يمكن القيام بذلك باستخدام طريقة digitize في numpy. في هذه الحالة، سنعرف حجم الحالة بدقة، لأنه سيعتمد على عدد المجموعات التي نختارها للتقسيم.

يمكننا استخدام الاستيفاء الخطي لجلب القيم إلى نطاق محدود (على سبيل المثال، من -20 إلى 20)، ثم تحويل الأرقام إلى أعداد صحيحة عن طريق تقريبها. هذا يمنحنا تحكمًا أقل في حجم الحالة، خاصة إذا لم نكن نعرف النطاقات الدقيقة للقيم المدخلة. على سبيل المثال، في حالتنا، 2 من أصل 4 قيم ليس لها حدود عليا/سفلى على قيمها، مما قد يؤدي إلى عدد لا نهائي من الحالات.

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

  1. هنا وظيفة ستأخذ الملاحظة من نموذجنا وتنتج مجموعة من 4 قيم صحيحة: (كتلة الكود 6)

    def discretize(x):
        return tuple((x/np.array([0.25, 0.25, 0.01, 0.1])).astype(np.int))
    
  2. دعنا نستكشف أيضًا طريقة أخرى للتقسيم باستخدام المجموعات: (كتلة الكود 7)

    def create_bins(i,num):
        return np.arange(num+1)*(i[1]-i[0])/num+i[0]
    
    print("Sample bins for interval (-5,5) with 10 bins\n",create_bins((-5,5),10))
    
    ints = [(-5,5),(-2,2),(-0.5,0.5),(-2,2)] # intervals of values for each parameter
    nbins = [20,20,10,10] # number of bins for each parameter
    bins = [create_bins(ints[i],nbins[i]) for i in range(4)]
    
    def discretize_bins(x):
        return tuple(np.digitize(x[i],bins[i]) for i in range(4))
    
  3. دعنا الآن نقوم بتشغيل محاكاة قصيرة ونلاحظ تلك القيم المنفصلة للبيئة. لا تتردد في تجربة كل من discretize و discretize_bins ومعرفة ما إذا كان هناك فرق.

    تُرجع discretize_bins رقم المجموعة، وهو يبدأ من 0. وبالتالي بالنسبة لقيم المتغير المدخل حول 0، تُرجع الرقم من منتصف النطاق (10). في discretize، لم نهتم بنطاق قيم الإخراج، مما يسمح لها بأن تكون سلبية، وبالتالي فإن القيم 0 تتوافق مع 0. (كتلة الكود 8)

    env.reset()
    
    done = False
    while not done:
       #env.render()
       obs, rew, done, info = env.step(env.action_space.sample())
       #print(discretize_bins(obs))
       print(discretize(obs))
    env.close()
    

    قم بإلغاء تعليق السطر الذي يبدأ بـ env.render إذا كنت تريد رؤية كيفية تنفيذ البيئة. خلاف ذلك، يمكنك تنفيذها في الخلفية، وهو أسرع. سنستخدم هذا التنفيذ "غير المرئي" أثناء عملية Q-Learning.

هيكل جدول Q

في درسنا السابق، كانت الحالة عبارة عن زوج بسيط من الأرقام من 0 إلى 8، وبالتالي كان من المناسب تمثيل جدول Q بمصفوفة numpy ذات شكل 8x8x2. إذا استخدمنا تقسيم المجموعات، فإن حجم متجه الحالة لدينا معروف أيضًا، لذلك يمكننا استخدام نفس النهج وتمثيل الحالة بمصفوفة ذات شكل 20x20x10x10x2 (هنا 2 هي بُعد مساحة الحركة، والأبعاد الأولى تتوافق مع عدد المجموعات التي اخترنا استخدامها لكل من المعلمات في مساحة الملاحظة).

ومع ذلك، في بعض الأحيان لا تكون أبعاد مساحة الملاحظة معروفة بدقة. في حالة وظيفة discretize، قد لا نكون متأكدين أبدًا من أن حالتنا تبقى ضمن حدود معينة، لأن بعض القيم الأصلية ليست محدودة. لذلك، سنستخدم نهجًا مختلفًا قليلاً ونمثل جدول Q بواسطة قاموس.

  1. استخدم الزوج (state,action) كمفتاح للقام

المهمة 1: جرّب تعديل قيم المعاملات الفائقة (hyperparameters) وانظر إذا كان بإمكانك تحقيق مكافأة تراكمية أعلى. هل تحصل على أكثر من 195؟ المهمة 2: لحل المشكلة بشكل رسمي، تحتاج إلى تحقيق متوسط مكافأة قدره 195 عبر 100 تشغيل متتالي. قم بقياس ذلك أثناء التدريب وتأكد من أنك قد حللت المشكلة بشكل رسمي!

رؤية النتيجة عمليًا

سيكون من المثير للاهتمام رؤية كيف يتصرف النموذج المدرب بالفعل. دعنا نقوم بتشغيل المحاكاة ونتبع نفس استراتيجية اختيار الإجراءات كما في التدريب، حيث يتم أخذ العينات وفقًا لتوزيع الاحتمالات في Q-Table: (كتلة الكود 13)

obs = env.reset()
done = False
while not done:
   s = discretize(obs)
   env.render()
   v = probs(np.array(qvalues(s)))
   a = random.choices(actions,weights=v)[0]
   obs,_,done,_ = env.step(a)
env.close()

يجب أن ترى شيئًا مثل هذا:

عربة متوازنة


🚀التحدي

المهمة 3: هنا، كنا نستخدم النسخة النهائية من Q-Table، والتي قد لا تكون الأفضل. تذكر أننا قمنا بتخزين أفضل نسخة أداءً من Q-Table في المتغير Qbest! جرب نفس المثال باستخدام Q-Table الأفضل أداءً عن طريق نسخ Qbest إلى Q وشاهد ما إذا كنت تلاحظ الفرق.

المهمة 4: هنا لم نكن نختار أفضل إجراء في كل خطوة، بل كنا نأخذ العينات وفقًا لتوزيع الاحتمالات المقابل. هل سيكون من المنطقي دائمًا اختيار أفضل إجراء، الذي يحتوي على أعلى قيمة في Q-Table؟ يمكن القيام بذلك باستخدام وظيفة np.argmax لمعرفة رقم الإجراء الذي يتوافق مع أعلى قيمة في Q-Table. قم بتنفيذ هذه الاستراتيجية وشاهد ما إذا كانت تحسن التوازن.

اختبار ما بعد المحاضرة

الواجب

تدريب سيارة الجبل

الخاتمة

لقد تعلمنا الآن كيفية تدريب الوكلاء لتحقيق نتائج جيدة فقط من خلال توفير دالة مكافأة تحدد الحالة المرغوبة للعبة، ومنحهم فرصة لاستكشاف مساحة البحث بذكاء. لقد طبقنا بنجاح خوارزمية Q-Learning في حالات البيئات المنفصلة والمستمرة، ولكن مع إجراءات منفصلة.

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


إخلاء المسؤولية:
تمت ترجمة هذا المستند باستخدام خدمة الترجمة الآلية Co-op Translator. بينما نسعى لتحقيق الدقة، يرجى العلم أن الترجمات الآلية قد تحتوي على أخطاء أو معلومات غير دقيقة. يجب اعتبار المستند الأصلي بلغته الأصلية هو المصدر الموثوق. للحصول على معلومات حساسة أو هامة، يُوصى بالاستعانة بترجمة بشرية احترافية. نحن غير مسؤولين عن أي سوء فهم أو تفسيرات خاطئة تنشأ عن استخدام هذه الترجمة.