الوحدة 8 — طرائق تدرّج السياسة
طرح مختلف جذريًّا: بدل تعلّم قيمة ثمّ استخلاص السياسة، لماذا لا نتعلّم السياسة مباشرة؟ لدينا شبكة تُخرج توزيعًا احتماليًّا على الأفعال، ونضبط بتدرّج على الأداء المُتوقّع. تفتح هذه العائلة الباب لثلاث ميزات لا يوفّرها DQN: سياسات احتماليّة، أفعال مستمرّة، وضمانات تحسين متجانسة.
دالّة الأداء وتدرّجها
نُعرّف أداء السياسة بأنّها العائد المتوقّع الأصلي:
نُريد لتطبيق صعود تدرّج. المشكلة: يُحسب على حلقات تولّدها السياسة نفسها، فتدرّجها ليس بديهيًّا. مبرهنة تدرّج السياسة تقدّم لنا صيغة قابلة للحساب:
القراءة الحدسيّة: يحرّك التدرّج في اتّجاه يزيد احتمال الأفعال التي أعطت عائدات كبيرة، ويقلّل احتمال الأفعال التي أعطت عائدات صغيرة. حرفيًّا: هذا هو ما نريده.
خوارزميّة REINFORCE
أبسط استعمال للصيغة أعلاه، من ورقة ويليامز 1992:
- شغّل حلقة كاملة تحت ، وسجّل .
- احسب لكلّ خطوة (المجموع المخفوض للمكافآت القادمة).
- حدّث: .
import torch
import torch.nn as nn
import torch.optim as optim
import gymnasium as gym
class Politique(nn.Module):
def __init__(self, dim_etat, dim_action):
super().__init__()
self.reseau = nn.Sequential(
nn.Linear(dim_etat, 128),
nn.ReLU(),
nn.Linear(128, dim_action),
)
def forward(self, s):
logits = self.reseau(s)
return torch.distributions.Categorical(logits=logits)
env = gym.make("CartPole-v1")
politique = Politique(4, 2)
optimiseur = optim.Adam(politique.parameters(), lr=1e-3)
gamma = 0.99
for episode in range(1000):
etat, _ = env.reset()
log_probs, recompenses = [], []
done = False
while not done:
dist = politique(torch.tensor(etat, dtype=torch.float32))
action = dist.sample()
log_probs.append(dist.log_prob(action))
etat, r, term, trunc, _ = env.step(int(action))
recompenses.append(r)
done = term or trunc
# حساب G_t لكلّ خطوة
G, retours = 0, []
for r in reversed(recompenses):
G = r + gamma * G
retours.insert(0, G)
retours = torch.tensor(retours)
perte = -torch.stack([lp * G for lp, G in zip(log_probs, retours)]).sum()
optimiseur.zero_grad()
perte.backward()
optimiseur.step()
نقطة تنفيذ حاسمة: نستعمل .sample() لا .argmax(). السياسة احتماليّة، والاستكشاف يأتي مجّانًا من عيّنة التوزيع. لا حاجة إلى إبسيلون-جشعة صريحة كما في DQN.
المشكلة الكبرى: التباين
تعمل REINFORCE، لكنّها تعمل ببطء وبتذبذب واسع. السبب: تعتمد على كامل الحلقة، وتباينها ضخم، فيدخل هذا التباين مباشرة في التدرّج.
مثال ملموس: على CartPole، حلقة قد تدوم 10 خطوات (سقوط سريع) أو 500 خطوة (نجاح). العائد يتغيّر من إلى . التدرّج المستند إلى قيمة يهيمن على تدرّج قيمته ، حتّى إن كانت الأفعال في الحلقة الثانية مشابهة تمامًا لأفعال في الأولى.
الخطّ الأساسي: الحلّ الجميل
الحيلة: طرح خطّ أساسي لا يعتمد على الفعل من :
يمكن إثبات أنّ التدرّج لا يتغيّر في المتوسّط ما دام لا يعتمد على . لكنّه يمكن أن يُقلّص التباين تقليصًا هائلًا إذا اخترناه بحكمة.
خيار طبيعي: . عندها يمثّل الميزة : كم كان الفعل أفضل من المتوسّط في تلك الحالة. لا نتوقّف إلّا عند ا لحاجة إلى تحديث إذا كان الفعل أفضل من المتوسّط، والقيمة أعلاه أفضل نسبيًّا لا مطلقًا.
هذه الفكرة — تعلّم إلى جانب ، واستخدام خطًّا أساسيًّا — تُنتج الممثّل-الناقد، وستكون موضوع الوحدة التالي ة.
الأفعال المستمرّة
لا يستطيع DQN التعامل مع فضاءات أفعال مستمرّة ( على مجموعة مستمرّة ثقيل). تدرّج السياسة يتعامل معها بشكل طبيعي: نستعمل توزيعًا مستمرًّا (غاوسي عادةً) بمعاملات تعطيها الشبكة.
class PolitiqueGaussienne(nn.Module):
def __init__(self, dim_etat, dim_action):
super().__init__()
self.moyenne = nn.Sequential(
nn.Linear(dim_etat, 128), nn.ReLU(),
nn.Linear(128, dim_action),
)
self.log_ecart = nn.Parameter(torch.zeros(dim_action))
def forward(self, s):
mu = self.moyenne(s)
sigma = torch.exp(self.log_ecart)
return torch.distributions.Normal(mu, sigma)
مفيد على القيادة الذاتيّة، الروبوتيّات، وضبط عزم دوران محرّك — كلّ ما يتطلّب فعلًا يأخذ قيمة حقيقيّة لا فئويّة.
متى تدرّج السياسة، ومتى DQN
- الأفعال المستمرّة: تدرّج السياسة إجباري.
- سياسة احتماليّة مطلوبة: تدرّج السياسة (في الشطرنج والبوكر مثلًا).
- كفاءة العيّنة حرجة: DQN غالبًا (يستخدم إعادة الرجعة، عيّنات كلّ خطوة، بينما REINFORCE يستخدم كلّ حلقة مرّة واحدة ثمّ ينساها).
- بيئة بسيطة، فضاء أفعال فئوي صغير: كلاهما يعمل؛ DQN غالبًا أسرع.
قبل تطبيق تدرّج REINFORCE، طبّعوا : retours = (retours - retours.mean()) / (retours.std() + 1e-8). تعديل بسيط يُقلّص التباين تقليصًا كبيرًا، ويجعل معدّل التعلّم أقلّ حسّاسيّة للمهمّة. إسقاطه سبب شائع لتدريب لا يتعلّم.
الخلاصة
- تدرّج السياسة يُعدّل في اتّجاه يرفع احتمال الأفعال ذات العائد المرتفع؛ الاستكشاف يأتي من سياسة احتماليّة.
- REINFORCE هو النسخة الأبسط، لكن تباينه ضخم لأنّه يستعمل الكامل من الحلقة.
- الخطّ الأساسي يُقلّص التباين دون تحيّز؛ استعمال خطًّا أساسيًّا يُعطي الميزة .
- الأفعال المستمرّة حصريّة تقريبًا لعائلة تدرّج السياسة؛ وسياسة احتماليّة مفيدة في مسائل الخصم.
الوحدة التالية: الممثّل والناقد، حيث نمزج قوّة وسياسة احتماليّة في شبكتين تعمل معًا، ثمّ نبني على ذلك A2C وPPO — نقطة بداية العمل الصناعي الحديث في التعلّم المعزّز.