تحسين السياسة القريبة (PPO) هو أحد الخوارزميات المفضلة لحل مشاكل التعلم المعزز (RL). تم تطويره في عام 2017 بواسطة جون شومان، أحد مؤسسي OpenAI.
تم استخدام PPO على نطاق واسع في OpenAI لتدريب النماذج على محاكاة سلوك شبيه بالبشر. إنه يحسن من الطرق السابقة مثل تحسين سياسة منطقة الثقة (TRPO) وقد أصبح شائعًا لأنه خوارزمية قوية وفعالة.
في هذا الدليل، نستعرض PPO بعمق. نتناول النظرية ونوضح كيفية تطبيقه باستخدام PyTorch.
فهم تحسين السياسة القريبة (PPO)
تقوم خوارزميات التعلم تحت الإشراف التقليدية بتحديث المعلمات في اتجاه الانحدار الأكثر حدة. إذا تبين أن هذا التحديث مفرط، يتم تصحيحه خلال أمثلة التدريب اللاحقة التي تكون مستقلة عن بعضها البعض.
ومع ذلك، تتكون أمثلة التدريب في التعلم المعزز من إجراءات العميل وعوائده. وبالتالي، فإن أمثلة التدريب مرتبطة ببعضها البعض. يستكشف العميل البيئة لمعرفة السياسة المثلى. وبالتالي، فإن إجراء تغييرات كبيرة على الانحدار يمكن أن يؤدي إلى توقف السياسة في منطقة سيئة مع مكافآت دون المستوى الأمثل. نظرًا لأن العميل يحتاج إلى استكشاف البيئة، فإن التغييرات الكبيرة في السياسة تجعل عملية التدريب غير مستقرة.
تهدف أساليب المعتمدة على منطق الثقة إلى تجنب هذه المشكلة من خلال ضمان أن تكون تحديثات السياسة ضمن منطقة موثوق بها. هذه المنطقة الموثوق بها هي منطقة مقيدة اصطناعيًا ضمن مساحة السياسة التي يُسمح فيها بالتحديثات. يمكن أن تكون السياسة المحدثة فقط ضمن منطقة موثوقة من السياسة القديمة. ضمان أن تكون تحديثات السياسة تدريجية يمنع الاستقرار.
تحديثات السياسة ضمن منطقة الثقة (TRPO)
تم اقتراح خوارزمية تحديثات السياسة ضمن منطقة الثقة (TRPO) في عام 2015 من قبل جون شولمان (الذي اقترح أيضًا PPO في عام 2017). لقياس الفرق بين السياسة القديمة والسياسة المحدثة، يستخدم TRPO التباين كولباك-لايبلر (KL). يتم استخدام تباين KL لقياس الفرق بين توزيعي احتمالين. أثبت TRPO أنه فعال في تنفيذ مناطق الثقة.
المشكلة في TRPO هي التعقيد الحسابي المرتبط بتباين KL. يجب توسيع تطبيق تباين KL إلى الأمر الثاني باستخدام أساليب عددية مثل توسيع تايلور. هذا مكلف حسابيًا. تم اقتراح PPO كبديل أبسط وأكثر كفاءة لـ TRPO. يقوم PPO بتقليص نسبة السياسات لتقريب منطقة الثقة دون اللجوء إلى حسابات معقدة تتضمن تباين KL.
هذا هو السبب في أن PPO أصبح مفضلًا على TRPO في حل مشاكل التعلم المعزز. نظرًا للطريقة الأكثر كفاءة في تقدير مناطق الثقة، فإن PPO يوازن بشكل فعال بين الأداء والاستقرار.
تقريب السياسة القريب (PPO)
PPO غالبًا ما يُعتبر فرعًا فرعيًا من طرق الممثل-الناقد، والتي تقوم بتحديث تدرجات السياسة بناءً على دالة القيمة. تستخدم طرق الممثل الناقد المميزة (A2C) معلمة تسمى الميزة. تقيس هذه الفارق بين العوائد المتوقعة من قبل الناقد والعوائد المحققة من خلال تنفيذ السياسة.
لفهم PPO، تحتاج إلى معرفة مكوناته:
- الممثل ينفذ السياسة. يتم تنفيذه كشبكة عصبية. عند إعطائها حالة كمدخل، فإنها تخرج الإجراء الذي يجب اتخاذه.
- الناقد هو شبكة عصبية أخرى. يأخذ الحالة كإدخال ويخرج القيمة المتوقعة لتلك الحالة. بالتالي، يعبر الناقد عن وظيفة قيمة الحالة.
- يمكن لطرق تدريب السياسات على أساس التدرج استخدام وظائف أهداف مختلفة. على وجه الخصوص، يستخدم PPO وظيفة الميزة. تقيس وظيفة الميزة المقدار الذي تتجاوزه المكافأة التراكمية (بناءً على السياسة التي ينفذها الفاعل) عن المكافأة الأساسية المتوقعة (كما يتنبأ به الناقد). هدف PPO هو زيادة احتمالية اختيار الإجراءات ذات الميزة العالية. تستخدم الهدف من الأمثلة لـ PPO وظائف فقدان استنادًا إلى وظيفة الميزة هذه.
- الدالة الهدف المقصوصة هي الابتكار الرئيسي في PPO. تمنع التحديثات الكبيرة للسياسة في تدريب واحد. تقيد مقدار تحديث السياسة في تدريب واحد. لقياس التحديثات التدريجية للسياسة، تستخدم الطرق القائمة على السياسة نسبة الاحتمال للسياسة الجديدة إلى السياسة القديمة.
- الخسارة البديلة هي الدالة الهدف في PPO وتأخذ بعين الاعتبار الابتكارات المذكورة سابقًا. يتم حسابها على النحو التالي:
- حساب النسبة الفعلية (كما شرح سابقًا) وضربها بالميزة.
- قص نسبة الى الحد المرغوب. ضرب النسبة المقصوصة بالميزة.
- خذ القيمة الدنيا للكميتين أعلاه.
- في التطبيق العملي، يتم أيضًا إضافة مصطلح الانحباس إلى الخسارة البديلة. يُسمى هذا المكافأة الانحباس. يستند إلى التوزيع الرياضي لاحتماليات الإجراء. الفكرة وراء مكافأة الانحباس هي إدخال بعض العشوائية الإضافية بطريقة مراقبة. يشجع القيام بذلك على عملية الأمثلة لاستكشاف فضاء الإجراء. تعزز مكافأة الانحباس العالية الاستكشاف على الاستغلال.
فهم آلية القص
لنفترض أنه بموجب السياسة القديمة πold، فإن احتمالية اتخاذ الإجراء a في الحالة s هي πold(a|s). بموجب السياسة الجديدة، تم تحديث احتمالية اتخاذ نفس الإجراء a من نفس الحالة s إلى πnew(a|s). نسبة هذه الاحتماليات، كدالة لمعلمات السياسة θ، هي r(θ). عندما تجعل السياسة الجديدة الإجراء أكثر احتمالية (في نفس الحالة)، تكون النسبة أكبر من 1 والعكس صحيح.
آلية القص تقيّد نسبة الاحتمالات الجديدة بحيث يجب أن تكون احتمالات الإجراءات الجديدة ضمن نسبة مئوية معينة من احتمالات الإجراءات القديمة. على سبيل المثال، r(θ) يمكن تقييده بالتحديد بين 0.8 و 1.2. وهذا يمنع القفزات الكبيرة، مما يضمن عملية تدريب مستقرة.
في بقية هذه المقالة، ستتعلم كيف تجمع المكونات لتنفيذ بروتوكول PPO باستخدام PyTorch.
1. إعداد البيئة
قبل تنفيذ بروتوكول PPO، يجب علينا تثبيت مكتبات البرمجيات الأساسية واختيار بيئة مناسبة لتطبيق السياسة.
تثبيت PyTorch والمكتبات المطلوبة
نحتاج إلى تثبيت البرامج التالية:
- PyTorch ومكتبات برمجيات أخرى، مثل
numpy
(للوظائف الرياضية والإحصائية) وmatplotlib
(لرسم الرسوم البيانية). - الحزمة البرمجية Gym مفتوحة المصدر من OpenAI، وهي مكتبة Python تحاكي بيئات وألعاب مختلفة، يمكن حلها باستخدام تعلم التعزيز. يمكنك استخدام واجهة برمجة التطبيقات الخاصة بـ Gym لجعل خوارزميتك تتفاعل مع البيئة. نظرًا لتغيير وظائف
gym
أحيانًا خلال عملية الترقية، في هذا المثال، سنقوم بتثبيت إصداره على0.25.2
.
لتثبيته على خادم أو جهاز محلي، قم بتشغيل:
$ pip install torch numpy matplotlib gym==0.25.2
لتثبيت باستخدام كمبيوتر محمول مثل جوجل كولاب أو ديتالاب، استخدم:
!pip install torch numpy matplotlib gym==0.25.2
قم بإنشاء بيئة (أو بيئات) CartPole
استخدم OpenAI Gym لإنشاء حالتين (واحدة للتدريب والأخرى للاختبار) من بيئة CartPole:
env_train = gym.make('CartPole-v1') env_test = gym.make('CartPole-v1')
2. تنفيذ PPO في PyTorch
الآن، دعنا نقوم بتنفيذ PPO باستخدام PyTorch.
تعريف شبكة السياسة
كما شرح سابقًا، يتم تنفيذ PPO كنموذج ممثل-نقاد. يقوم الممثل بتنفيذ السياسة، والنقاد يتنبأ بقيمتها المقدرة. تأخذ الشبكات العصبية للممثل والنقاد نفس المدخل – الحالة في كل فترة زمنية. بالتالي، يمكن لنماذج الممثل والنقاد مشاركة شبكة عصبية مشتركة، والتي تُشار إليها بتصميم المعمارية الأساسية. يمكن للممثل والنقاد توسيع تصميم المعمارية الأساسية بطبقات إضافية.
قم بتعريف شبكة العمود الفقري
تصف الخطوات التالية شبكة العمود الفقري:
- قم بتنفيذ شبكة تتكون من 3 طبقات – مدخل وطبقة مخفية وطبقة إخراج.
- بعد الطبقات المدخلية والمخفية، نستخدم وظيفة تنشيط. في هذا البرنامج التعليمي، نختار ReLU لأنها فعالة حسابيًا.
- نفرض أيضًا وظيفة الإسقاط بعد الطبقات الداخلية للحصول على شبكة قوية. تقوم وظيفة الإسقاط بتصفير بعض الخلايا العصبية بشكل عشوائي. يقلل هذا من الاعتماد على الخلايا العصبية المحددة ويمنع الإفراط في التلائم، مما يجعل الشبكة أكثر قوة.
الكود أدناه ينفذ البنية الأساسية:
class BackboneNetwork(nn.Module): def __init__(self, in_features, hidden_dimensions, out_features, dropout): super().__init__() self.layer1 = nn.Linear(in_features, hidden_dimensions) self.layer2 = nn.Linear(hidden_dimensions, hidden_dimensions) self.layer3 = nn.Linear(hidden_dimensions, out_features) self.dropout = nn.Dropout(dropout) def forward(self, x): x = self.layer1(x) x = f.relu(x) x = self.dropout(x) x = self.layer2(x) x = f.relu(x) x = self.dropout(x) x = self.layer3(x) return x
تعريف شبكة اللاعب-الحكم
الآن، يمكننا استخدام هذه الشبكة لتعريف فئة اللاعب-الحكم، ActorCritic
. اللاعب يقوم بنمذجة السياسة ويتنبأ بالإجراء. الحكم يقوم بنمذجة وظيفة القيمة ويتنبأ بالقيمة. كلاهما يأخذ الحالة كإدخال.
class ActorCritic(nn.Module): def __init__(self, actor, critic): super().__init__() self.actor = actor self.critic = critic def forward(self, state): action_pred = self.actor(state) value_pred = self.critic(state) return action_pred, value_pred
إنشاء شبكات اللاعب والحكم
سنستخدم الشبكات المحددة أعلاه لإنشاء لاعب وحكم. ثم، سنقوم بإنشاء وكيل، بما في ذلك اللاعب والحكم.
قبل إنشاء الوكيل، قم بتهيئة معلمات الشبكة:
- أبعاد الطبقة الداخلية، H، وهو معلم قابل للتكوين. يعتمد حجم وعدد الطبقات الداخلية على تعقيد المشكلة. سنستخدم طبقة داخلية بأبعاد 64 × 64.
- ميزات الإدخال، N، حيث يعد N حجم مصفوفة الحالة. تحتوي الطبقة الداخلية على أبعاد N x H. في بيئة CartPole، الحالة هي مصفوفة تتكون من 4 عناصر. لذا N هو 4.
- ميزات الإخراج لشبكة اللاعب، O، حيث يعد O عدد الإجراءات في البيئة. تحتوي طبقة الإخراج للاعب على أبعاد H x O. تحتوي بيئة CartPole على 2 إجراء.
- ميزات الإخراج لشبكة الحكم. نظرًا لأن شبكة الحكم تتنبأ فقط بالقيمة المتوقعة (بالنظر إلى حالة الإدخال)، فإن عدد ميزات الإخراج هو 1.
- الانقطاع ككسر.
يوضح الكود التالي كيفية إعلان الشبكات الخاصة بالممثل والنقد بناءً على الشبكة الأساسية:
def create_agent(hidden_dimensions, dropout): INPUT_FEATURES = env_train.observation_space.shape[0] HIDDEN_DIMENSIONS = hidden_dimensions ACTOR_OUTPUT_FEATURES = env_train.action_space.n CRITIC_OUTPUT_FEATURES = 1 DROPOUT = dropout actor = BackboneNetwork( INPUT_FEATURES, HIDDEN_DIMENSIONS, ACTOR_OUTPUT_FEATURES, DROPOUT) critic = BackboneNetwork( INPUT_FEATURES, HIDDEN_DIMENSIONS, CRITIC_OUTPUT_FEATURES, DROPOUT) agent = ActorCritic(actor, critic) return agent
حساب العوائد
يوفر البيئة مكافأة عند الانتقال من كل خطوة إلى التالية، اعتمادًا على إجراء الوكيل. تُعبر المكافأة، R، عن:
تُعرف العائدات بأنها القيمة المتراكمة للمكافآت المستقبلية المتوقعة. المكافآت من الخطوات الزمنية التي تكون أبعد في المستقبل أقل قيمة من المكافآت الفورية. وبالتالي، يتم حساب العائد بشكل شائع كعائد مخفض، G، والذي يُعرف على أنه:
في هذا الدليل (وعديد من المراجع الأخرى)، تشير العائدات إلى العائد المخفض.
لحساب العائد:
- ابدأ بالمكافآت المتوقعة من جميع الحالات المستقبلية.
- اضرب كل مكافأة مستقبلية بقوة عامل الخصم. على سبيل المثال، تُضرب المكافأة المتوقعة بعد 2 خطوة زمنية (من الحاضر) في 2.
- اجمع جميع المكافآت المستقبلية المخفضة لحساب العائد.
- قم بتطبيع قيمة العائد.
تقوم الدالة calculate_returns()
بإجراء هذه الحسابات، كما هو موضح أدناه:
def calculate_returns(rewards, discount_factor): returns = [] cumulative_reward = 0 for r in reversed(rewards): cumulative_reward = r + cumulative_reward * discount_factor returns.insert(0, cumulative_reward) returns = torch.tensor(returns) # تطبيع العائد returns = (returns - returns.mean()) / returns.std() return returns
تنفيذ دالة الميزة
يتم حساب الميزة كفارق بين القيمة التي يتنبأ بها الناقد والعائد المتوقع من الإجراءات التي يختارها الممثل وفقًا للسياسة. بالنسبة لإجراء معين، تعبر الميزة عن فائدة اتخاذ هذا الإجراء المحدد على إجراء عشوائي (معدل).
في ورقة PPO الأصلية (المعادلة 10)، يتم التعبير عن الميزة، التي تنظر إلى الأمام حتى الخطوة الزمنية T، على النحو التالي:
أثناء ترميز الخوارزمية، يتم فرض قيد النظر إلى عدد مجموعة من الخطوات الزمنية من خلال حجم الدفعة. لذلك، يمكن تبسيط المعادلة أعلاه كفرق بين القيمة والمردودات المتوقعة. تُقدر المردودات المتوقعة في دالة قيمة الحالة-الإجراء، Q.
وبالتالي، تعبر الصيغة المبسطة أدناه عن الميزة في اختيار:
- إجراء معين
- في حالة معينة
- تحت سياسة معينة
- في الخطوة الزمنية المحددة
ويتم التعبير عن ذلك على النحو التالي:
تستخدم OpenAI أيضًا هذه الصيغة لتنفيذ RL. دالة calculate_advantages()
المعروضة أدناه تقوم بحساب الميزة:
def calculate_advantages(returns, values): advantages = returns - values # تقييم الميزة advantages = (advantages - advantages.mean()) / advantages.std() return advantages
خسارة البدائل وآلية القص المناسبة
سيكون خسارة السياسة القياسية هي خسارة تدريج السياسة القياسية دون تقنيات خاصة مثل PPO. يتم حساب خسارة تدريج السياسة القياسية على أنها حاصل ضرب:
- احتمالات إجراء السياسة
- وظيفة الميزة، التي تحسب كفرق بين:
- عائد السياسة
- القيمة المتوقعة
لا يمكن لخسارة تدريج السياسة القياسية إجراء تصحيحات للتغييرات السريعة في السياسة. تعد الخسارة البديلة بديلاً للخسارة القياسية لتقييد كمية التغيير التي يمكن أن تحدث في السياسة في كل تكرار. إنها الحد الأدنى لكميتين:
- منتج:
- نسبة السياسة. تعبر هذه النسبة عن الفرق بين احتمالات الإجراء القديمة والجديدة.
- دالة الميزة
- منتج:
- قيمة نسبة السياسة المقطوعة. يتم قص هذه النسبة بحيث تكون السياسة المحدثة ضمن نسبة معينة من السياسة القديمة.
- دالة الميزة
لعملية الأمثلية، يُستخدم الخسارة الاستبدالية كبديل للخسارة الفعلية.
آلية القص
نسبة السياسة، R، هي الفارق بين السياسات الجديدة والقديمة وتُعطى كنسبة للسجلات الاحتمالية للسياسة تحت المعلمات الجديدة والقديمة:
نسبة السياسة المُقصَّرة، R’، مقيّدة بحيث:
بناءً على الميزة، أما تم عرضه في القسم السابق، ونسبة السياسة، كما هو موضح أعلاه، يتم حساب الخسارة البديلة على النحو التالي:
الكود أدناه يوضح كيفية تنفيذ آلية القص والخسارة البديلة.
def calculate_surrogate_loss( actions_log_probability_old, actions_log_probability_new, epsilon, advantages): advantages = advantages.detach() policy_ratio = ( actions_log_probability_new - actions_log_probability_old ).exp() surrogate_loss_1 = policy_ratio * advantages surrogate_loss_2 = torch.clamp( policy_ratio, min=1.0-epsilon, max=1.0+epsilon ) * advantages surrogate_loss = torch.min(surrogate_loss_1, surrogate_loss_2) return surrogate_loss
3. تدريب العامل
الآن، دعونا نقوم بتدريب العامل.
حساب الخسارة الخاصة بالسياسة والقيمة
نحن الآن جاهزون لحساب خسائر السياسة والقيمة:
- خسارة السياسة هي مجموع خسارة الاحتكار ومكافأة الانحراف.
- خسارة القيمة تعتمد على الفرق بين القيمة المتوقعة من قبل الناقد والعوائد (المكافأة التراكمية) التي تم توليدها بواسطة السياسة. يستخدم حساب خسارة القيمة وظيفة Smooth L1 Loss. هذا يساعد على تنعيم وظيفة الخسارة ويجعلها أقل حساسية للقيم الشاذة.
كلتا الخسارتين، كما تم حسابهما أعلاه، هما أوجه توافق. يستند الانحدار التدريجي إلى القيم العلمية. للحصول على قيمة علمية واحدة تمثل الخسارة، استخدم وظيفة .sum()
لجمع عناصر الجهاز الحسابي. توضح الوظيفة أدناه كيفية القيام بذلك:
def calculate_losses( surrogate_loss, entropy, entropy_coefficient, returns, value_pred): entropy_bonus = entropy_coefficient * entropy policy_loss = -(surrogate_loss + entropy_bonus).sum() value_loss = f.smooth_l1_loss(returns, value_pred).sum() return policy_loss, value_loss
تحديد حلقة التدريب
قبل بدء عملية التدريب، قم بإنشاء مجموعة من البافرات كمصفوفات فارغة. سيقوم خوارزمية التدريب باستخدام هذه البافرات لتخزين معلومات حول إجراءات الوكيل، حالات البيئة، والمكافآت في كل خطوة زمنية. الدالة أدناه تهيئ هذه البافرات:
def init_training(): states = [] actions = [] actions_log_probability = [] values = [] rewards = [] done = False episode_reward = 0 return states, actions, actions_log_probability, values, rewards, done, episode_reward
كل تكرار للتدريب يشغّل الوكيل بمعلمات السياسة لذلك التكرار. الوكيل يتفاعل مع البيئة في خطوات زمنية في حلقة حتى يصل إلى شرط الإنهاء.
بعد كل خطوة زمنية، يتم إلحاق إجراء الوكيل، المكافأة، والقيمة بالبافرات المناسبة. عند انتهاء الحلقة، تقوم الدالة بإرجاع مجموعة البافرات المحدثة، التي تلخص نتائج الحلقة.
قبل تشغيل حلقة التدريب:
- قم بتعيين النموذج إلى وضع التدريب باستخدام
agent.train()
. - أعد بيئة إلى حالة عشوائية باستخدام
env.reset()
. هذه هي الحالة الابتدائية لهذه الدورة التدريبية.
تشرح الخطوات التالية ما يحدث في كل خطوة زمنية في حلقة التدريب:
- قم بتمرير الحالة إلى الوكيل.
- يُرجع الوكيل:
- الإجراء المتوقع بالنظر إلى الحالة، استنادًا إلى السياسة (الممثل). قم بتمرير هذا الجزء من الإجراء المتوقع من خلال وظيفة softmax للحصول على مجموعة من احتماليات الإجراء.
- القيمة المتوقعة للحالة، بناءً على الناقد.
- يختار العامل الإجراء الذي يجب اتخاذه:
- استخدم احتمالات الإجراء لتقدير توزيع الاحتمالات.
- اختر إجراء بشكل عشوائي عن طريق اختيار عينة من هذا التوزيع. تقوم وظيفة
dist.sample()
بذلك. - استخدم وظيفة
env.step()
لتمرير هذا الإجراء إلى البيئة لمحاكاة استجابة البيئة لهذه الفترة الزمنية. استنادًا إلى إجراء العامل، تولد البيئة: - الحالة الجديدة
- المكافأة
- قيمة الإرجاع البولية
done
(وهذا يشير إلى ما إذا كانت البيئة قد وصلت إلى حالة نهائية) - ألصق في الذواكر المعنية قيم إجراء العميل، والمكافآت، والقيم المتوقعة، والحالة الجديدة.
تنتهي حلقة التدريب عندما تعود وظيفة env.step()
بقيمة true
لقيمة الإرجاع البولية لـ done
.
بعد انتهاء الحلقة، استخدم القيم المتراكمة من كل خط زمني لحساب العوائد التراكمية من هذه الحلقة عن طريق إضافة المكافآت من كل خط زمني. نستخدم وظيفة calculate_returns()
الموضحة سابقًا للقيام بذلك. مدخلات هذه الوظيفة هي عامل الخصم والمخزن الذي يحتوي على المكافآت من كل خط زمني. نستخدم هذه العوائد والقيم المتراكمة من كل خط زمني لحساب المزايا باستخدام وظيفة calculate_advantages()
.
توضح الوظيفة البرمجية التالية باللغة Python كيفية تنفيذ هذه الخطوات:
def forward_pass(env, agent, optimizer, discount_factor): states, actions, actions_log_probability, values, rewards, done, episode_reward = init_training() state = env.reset() agent.train() while not done: state = torch.FloatTensor(state).unsqueeze(0) states.append(state) action_pred, value_pred = agent(state) action_prob = f.softmax(action_pred, dim=-1) dist = distributions.Categorical(action_prob) action = dist.sample() log_prob_action = dist.log_prob(action) state, reward, done, _ = env.step(action.item()) actions.append(action) actions_log_probability.append(log_prob_action) values.append(value_pred) rewards.append(reward) episode_reward += reward states = torch.cat(states) actions = torch.cat(actions) actions_log_probability = torch.cat(actions_log_probability) values = torch.cat(values).squeeze(-1) returns = calculate_returns(rewards, discount_factor) advantages = calculate_advantages(returns, values) return episode_reward, states, actions, actions_log_probability, advantages, returns
تحديث معلمات النموذج
تقوم كل دورة تدريب بتمرير النموذج من خلال حلقة كاملة تتألف من العديد من الخطوات الزمنية (حتى يصل إلى شرط الإنهاء). في كل خط زمني، نقوم بتخزين معلمات السياسة، إجراء العميل، العوائد، والمزايا. بعد كل دورة، نقوم بتحديث النموذج استنادًا إلى أداء السياسة عبر جميع الخطوات الزمنية في تلك الدورة.
الحد الأقصى لعدد الخطوات في بيئة CartPole هو 500. في بيئات أكثر تعقيدًا، هناك مزيد من الخطوات، حتى ملايين. في مثل هذه الحالات، يجب تقسيم مجموعة بيانات نتائج التدريب إلى دفعات. يُسمى عدد الخطوات في كل دفعة حجم الدفعة التحسينية.
بالتالي، الخطوات لتحديث معلمات النموذج هي:
- تقسيم مجموعة بيانات نتائج التدريب إلى دفعات.
- لكل دفعة:
- الحصول على إجراء الوكيل والقيمة المتوقعة لكل حالة.
- استخدام هذه الإجراءات المتوقعة لتقدير توزيع احتمالية الإجراء الجديد.
- استخدم هذا التوزيع لحساب الانحراف.
- استخدم هذا التوزيع للحصول على سجل احتمال الإجراءات في مجموعة بيانات نتائج التدريب. هذه هي مجموعة جديدة من سجلات الاحتمالات للإجراءات في مجموعة بيانات نتائج التدريب. تم حساب مجموعة السجلات القديمة لهذه الإجراءات نفسها في حلقة التدريب المشروحة في القسم السابق.
- قم بحساب الخسارة البديلة باستخدام توزيعات الاحتمالات القديمة والجديدة للإجراءات.
- قم بحساب خسارة السياسة وخسارة القيمة باستخدام الخسارة البديلة والانحراف والمزايا.
- قم بتشغيل
.backward()
بشكل منفصل على خسارة السياسة والقيمة. يقوم هذا بتحديث الميل على وظائف الخسارة. - تشغيل
.step()
على المحسن لتحديث معلمات السياسة. في هذه الحالة، نستخدم محسن Adam لتحقيق توازن بين السرعة والمتانة. - تراكم خسائر السياسة والقيمة.
- كرر التمرير الخلفي (العمليات أعلاه) على كل دفعة عدة مرات، اعتمادًا على قيمة المعلمة
PPO_STEPS
. تكرار التمرير الخلفي على كل دفعة يعتبر كفاءة حسابية لأنه يزيد بشكل فعال من حجم مجموعة بيانات التدريب دون الحاجة إلى تشغيل تمريرات أمامية إضافية. يُطلق على عدد خطوات البيئة في كل تناوب بين العينات والتحسين حجم الدفعة لكل دورة. - إرجاع متوسط خسارة السياسة وخسارة القيمة.
الكود أدناه ينفذ هذه الخطوات:
def update_policy( agent, states, actions, actions_log_probability_old, advantages, returns, optimizer, ppo_steps, epsilon, entropy_coefficient): BATCH_SIZE = 128 total_policy_loss = 0 total_value_loss = 0 actions_log_probability_old = actions_log_probability_old.detach() actions = actions.detach() training_results_dataset = TensorDataset( states, actions, actions_log_probability_old, advantages, returns) batch_dataset = DataLoader( training_results_dataset, batch_size=BATCH_SIZE, shuffle=False) for _ in range(ppo_steps): for batch_idx, (states, actions, actions_log_probability_old, advantages, returns) in enumerate(batch_dataset): # احصل على احتمالات تسجيل جديدة للإجراءات لجميع حالات الإدخال action_pred, value_pred = agent(states) value_pred = value_pred.squeeze(-1) action_prob = f.softmax(action_pred, dim=-1) probability_distribution_new = distributions.Categorical( action_prob) entropy = probability_distribution_new.entropy() # قم بتقدير الاحتماليات الجديدة باستخدام الإجراءات القديمة actions_log_probability_new = probability_distribution_new.log_prob(actions) surrogate_loss = calculate_surrogate_loss( actions_log_probability_old, actions_log_probability_new, epsilon, advantages) policy_loss, value_loss = calculate_losses( surrogate_loss, entropy, entropy_coefficient, returns, value_pred) optimizer.zero_grad() policy_loss.backward() value_loss.backward() optimizer.step() total_policy_loss += policy_loss.item() total_value_loss += value_loss.item() return total_policy_loss / ppo_steps, total_value_loss / ppo_steps
4. تشغيل وكيل PPO
لنقم أخيرًا بتشغيل وكيل PPO.
تقييم الأداء
لتقييم أداء الوكيل، قم بإنشاء بيئة جديدة واحسب المكاسب التراكمية من تشغيل الوكيل في هذه البيئة الجديدة. تحتاج إلى ضبط الوكيل على وضع التقييم باستخدام الدالة .eval()
. الخطوات هي نفسها كما في حلقة التدريب. تقوم الكود أدناه بتنفيذ دالة التقييم:
def evaluate(env, agent): agent.eval() rewards = [] done = False episode_reward = 0 state = env.reset() while not done: state = torch.FloatTensor(state).unsqueeze(0) with torch.no_grad(): action_pred, _ = agent(state) action_prob = f.softmax(action_pred, dim=-1) action = torch.argmax(action_prob, dim=-1) state, reward, done, _ = env.step(action.item()) episode_reward += reward return episode_reward
تصور نتائج التدريب
سنستخدم مكتبة Matplotlib لتصوير تقدم عملية التدريب. توضح الدالة أدناه كيفية رسم المكاسب من حلقات التدريب والاختبار:
def plot_train_rewards(train_rewards, reward_threshold): plt.figure(figsize=(12, 8)) plt.plot(train_rewards, label='Training Reward') plt.xlabel('Episode', fontsize=20) plt.ylabel('Training Reward', fontsize=20) plt.hlines(reward_threshold, 0, len(train_rewards), color='y') plt.legend(loc='lower right') plt.grid() plt.show()
def plot_test_rewards(test_rewards, reward_threshold): plt.figure(figsize=(12, 8)) plt.plot(test_rewards, label='Testing Reward') plt.xlabel('Episode', fontsize=20) plt.ylabel('Testing Reward', fontsize=20) plt.hlines(reward_threshold, 0, len(test_rewards), color='y') plt.legend(loc='lower right') plt.grid() plt.show()
في الرسوم البيانية المعروضة أدناه، نظهر مكافآت التدريب والاختبار، التي تم الحصول عليها من خلال تطبيق السياسة في بحوث واختبارات البيئات على التوالي. يرجى ملاحظة أن شكل هذه الرسوم البيانية سيبدو مختلفًا في كل مرة تقوم فيها بتشغيل الكود. هذا بسبب العشوائية الكامنة في عملية التدريب.
مكافآت التدريب (التي تم الحصول عليها من خلال تطبيق السياسة في بيئة التدريب). صورة بواسطة المؤلف.
مكافآت الاختبار (التي تم الحصول عليها من خلال تطبيق السياسة في بيئة الاختبار). صورة بواسطة المؤلف.
في الرسوم البيانية المعروضة أعلاه، انظر إلى تقدم عملية التدريب:
- المكافأة تبدأ من قيم منخفضة. مع تقدم التدريب، تزيد قيم المكافآت.
- تتذبذب المكافآت بشكل عشوائي أثناء الزيادة. يعود ذلك إلى الوكيل الذي يستكشف مساحة السياسة.
- يتوقف التدريب، وتستقر المكافآت التجريبية حول الحد الأدنى (475) لعدة عمليات.
- تتم قيود المكافآت عند 500. هذه القيود مفروضة من قبل البيئة (بيئة Gym CartPole v1).
بالمثل، يمكنك رسم القيمة وفقدان السياسة عبر العمليات:
def plot_losses(policy_losses, value_losses): plt.figure(figsize=(12, 8)) plt.plot(value_losses, label='Value Losses') plt.plot(policy_losses, label='Policy Losses') plt.xlabel('Episode', fontsize=20) plt.ylabel('Loss', fontsize=20) plt.legend(loc='lower right') plt.grid() plt.show()
توضح الرسم البياني الموجود أدناه الخسائر المتتبعة خلال حلقات التدريب:
القيمة والخسائر في السياسة خلال عملية التدريب. الصورة بواسطة المؤلف
لاحظ الرسم البياني وانتبه:
- تبدو الخسائر موزعة عشوائيًا ولا تتبع أي نمط.
- هذا شائع في تدريب RL، حيث أن الهدف ليس تقليل الخسائر وإنما تعظيم المكافآت.
تشغيل خوارزمية PPO
لديك الآن جميع المكونات لتدريب الوكيل باستخدام PPO. لتجميع كل شيء معًا، تحتاج إلى:
- إعلان الهايبربارامترات مثل عامل الخصم، حجم الدفعة، معدل التعلم، إلخ.
- قم بإنشاء حافظات كمصفوفات فارغة لتخزين المكافآت والخسائر من كل تكرار.
- أنشئ مثيل وكيل باستخدام وظيفة
create_agent()
. - قم بتشغيل التمريرات الأمامية والخلفية تكرارًا باستخدام الدوال
forward_pass()
وupdate_policy()
. - اختبر أداء السياسة باستخدام وظيفة
evaluate()
. - ألحق السياسة وخسائر القيمة والمكافآت من وظائف التدريب والتقييم بالحافظات المناسبة.
- حساب متوسط المكافآت والخسائر على مدى الخطوات الزمنية الأخيرة. يقوم المثال أدناه بحساب متوسط المكافآت والخسائر على مدى الـ 40 خطوة زمنية.
- طباعة نتائج التقييم كل عدد من الخطوات. يقوم المثال أدناه بالطباعة كل 10 خطوات.
- إنهاء العملية عند تجاوز المكافأة المتوسطة عتبة معينة.
يوضح الكود أدناه كيفية إعلان وظيفة تقوم بذلك في Python:
def run_ppo(): MAX_EPISODES = 500 DISCOUNT_FACTOR = 0.99 REWARD_THRESHOLD = 475 PRINT_INTERVAL = 10 PPO_STEPS = 8 N_TRIALS = 100 EPSILON = 0.2 ENTROPY_COEFFICIENT = 0.01 HIDDEN_DIMENSIONS = 64 DROPOUT = 0.2 LEARNING_RATE = 0.001 train_rewards = [] test_rewards = [] policy_losses = [] value_losses = [] agent = create_agent(HIDDEN_DIMENSIONS, DROPOUT) optimizer = optim.Adam(agent.parameters(), lr=LEARNING_RATE) for episode in range(1, MAX_EPISODES+1): train_reward, states, actions, actions_log_probability, advantages, returns = forward_pass( env_train, agent, optimizer, DISCOUNT_FACTOR) policy_loss, value_loss = update_policy( agent, states, actions, actions_log_probability, advantages, returns, optimizer, PPO_STEPS, EPSILON, ENTROPY_COEFFICIENT) test_reward = evaluate(env_test, agent) policy_losses.append(policy_loss) value_losses.append(value_loss) train_rewards.append(train_reward) test_rewards.append(test_reward) mean_train_rewards = np.mean(train_rewards[-N_TRIALS:]) mean_test_rewards = np.mean(test_rewards[-N_TRIALS:]) mean_abs_policy_loss = np.mean(np.abs(policy_losses[-N_TRIALS:])) mean_abs_value_loss = np.mean(np.abs(value_losses[-N_TRIALS:])) if episode % PRINT_INTERVAL == 0: print(f'Episode: {episode:3} | \ Mean Train Rewards: {mean_train_rewards:3.1f} \ | Mean Test Rewards: {mean_test_rewards:3.1f} \ | Mean Abs Policy Loss: {mean_abs_policy_loss:2.2f} \ | Mean Abs Value Loss: {mean_abs_value_loss:2.2f}') if mean_test_rewards >= REWARD_THRESHOLD: print(f'Reached reward threshold in {episode} episodes') break plot_train_rewards(train_rewards, REWARD_THRESHOLD) plot_test_rewards(test_rewards, REWARD_THRESHOLD) plot_losses(policy_losses, value_losses)
تشغيل البرنامج:
run_ppo()
يجب أن تكون النتائج مشابهة للمثال أدناه:
Episode: 10 | Mean Train Rewards: 22.3 | Mean Test Rewards: 30.4 | Mean Abs Policy Loss: 0.37 | Mean Abs Value Loss: 0.39 Episode: 20 | Mean Train Rewards: 38.6 | Mean Test Rewards: 69.8 | Mean Abs Policy Loss: 0.46 | Mean Abs Value Loss: 0.37 . . . Episode: 100 | Mean Train Rewards: 289.5 | Mean Test Rewards: 427.3 | Mean Abs Policy Loss: 1.73 | Mean Abs Value Loss: 0.21 Episode: 110 | Mean Train Rewards: 357.7 | Mean Test Rewards: 461.4 | Mean Abs Policy Loss: 1.86 | Mean Abs Value Loss: 0.22 Reached reward threshold in 116 episodes
يمكنك عرض وتشغيل البرنامج العامل على هذه الدفتر DataLab!
5. ضبط وتحسين المعلمات
في تعلم الآلة، تتحكم المعلمات الفائقة في عملية التدريب. فيما يلي، أقدم شرحًا لبعض المعلمات الفائقة المهمة المستخدمة في PPO:
- معدل التعلم: يحدد معدل التعلم مدى اختلاف معلمات السياسة في كل تكرار. في الانحدار التدريجي العشوائي، يتم تحديد مقدار تحديث معلمات السياسة في كل تكرار بواسطة حاصل ضرب معدل التعلم والميل.
- معلم القص: يشار إليه أيضًا بالإبسيلون، ε.إنه يحدد مدى قصة نسبة السياسة. يُسمح بتغير نسبة السياسات الجديدة والقديمة في النطاق [1-ε، 1+ε]. عندما تتجاوز هذا النطاق، يتم قصها بشكل اصطناعي لتكون ضمن النطاق.
- حجم الدُفعة: يشير هذا إلى عدد الخطوات التي يتعين مراعاتها لكل تحديث تدرجي. في PPO، حجم الدُفعة هو عدد الخطوات الزمنية اللازمة لتطبيق السياسة وحساب الخسارة البديلة لتحديث معلمات السياسة. في هذه المقالة، استخدمنا حجم دُفعة قدره 64.
- خطوات التكرار: هذا هو عدد مرات إعادة استخدام كل دُفعة لتشغيل التمرير الخلفي. يشير الكود في هذه المقالة إلى هذا باسم
PPO_STEPS
. في البيئات المعقدة، تشغيل التمرير الأمامي مرات عديدة يكلف حسابيًا. البديل الأكثر كفاءة هو إعادة تشغيل كل دُفعة عدة مرات. من الموصى به عادة استخدام قيمة بين 5 و 10. - عامل الخصم: تُشار إليه أيضًا باسم غاما، γ. يعبر عن مدى قيمة المكافآت الفورية مقارنة بالمكافآت المستقبلية. هذا يشبه مفهوم أسعار الفائدة في حساب قيمة الوقت للمال. عندما تكون أقرب إلى 0، فإن ذلك يعني أن المكافآت المستقبلية أقل قيمة ويجب على العامل الأولوية للمكافآت الفورية. عندما تكون أقرب إلى 1، فإن ذلك يعني أن المكافآت المستقبلية مهمة.
- معامل الانحراف:يقرر معامل الانحراف مكافأة الانحراف، التي يتم حسابها كناتج ضرب معامل الانحراف في الانحراف للتوزيع. دور مكافأة الانحراف هو إدخال المزيد من العشوائية في السياسة. وهذا يشجع الوكيل على استكشاف مساحة السياسة. ومع ذلك، فإن التدريب لا يتم الانحسار إلى سياسة مثلى عندما تكون هذه العشوائية مرتفعة جدًا.
- معايير النجاح للتدريب: تحتاج إلى تحديد المعايير لتحديد متى يكون التدريب ناجحًا. الطريقة الشائعة للقيام بذلك هي وضع شرط يفيد بأن المكافآت المتوسطة على مدى آخر N جولة (حلقات) تتجاوز عتبة معينة. في الشيفرة المثالية أعلاه، يتم التعبير عن ذلك باستخدام المتغير
N_TRIALS
. عند تعيين قيمة أعلى لهذا المتغير، يستغرق التدريب وقتًا أطول لأن السياسة يجب أن تحقق المكافأة المطلوبة على مدى حلقات أكثر. كما أنه يؤدي إلى سياسة أكثر قوة بينما يكون أكثر تكلفة حسابية. لاحظ أن PPO هو سياسة متغيرة العشوائية، وستكون هناك حلقات عندما لا يتجاوز العامل العتبة. لذلك، إذا كانت قيمةN_TRIALS
عالية للغاية، فإن التدريب الخاص بك قد لا ينتهي.
استراتيجيات لتحسين أداء PPO
تحسين أداء خوارزميات تدريب PPO يتضمن التجربة والخطأ والتجربة مع قيم معلمات فرعية مختلفة. ومع ذلك، هناك بعض الإرشادات العامة:
- عامل الخصم: عندما تكون المكافآت طويلة المدى مهمة، كما في بيئة CartPole، حيث يجب أن يبقى العمود ثابتًا مع مرور الوقت، ابدأ بقيمة جاما معتدلة، مثل 0.99.
- مكافأة الانحراف: في البيئات المعقدة، يجب على الوكيل استكشاف مساحة الإجراء للعثور على السياسة الأمثل. تعزز مكافأة الانحراف عملية الاستكشاف. يتم إضافة مكافأة الانحراف إلى الخسارة البديلة. تحقق من مقدار الخسارة البديلة وانحراف التوزيع قبل اتخاذ قرار معامل الانحراف. في هذه المقالة، استخدمنا معامل انحراف بقيمة 0.01.
- معلمة القص: تحدد معلمة القص مدى اختلاف السياسة المحدثة يمكن أن تكون عن السياسة الحالية. قيمة كبيرة لمعلمة القص تشجع على استكشاف أفضل للبيئة، ولكنها تعرض التدريب لخطر الاضطراب. تريد معلمة قص تسمح بالاستكشاف التدريجي مع منع التحديثات المثيرة للاضطراب. في هذه المقالة، استخدمنا معلمة قص بقيمة 0.2.
- معدل التعلم: عندما يكون معدل التعلم مرتفعًا للغاية، يتم تحديث السياسة بخطوات كبيرة في كل تكرار وقد يصبح العملية التدريبية غير مستقرة. عندما يكون منخفضًا للغاية، يستغرق التدريب وقتًا طويلًا. في هذا البرنامج التعليمي، تم استخدام معدل تعلم بقيمة 0.001، الذي يعمل بشكل جيد للبيئة. في العديد من الحالات، يُوصى باستخدام معدل تعلم بقيمة 1e-5.
التحديات وأفضل الممارسات في PPO
بعد شرح مفاهيم PPO وتفاصيل تنفيذه، دعونا نناقش التحديات وأفضل الممارسات.
التحديات الشائعة في تدريب PPO
على الرغم من استخدام PPO على نطاق واسع، يجب عليك أن تكون على علم بالتحديات المحتملة لحل مشاكل العالم الحقيقي باستخدام هذه التقنية بنجاح. بعض هذه التحديات هي:
- تقارب بطيء:في البيئات المعقدة، قد يكون PPO غير كفء في استخدام العينات ويحتاج إلى العديد من التفاعلات مع البيئة للتقارب على السياسة الأمثل. وهذا يجعل عملية التدريب بطيئة ومكلفة.
- الحساسية للمعلمات الفائقة: يعتمد PPO على استكشاف مساحة السياسة بكفاءة. استقرار عملية التدريب وسرعة التقارب حساسة لقيم المعلمات الفائقة. يمكن تحديد القيم الأمثل لهذه المعلمات الفائقة غالبًا فقط عن طريق التجربة والخطأ.
- التجاوز: بشكل عام، يتم تهيئة بيئات RL بمعلمات عشوائية. يعتمد تدريب PPO على العثور على السياسة الأمثل بناءً على بيئة العميل. أحيانًا، يتقارب عملية التدريب إلى مجموعة من المعلمات الأمثل لبيئة معينة ولكن ليس لأي بيئة عشوائية. يتم التعامل مع هذا عادةً من خلال إجراء العديد من التكرارات، كل منها ببيئة تدريب مختلفة بشكل عشوائي.
- البيئات الديناميكية: البيئات البسيطة لتعلم التعزيز، مثل بيئة CartPole، هي ثابتة – حيث تبقى القواعد ثابتة مع مرور الوقت. العديد من البيئات الأخرى، مثل روبوت يتعلم السير على سطح متحرك غير مستقر، هي ديناميكية – حيث تتغير قواعد البيئة مع مرور الوقت. للأداء الجيد في مثل هذه البيئات، يحتاج PPO في كثير من الأحيان إلى ضبط إضافي.
- الاستكشاف مقابل الاستغلال: آلية القص في PPO تضمن أن تكون تحديثات السياسة ضمن منطقة موثوقة. ومع ذلك، فإنها تمنع العامل من استكشاف مساحة الإجراءات. وهذا يمكن أن يؤدي إلى التقارب على النقاط المحلية، خاصة في البيئات المعقدة. من ناحية أخرى، فإن السماح للعامل بالاستكشاف بشكل كبير يمكن أن يمنعه من التقارب على أي سياسة أمثل.
أفضل الممارسات لتدريب نماذج PPO
للحصول على نتائج جيدة باستخدام PPO ، أوصي ببعض الممارسات الأفضل مثل:
- تطبيع ميزات الإدخال: تطبيع قيم التقديرات والمزايا يقلل من التباين في البيانات ويؤدي إلى تحديثات ميل مستقرة. يجلب تطبيع البيانات جميع القيم إلى نطاق رقمي متسق. يساعد في تقليل تأثير القيم الشاذة والقيم القصوى، التي يمكن أن تشوه تحديثات الميل وتبطئ عملية التقارب.
- استخدم أحجام دفع كبيرة بشكل مناسب: الدفعات الصغيرة تسمح بتحديثات وتدريب أسرع ولكن يمكن أن تؤدي إلى التق converت إلى البؤر المحلية وعدم استقرار في عملية التدريب. تسمح الدفعات الأكبر بتعلم العميل بسياسات قوية، مما يؤدي إلى عملية تدريب مستقرة. ومع ذلك، الدفعات الكبيرة جدًا غير مثالية أيضًا. بالإضافة إلى زيادة تكاليف الحساب، تجعل تحديثات السياسة أقل استجابة لوظيفة القيمة لأن تحديثات الميل تعتمد على المتوسطات المقدرة على دفعات كبيرة. علاوة على ذلك، يمكن أن يؤدي ذلك إلى تطابق البيانات التحديثية مع تلك الدفعة المحددة.
- خطوات التكرار: عمومًا، من المستحسن إعادة استخدام كل دفعة لمدة 5-10 تكرارات. يجعل ذلك العملية التدريبية أكثر كفاءة. إعادة استخدام نفس الدفعة مرات كثيرة يؤدي إلى التطابق الزائد. يشير الكود إلى هذا المعلمة الفعالة كـ
PPO_STEPS
. - أدِّ تقييمًا دوريًا: لكشف الفرط التكيُّف، من الضروري مراقبة فعالية السياسة بانتظام. إذا تبيَّن أن السياسة غير فعّالة في بعض السيناريوهات، قد تكون هناك حاجة للمزيد من التدريب أو ضبط الدقة.
- ضبط الهايبربارامترز: كما شُرح سابقًا، تعتمد تدريب PPO بشكل حساس على قيم الهايبربارامترز. قم بتجربة قيم مختلفة للهايبربارامترز لتحديد مجموعة القيم الصحيحة لمشكلتك الخاصة.
- الشبكة الظهرية المشتركة: كما هو موضح في هذه المقالة، فإن استخدام شبكة ظهرية مشتركة يمنع الاختلالات بين شبكات العملاء والنقاد. مشاركة الشبكة الظهرية بين العميل والناقد تساعد في استخراج الميزات المشتركة وفهم مشترك للبيئة. هذا يجعل عملية التعلم أكثر كفاءة واستقرارًا. كما أنه يساعد في تقليل المساحة الحسابية وتعقيد الوقت للخوارزمية.
- عدد وحجم الطبقات الخفية: زيادة عدد الطبقات الخفية والأبعاد للبيئات أكثر تعقيدًا. يمكن حل المشاكل الأبسط مثل CartPole باستخدام طبقة خفية واحدة. تحتوي الطبقة الخفية المستخدمة في هذه المقالة على 64 بُعدًا. جعل الشبكة أكبر بكثير من اللازم يُضيع الحوسبة ويمكن أن يجعلها غير مستقرة.
- التوقف المبكّر: التوقف عن التدريب عند تحقيق معايير التقييم يساعد في منع التدريب الزائد ويجنب إهدار الموارد. واحدة من المعايير الشائعة للتقييم هي عندما يتجاوز العميل حدود الجوائز على مدى N أحداث الماضية.
الاستنتاج
في هذه المقالة، ناقشنا PPO كوسيلة لحل مشكلات RL. ثم قمنا بتفصيل الخطوات لتنفيذ PPO باستخدام PyTorch. وأخيرًا، قدمنا بعض النصائح الأداء وأفضل الممارسات لـ PPO.
أفضل طريقة للتعلم هي تنفيذ الشفرة بنفسك. يمكنك أيضًا تعديل الشفرة للعمل مع بيئات التحكم الكلاسيكية الأخرى في Gym. لمعرفة كيفية تنفيذ وكلاء RL باستخدام Python وGymnasium لـ OpenAI، تابع الدورة Reinforcement Learning with Gymnasium in Python!
Source:
https://www.datacamp.com/tutorial/proximal-policy-optimization