سنتعرف في هذا المقال على إحدى طرق التعلم المعزز (RL) المسماة الانتروبيا المتقاطعة.على الرغم من حقيقة أنها أقل شهرة بكثير من الأدوات الأخرى الموجودة في صندوق أدوات ممارس التعلم المعزز ، مثل شبكة كيو العميقة (deep Q-network) بإختصار (DQN) أو منتقد الممثل المميز (advantage actor-critic) ، إلا أن طريقة الانتروبيا المتقاطعة (cross-entropy) لها نقاط قوتها الخاصة.
- أولاً ، طريقة الانتروبيا المتقاطعة بسيطة حقًا ، مما يجعلها طريقة سهلة الفهم. على سبيل المثال ،يتم تنفيذها في PyTorch في أقل من 100 سطر.
- ثانيًا ، لها تقارب جيد. في البيئات البسيطة التي لا تتطلب سياسات معقدة ومتعددة الخطوات ليتم تعلمها واكتشافها ، والتي تحتوي على حلقات قصيرة مع مكافآت متكررة ، عادةً ما تعمل طريقة الانتروبيا بشكل جيد للغاية.
بالطبع ، لا تندرج الكثير من المشاكل العملية في هذه الفئة ، لكنها في بعض الأحيان تقع. في مثل هذه الحالات ، يمكن أن تكون طريقة الانتروبيا (بمفردها أو كجزء من نظام أكبر) هي الطريقة المثالية.
في هذا المقال سوف نغطي:
- الجانب العملي لطريقة الانتروبيا
- كيف تعمل طريقة الانتروبيا المتقاطعة في بيئتين في gym وهما (CartPole و FrozenLake)
تصنيف طرق التعلم المعزز
تندرج طريقة الانتروبيا المتقاطعة في تصنيف فئة الطرق عديمة النماذج (model-free) و المبنية على السياسة (policy-based). هذه المفاهيم جديدة ، لذلك دعونا نقضي بعض الوقت في استكشافها. يمكن تصنيف جميع الطرق في التعلم المعزز إلى جوانب مختلفة:
- عديمة النموذج (Model-free) أو مبنية على نموذج (model-based)
- مبنية على القيمة (Value-based) أو مبنية على السياسة (policy-based)
- مع سياسة (On-policy) أو بدون سياسة (off-policy)
هناك طرق أخرى يمكنك من خلالها تصنيف طرق التعلم المعزز لكننا مهتمون حاليًا بالطرق الثلاثة السابقة. دعنا نحددها ، حيث يمكن أن تؤثر تفاصيل مشكلتك على قرارك بشأن طريقة معينة.
المصطلح “عديمة النموذج” يعني أن الطريقة لا تبني نموذجًا للبيئة أو مكافأة ؛ بل تربط الملاحظات مباشرة بالأفعال (أو القيم المتعلقة بالإجراءات). بمعنى آخر ، يأخذ الوكيل الملاحظات الحالية ويقوم ببعض الحسابات عليها ، والنتيجة هي الإجراء الذي يجب أن يتخذه.
في المقابل ، تحاول الأساليب القائمة على النموذج التنبؤ بما ستكون عليه الملاحظة و / أو المكافأة التالية. بناءً على هذا التوقع ، يحاول الوكيل اختيار أفضل إجراء يمكن اتخاذه ، وغالبًا ما يقوم بهذه التنبؤات عدة مرات للبحث عن المزيد والمزيد من الخطوات في المستقبل.
كلا الفئتين من الطريقتين لهما جوانب قوة وضعف ، ولكن عادة ما يتم استخدام الأساليب القائمة على النموذج الخالص في البيئات الحتمية ، مثل ألعاب الطاولة ذات القواعد الصارمة.
من ناحية أخرى ، عادةً ما يكون تدريب الطرق عديمة النماذج أسهل لأنه من الصعب بناء نماذج جيدة من البيئات المعقدة ذات الملاحظات الغنية. حتى الماضي القريب كانت فئة الطرق عديمة النماذج هي الأكثر نشاطاً و بحثاً ، لكن بدأ الباحثون مؤخرًا فقط في مزج الفوائد من كلا العالمين (على سبيل المثال ، ارجع إلى أبحاث DeepMind حول الخيال في الوكلاء).
من خلال النظر من زاوية أخرى ، فإن الطرق المبنية على السياسة تقارب بشكل مباشر مع سياسة الوكيل ، أي الإجراءات التي يجب على الوكيل تنفيذها في كل خطوة. عادة ما يتم تمثيل السياسة من خلال توزيع احتمالية على الإجراءات المتاحة.
في المقابل ، يمكن أن تكون الطريقة المبنية على القيمة. في هذه الحالة ، بدلاً من احتمال الإجراءات ، يحسب الوكيل قيمة كل إجراء ممكن ويختار الإجراء بأفضل قيمة. تتمتع كلتا هاتين العائلتين من الطرق بشعبية متساوية .
التصنيف الثالث المهم للطرق هو مع سياسه مقابل بدون سياسه .بدون سياسه هي قدرة الطريقة على التعلم من البيانات التاريخية (التي تم الحصول عليها بواسطة إصدار سابق من الوكيل ، تم تسجيله بواسطة المستخدم ، أو شاهده نفس الوكيل منذ عدة حلقات).
لذا ، فإن طريقة الانتروبيا المتقاطعة لدينا عديمة النماذج (model-free,) ، و مبنية على السياسة (policy-based)، و مع سياسة (on-policy) ، مما يعني ما يلي:
- لا تبني أي نموذج للبيئة ؛ إنها تقول فقط للوكيل ما يجب فعله في كل خطوة
- إنها تعطي تقريب لسياسة الوكيل
- تتطلب بيانات جديدة يتم الحصول عليها من البيئة
طريقة الانتروبيا في الممارسة
ينقسم وصف طريقة الانتروبيا المتقاطعة إلى جزأين غير متكافئين: عملي ونظري. الجزء العملي بديهي بطبيعته ، في حين أن التفسير النظري لسبب نجاح طريقة الانتروبيا ، وما يحدث ، هو أكثر تعقيدًا.
قد تتذكر أن الشيء المركزي والأصعب في التعلم المعزز هو الوكيل ، وهو يحاول تجميع أكبر قدر ممكن من المكافآت من خلال التواصل مع البيئة.
من الناحية العملية ، نتبع نهجًا شائعًا لتعلم الألة ونستبدل جميع مضاعفات الوكيل بنوع من الوظائف غير الخطية القابلة للتدريب ، والتي تربط مدخلات الوكيل (الملاحظات من البيئة) إلى بعض المخرجات. قد تعتمد تفاصيل المخرجات التي تنتجها هذه الوظيفة على طريقة معينة أو مجموعة من الأساليب ، كما هو موضح في القسم السابق (مثل الأساليب القائمة على القيمة مقابل الأساليب القائمة على السياسة).
نظرًا لأن طريقة الانتروبيا لدينا تعتمد على السياسة ، فإن وظيفتنا الغير الخطية (الشبكة العصبية (neural network)) تنتج السياسة ، والتي تحدد الإجراء الذي يجب على الوكيل اتخاذه عند كل ملاحظة .
من الناحية العملية ، عادةً ما يتم تمثيل السياسة على أنها توزيع احتمالي على الإجراءات ، مما يجعلها مشابهة جدًا لمشكلة التصنيف ، حيث تكون كمية التصانيف مساوية لمقدار الإجراءات التي يمكننا تنفيذها.
يجعل هذا التجريد وكيلنا بسيطًا للغاية: فهو يحتاج إلى تمرير ملاحظة من البيئة إلى الشبكة العصبية، والحصول على توزيع احتمالي للإجراءات ، و من ثم أخذ عينات عشوائي باستخدام توزيع الاحتمالات للحصول على إجراء لتنفيذه.
تضيف هذه العينة العشوائية مقدار من العشوائية إلى وكيلنا ، وهو أمر جيد ، كما في بداية التدريب ، عندما تكون أوزاننا عشوائية ، يتصرف الوكيل بشكل عشوائي. بعد أن يحصل الوكيل على إجراء لإصداره ، فإنه يقوم بالإجراء في البيئة ويحصل على الملاحظة التالية والمكافأة على الإجراء الأخير. ثم تستمر الحلقة.
خلال عمر الوكيل ، يتم تقديم تجربته على شكل حلقات. كل حلقة هي سلسلة من الملاحظات التي حصل عليها الوكيل من البيئة ، والإجراءات التي أصدرها ، والمكافآت على هذه الإجراءات. تخيل أن وكيلنا قد لعب العديد من هذه الحلقات. لكل حلقة ، يمكننا حساب المكافأة الإجمالية التي حصل عليها الوكيل. يمكن خصمها أو عدم خصمها ؛ للتبسيط ، دعنا نفترض عامل خصم y=1، مما يعني مجموع جميع المكافآت المحلية لكل حلقة. تُظهر هذه المكافأة الإجمالية مدى جودة هذه الحلقة للوكيل.
دعنا نوضح هذا بمخطط يحتوي على أربع حلقات (لاحظ أن الحلقات المختلفة لها قيم مختلفة لـ oi و ai و ri):
الشكل 4.2: عينة من الحلقات مع ملاحظاتها وأفعالها ومكافآتها
تمثل كل خلية خطوة الوكيل في الحلقة. نظرًا للعشوائية في البيئة والطريقة التي يختار بها الوكيل الإجراءات التي يجب اتخاذها ، ستكون بعض الحلقات أفضل من غيرها. إن جوهر طريقة الانتروبيا المتقاطعة هو التخلص من الحلقات السيئة والتدريب على الحلقات الأفضل.
إذن ، خطوات الطريقة كالتالي:
- قم بتشغيل عدد N من الحلقات باستخدام النموذج والبيئة الحالية.
- احسب إجمالي المكافأة لكل حلقة وحدد حد المكافأة. عادة ، نستخدم نسبة مئوية من جميع المكافآت ، مثل 50 أو 70.
- تخلص من كل الحلقات بمكافأة أقل من الحد.
- تدرب على حلقات “النخبة” المتبقية باستخدام الملاحظات كمدخلات والإجراءات المصدرة كالناتج المطلوب.
- كرر من الخطوة 1 حتى نشعر بالرضا عن النتيجة.
إذن ، هذا هو وصف طريقة الانتروبيا المتقاطعة. من خلال الإجراء السابق ،تتعلم الشبكة العصبية الخاص بنا كيفية تكرار الإجراءات ، مما يؤدي إلى مكافأة أكبر ، وهذا يؤدي باستمرار إلى تحريك الحدود إلى أعلى وأعلى. على الرغم من بساطة هذه الطريقة ، إلا أنها تعمل جيدًا في البيئات الأساسية ، ومن السهل تنفيذها ، كما أنها تتعامل بشكل جيد مع تغيرات معايير الضبط، مما يجعلها طريقة أساسية مثالية للمحاولة. دعنا الآن نطبقه على بيئة CartPole الخاصة بنا.
طريقة الانتروبيا المتقاطعة على بيئة CartPole
الكود الكامل موجود على Github ، ولكن ما يلي هو أهم الأجزاء. جوهر نموذجنا هو شبكة عصبية لها طبقة واحدة مخفية ، مع وحدة خطية مصححة (ReLU) و 128 عصبونه (وهو رقم إختياري). يتم أيضًا تعيين مدخلات الضبط (hyperparameters ) الأخرى بشكل عشوائي تقريبًا ولا يتم ضبطها ، لأن الطريقة قوية وتتقارب بسرعة كبيرة.
HIDDEN_SIZE = 128 BATCH_SIZE = 16 PERCENTILE = 70
نحدد الثوابت في الجزء العلوي من الملف وتشمل عدد العصبونات في الطبقة المخفية ، وعدد الحلقات التي نلعبها في كل تكرار (16) ، والنسبة المئوية لمجموع المكافآت للحلقات التي نستخدمها لترشيح حلقة “النخبة”.
class Net(nn.Module): def __init__(self, obs_size, hidden_size, n_actions): super(Net, self).__init__() self.net = nn.Sequential( nn.Linear(obs_size, hidden_size), nn.ReLU(), nn.Linear(hidden_size, n_actions) ) def forward(self, x): return self.net(x)
لا يوجد شيء مميز في الشبكة لدينا ؛ يأخذ ملاحظة واحدة من البيئة كمتجه إدخال ويخرج رقمًا لكل إجراء يمكننا تنفيذه. الناتج من الشبكة العصبية هو توزيع احتمالي على الإجراءات ، الطريقة الشائعة للإكمال هي إضافة طبقة softmax بعد الطبقة الأخيرة.
ومع ذلك ، في الشبكة السابقة ، لا نطبق softmax لزيادة الاستقرار العددي لعملية التدريب. بدلاً من حساب softmax (الذي يستخدم الأس) ثم حساب خسارة الانتروبيا المتقاطعة (التي تستخدم لوغاريتم الاحتمالات) .
يمكننا استخدام فئة PyTorch المسماة nn.CrossEntropyLoss . و التي تقوم بالجمع ما بين سوفت ماكس و الإنتروبيا المتقاطعة في تعبير رياضي أكثر إستقراراً .
يتطلب CrossEntropyLoss قيمً خام و غير مسوية (unnormalized ) من الشبكة العصبية (تسمى أيضًا logits). الجانب السلبي لهذا هو أننا نحتاج إلى أن تذكر أنه علينا تطبيق softmax في كل مرة نحتاج فيها للحصول على الاحتمالات من ناتج الشبكة العصبية الخاص بنا.
Episode = namedtuple('Episode', field_names=['reward', 'steps']) EpisodeStep = namedtuple( 'EpisodeStep',field_names=['observation', 'action'])
سنقوم هنا بتعريف فئتين مساعدين و هما namedtuple :
- EpisodeStep: سيتم استخدام هذا لتمثيل خطوة واحدة قام بها وكيلنا في الحلقة ، ويقوم بتخزين الملاحظة من البيئة والإجراء الذي أكمله الوكيل. سوف نستخدم خطوات الحلقة من حلقات “النخبة” كبيانات تدريبية.
- Episode : هذه حلقة واحدة مخزنة كمكافأة إجمالية غير مخصومة ومجموعة من EpisodeStep.
لنلقِ نظرة على وظيفة تنشئ دفعات من حلقات:
def iterate_batches(env, net, batch_size): batch = [] episode_reward = 0.0 episode_steps = [] obs = env.reset() sm = nn.Softmax(dim=1)
تقبل الوظيفة السابقة البيئة ( فئة Env من مكتبة الجيم) ، و الشبكة العصبية الخاص بنا ، وعدد الحلقات التي يجب أن تولدها في كل تكرار. سيتم استخدام متغير الدُفعة (batch ) لتجميع الدُفعة الخاصة بنا (وهي قائمة بمثيلات الحلقة). نعلن أيضًا عن عداد مكافأة للحلقة الحالية وقائمة خطواتها (و هي EpisodeStep). ثم نقوم بإعادة ضبط بيئتنا للحصول على الملاحظة الأولى وإنشاء طبقة softmax ، والتي سيتم استخدامها لتحويل ناتج الشبكة العصبية إلى توزيع احتمالي للإجراءات. وبهذا نكون قد إنتهينا من جميع التجهيزات ، لذلك نحن جاهزون لبدء حلقة البيئة.
while True: obs_v = torch.FloatTensor([obs]) act_probs_v = sm(net(obs_v)) act_probs = act_probs_v.data.numpy()[0]
في كل تكرار ، نقوم بتحويل ملاحظتنا الحالية إلى موتر PyTorch ونمررها إلى الشبكة العصبية للحصول على احتمالات الإجراء. هناك العديد من الأشياء التي يجب ملاحظتها هنا:
- تتوقع جميع مثيلات nn.Module في PyTorch حزم من عناصر البيانات وينطبق الشيء نفسه على الشبكة العصبية، لذلك نقوم بتحويل ملاحظتنا (وهي متجه من أربعة أرقام في CartPole) إلى موتر بحجم 1 × 4 (لتحقيق ذلك ، نقوم بتمرير الملاحظة في قائمة أحادية العنصر ).
- نظرًا لأننا لم نستخدم اللاخطية في ناتج الشبكة العصبية الخاص بنا ، فإنه ينتج نتائج الإجراءات الخام ، والتي نحتاج إلى تمريرها من خلال دالة softmax.
- تعيد كل من الشبكة العصبية وطبقة softmax الموترات التي تتعقب الإشتقاقات لذلك نحتاج إلى فك ضغطها عن طريق الولولج إلى حقل tensor.data ثم تحويل الموتر إلى مصفوفة NumPy. سيكون لهذه المصفوفة نفس الهيكل ثنائي الأبعاد كالمدخل ، مع بُعد الحزمة على المحور 0 ، لذلك نحتاج إلى الحصول على أول عنصر في الحزمة للحصول على متجه أحادي البعد لاحتمالات الإجراء.
action = np.random.choice(len(act_probs), p=act_probs) next_obs, reward, is_done, _ = env.step(action)
الآن بعد أن أصبح لدينا التوزيع الاحتمالي للإجراءات ، يمكننا استخدامه للحصول على الإجراء الفعلي للخطوة الحالية عن طريق أخذ عينات من هذا التوزيع باستخدام وظيفة نمباي المسماة random.choice (). بعد ذلك ، سننقل هذا الإجراء إلى البيئة للحصول على ملاحظتنا التالية ، ومكافأتنا ، والإشارة إلى انتهاء الحلقة.
episode_reward += reward step = EpisodeStep(observation=obs,action=action) episode_steps.append(step)
تتم إضافة المكافأة إلى إجمالي المكافأة للحلقة الحالية ، كما يتم تمديد قائمة خطوات الحلقة أيضًا بزوج (ملاحظة ، إجراء). لاحظ أننا نحفظ الملاحظة التي تم استخدامها لاختيار الإجراء ، ولكن ليس الملاحظة التي أرجعتها البيئة كنتيجة للإجراء. هذه هي التفاصيل الصغيرة ، ولكن المهمة ، التي تحتاج إلى وضعها في الاعتبار.
if is_done: e = Episode(reward=episode_reward,steps=episode_steps) batch.append(e) episode_reward = 0.0 episode_steps = [] next_obs = env.reset() if len(batch) == batch_size: yield batch batch = []
هذه هي الطريقة التي نتعامل بها مع الموقف عندما تنتهي الحلقة الحالية (في حالة CartPole ، تنتهي الحلقة عندما تسقط العصا على الرغم من جهودنا). نلحق الحلقة النهائية بالحزمة، ونحفظ المكافأة الإجمالية (حيث اكتملت الحلقة وقمنا بتجميع كل المكافآت) والخطوات التي اتخذناها. ثم نقوم بإعادة تعيين إجمالي تراكم المكافآت لدينا وتنظيف قائمة الخطوات. بعد ذلك ، نعيد ضبط بيئتنا لنبدأ من جديد.
في حالة وصول الحزمة إلى العدد الحلقات المطلوب ، نعيدها إلى المتصل للمعالجة باستخدام yield. وظيفتنا هي مولد ، لذلك في كل مرة يتم فيها إستخدام yield ، يتم نقل التحكم إلى حلقة التكرار الخارجية ثم يستمر بعد سطر yield . إذا لم تكن معتادًا على وظائف مولد Python ، فارجع إلى وثائق بايثون بخصوص المولد .بعد المعالجة ، سنقوم بتنظيف الحزمة.
obs = next_obs
الخطوة الأخيرة ، ولكنها مهمة جدًا ، في حلقتنا هي تعيين ملاحظة تم الحصول عليها من البيئة لمتغير الملاحظة الحالي. بعد ذلك ، يتكرر كل شيء بلا حدود – نقوم بتمرير الملاحظة إلى الشبكة العصبية ، ونعاين الإجراء المطلوب تنفيذه ، ونطلب من البيئة معالجة الإجراء ، ونتذكر نتيجة هذه المعالجة.
إحدى الحقائق المهمة جدًا التي يجب فهمها في منطق الوظيفة هذا هي أن تدريب الشبكة العصبية وتوليد حلقاتنا يتم إجراؤها في نفس الوقت. إنها ليست متوازية تمامًا ، ولكن في كل مرة تتراكم في الحلقة الخاصة بنا حلقات كافية (16) ، فإنها تمرر التحكم إلى متصل الوظيفة ، والذي من المفترض أن يقوم بتدريب الشبكة العصبية باستخدام النزول الإشتقاقي (Gradient Descent) . لذلك ، عندما يتم إرجاع yield ، سيكون للشبكة العصبية سلوك مختلف (نأمل) أفضل قليلاً.
حسنًا ، نحتاج الآن إلى تحديد وظيفة أخرى وبعد ذلك سنكون مستعدين للانتقال إلى حلقة التدريب.
def filter_batch(batch, percentile): rewards = list(map(lambda s: s.reward, batch)) reward_bound = np.percentile(rewards, percentile) reward_mean = float(np.mean(rewards))
هذه الوظيفة هي جوهر طريقة الانتروبيا المتقاطعة – من حزم الحلقات المعطاة والقيمة المئوية ، فإنها تحسب مكافأة حدية (boundary reward,) ، تُستخدم لتصفية حلقات “النخبة” للتدريب عليها. للحصول على المكافأة الحديه، سنستخدم دالة النسبة المئوية في NumPy ، والتي تحسب قيمة النسبة المئوية من قائمة القيم والنسبة المئوية المطلوبة. بعد ذلك ، سوف نحسب متوسط المكافأة ، والذي يستخدم فقط للمراقبة.
train_obs = [] train_act = [] for reward, steps in batch: if reward < reward_bound: continue train_obs.extend(map(lambda step: step.observation,steps)) train_act.extend(map(lambda step: step.action, steps))
بعد ذلك ، سنقوم بتصفية حلقاتنا. لكل حلقة في الحزمة، سوف نتحقق من أن الحلقة تحتوي على مكافأة إجمالية أعلى من حدودنا ، وإذا كانت كذلك ، فسنقوم بتعبئة قوائم الملاحظات والإجراءات التي سنتدرب عليها.
train_obs_v = torch.FloatTensor(train_obs) train_act_v = torch.LongTensor(train_act) return train_obs_v, train_act_v, reward_bound, reward_mean
كخطوة أخيرة للوظيفة ، سنحول ملاحظاتنا وأفعالنا من حلقات “النخبة” إلى حلقات موتر ، ونعيد مجموعة من أربعة عناصر: الملاحظات ، والإجراءات ، وحدود المكافأة ، والمكافأة المتوسطة. سيتم استخدام القيمتين الأخيرتين فقط لكتابتهما في TensorBoard للتحقق من أداء وكيلنا.
الآن ، الجزء الأخير من الكود الذي يجمع كل شيء معًا ، ويتكون في الغالب من حلقة التدريب ، هو كما يلي:
if __name__ == "__main__": env = gym.make("CartPole-v0") # env = gym.wrappers.Monitor(env, directory="mon", force=True) obs_size = env.observation_space.shape[0] n_actions = env.action_space.n net = Net(obs_size, HIDDEN_SIZE, n_actions) objective = nn.CrossEntropyLoss() optimizer = optim.Adam(params=net.parameters(), lr=0.01) writer = SummaryWriter(comment="-cartpole")
في البداية ، نقوم بإنشاء جميع الكائنات المطلوبة: البيئة ، و الشبكة العصبية الخاص بنا ، والوظيفة الموضوعية ، والمحسن ، وكاتب الملخص لـ TensorBoard ، وكذلك مقطع فيديو لأداء وكيلك.
for iter_no, batch in enumerate(iterate_batches( env, net,BATCH_SIZE)): obs_v, acts_v, reward_b, reward_m = \ filter_batch(batch, PERCENTILE) optimizer.zero_grad() action_scores_v = net(obs_v) loss_v = objective(action_scores_v, acts_v) loss_v.backward() optimizer.step()
في حلقة التدريب ، نقوم بتكرار مجموعاتنا (قائمة كائنات الحلقة) ، ثم نقوم بتصفية حلقات “النخبة” باستخدام وظيفة filter_batch. والنتيجة هي متغيرات الملاحظات والإجراءات المتخذة ، وحد المكافأة المستخدم للتصفية ، ومتوسط المكافأة.
بعد ذلك ، نصفر إشتقاقات الشبكة العصبية الخاصة بنا ونمرر الملاحظات إلى الشبكة العصبة، ونحصل على نتائج عملها. يتم تمرير هذه النتائج إلى الوظيفة الموضوعية ، والتي ستحسب الانتروبيا المتقاطعة بين ناتج الشبكة العصبية والإجراءات التي اتخذها الوكيل.
فكرة هذا هو تعزيز الشبكة العصبية لدينا لتنفيذ تلك الإجراءات “النخبة” التي أدت إلى مكافآت جيدة. بعد ذلك ، نحسب التدرجات عند الخسارة ونطلب من المحسن ضبط الشبكة العصبية الخاص بنا.
print("%d: loss=%.3f, reward_mean=%.1f, rw_bound=%.1f" % ( iter_no, loss_v.item(), reward_m, reward_b)) writer.add_scalar("loss", loss_v.item(), iter_no) writer.add_scalar("reward_bound", reward_b, iter_no) writer.add_scalar("reward_mean", reward_m, iter_no)
ما تبقى من الحلقة هو في الغالب مراقبة التقدم. على وحدة التحكم ، نعرض رقم التكرار ، والخسارة ، ومتوسط المكافأة للدُفعة ، وحدود المكافأة. نكتب أيضًا نفس القيم إلى TensorBoard ، للحصول على مخطط جميل لأداء التعلم للوكيل.
if reward_m > 199: print("Solved!") break writer.close()
آخر ما تفحصه الحلقة هو مقارنة متوسط المكافآت لحلقات الحزم . عندما يصبح هذا أكبر من 199 ، نتوقف عن تدريبنا. لماذا 199؟ فيgym ، تعتبر بيئة CartPole قد تم حلها عندما يكون متوسط المكافأة لآخر 100 حلقة أكبر من 195 ، لكن طريقتنا تتقارب بسرعة كبيرة لدرجة أن 100 حلقة هي عادة كل ما نحتاج إليه
. يمكن للوكيل المدرب بشكل صحيح أن يوازن العصا الطويلة بلا حدود (الحصول على أي قدر من النقاط) ، لكن طول الحلقة في CartPole يقتصر على 200 خطوة (إذا نظرت إلى متغير البيئة لـ CartPole ، فقد تلاحظ غلاف TimeLimit ، والذي توقف الحلقة بعد 200 خطوة). مع وضع كل هذا في الاعتبار ، سنتوقف عن التدريب بعد أن يكون متوسط المكافأة في الحزمة أكبر من 199 ، وهو مؤشر جيد على أن وكيلنا يعرف كيفية موازنة العصا مثل المحترفين.
هذا هو. فلنبدأ تدريبنا الأول على RL!
0: loss=0.701, reward_mean=18.0, rw_bound=21.0 1: loss=0.682, reward_mean=22.6, rw_bound=23.5 2: loss=0.688, reward_mean=23.6, rw_bound=25.5 3: loss=0.675, reward_mean=22.8, rw_bound=22.0 4: loss=0.658, reward_mean=31.9, rw_bound=34.0 ......... 36: loss=0.527, reward_mean=135.9, rw_bound=168.5 37: loss=0.527, reward_mean=147.4, rw_bound=160.5 38: loss=0.528, reward_mean=179.8, rw_bound=200.0 39: loss=0.530, reward_mean=178.7, rw_bound=200.0 40: loss=0.532, reward_mean=192.1, rw_bound=200.0 41: loss=0.523, reward_mean=196.8, rw_bound=200.0 42: loss=0.540, reward_mean=200.0, rw_bound=200.0 Solved!
عادة لا يستغرق الوكيل أكثر من 50 حزمة لحل البيئة. وهو أداء تعليمي جيد حقًا (تذكر ، نحتاج إلى تشغيل 16 حلقة فقط لكل دفعة). يُظهر TensorBoard أن وكيلنا يحرز تقدمًا باستمرار ، ويدفع الحد الأعلى في كل دفعة تقريبًا (هناك بعض فترات التدحرج ، ولكن في معظم الأحيان يتحسن).
ختاماً
دعنا الآن نتوقف قليلاً ونفكر فيما حدث للتو. لقد تعلمت الشبكة العصبية كيف تلعب في البيئة فقط من الملاحظات والمكافآت ، دون أي تفسير للقيم المرصودة. لا يمكن أن تكون البيئة عربة بعصا و حسب ؛ يمكن أن تكون ، على سبيل المثال ، نموذج مستودع بكميات المنتج كملاحظة والأموال المكتسبة كمكافأة. لا يعتمد تنفيذنا على تفاصيل البيئة. هذا هو جمال نموذج التعلم العميق.
إضافة تعليق