التعلم المعزز
“وكيل يتعلم بالفعل — تعظيم المكافأة التراكمية من خلال التفاعل بالتجربة والخطأ”
صياغة MDP ومعادلات Bellman وQ-learning والشبكات DQN وتدرجات السياسة وPPO — مع تصور تفاعلي يُظهر تقارب قيم Q عبر 200 حلقة.
المتطلبات الأساسية
المفاهيم المغطاة
∑الصيغ الرئيسية
معادلة بيلمان
قيمة Q المثلى: المكافأة الفورية + أفضل قيمة مستقبلية مخصومة. الهدف العودي الذي يتقارب إليه Q-learning
تحديث Q-Learning
تحريك التقدير الحالي نحو هدف بيلمان بخطوة α (التعلم بالفرق الزمني)
تدرج السياسة (REINFORCE)
زيادة احتمال الأفعال التي أدت إلى عوائد عالية، وتقليله للأفعال ذات العوائد المنخفضة
هدف PPO مع القطع
تحسين السياسة القريبة: يقطع نسبة تحديث السياسة لتبقى في [1-ε, 1+ε] — تدريب مستقر بالدُّفعات الكبيرة
▶محاكاة تفاعلية
التعلم بالممارسة — نموذج التعلم التعزيزي
يحتاج التعلم الخاضع للإشراف إلى أمثلة مُعلَّمة. يحتاج التعلم التعزيزي فقط إلى إشارة مكافأة — ردود فعل على ما إذا كان الفعل جيداً أم سيئاً. هكذا يتعلم البشر المشي واللعب والقيادة: من خلال الممارسة والتغذية الراجعة والتحسين التدريجي للاستراتيجية. نجاحات RL: هزم AlphaGo بطل العالم في Go (2016) — دُرِّب بـRL بعد تدريب مسبق خاضع للإشراف. يستخدم ChatGPT / GPT-4 RLHF لمحاذاة مخرجات النموذج مع التفضيلات البشرية. تُدرّب أنظمة التلاعب الروبوتي سياساتها في المحاكاة ثم تنقلها إلى الأجهزة الحقيقية.
تعلّم AlphaZero من DeepMind الشطرنج والغو والشوغي على المستوى فوق البشري في 24 ساعة من اللعب الذاتي — دون سجلات ألعاب بشرية، تعلم تعزيزي خالص من اللعب العشوائي ومكافأة الفوز.
إطار عمل RL: الوكيل، البيئة، MDP
**عملية قرار ماركوف (MDP):** (S, A, T, R, γ) — حالات S، أفعال A، دالة انتقال T(s'|s,a)، مكافأة R(s,a,s')، خصم γ∈[0,1]. **الوكيل:** في كل خطوة زمنية t، يلاحظ الحالة sₜ، يتخذ الفعل aₜ وفق السياسة π(aₜ|sₜ)، يتلقى المكافأة rₜ. **الهدف:** إيجاد السياسة π* التي تُعظّم العائد المخصوم المتوقع Gₜ = Σᵢ γⁱrₜ₊ᵢ. **دالة Q(s,a):** العائد المتوقع بدءاً من الحالة s مع اتخاذ الفعل a ثم اتباع السياسة المثلى. **تمييز رئيسي:** RL بدون نموذج (Q-learning, PPO) يتعلم مباشرةً من التفاعل دون معرفة T. RL بنموذج (Dyna, MuZero) يتعلم نموذج عالم T̂ ويخطط في الخيال.
يتحكم معامل الخصم γ في قصر النظر: γ=0.99 يجعل الوكيل يهتم بالمكافآت 100 خطوة في المستقبل؛ γ=0 جشع بحت. معظم المسائل تحتاج γ∈[0.95, 0.999].
التعلم بـQ: الجدولي والعميق (DQN)
ابدأ جدول Q: Q(s,a)=0 لجميع أزواج الحالة-الفعل (جدولي) أو شبكة Q ذات معاملات θ (DQN).
لكل حلقة: أعِد تهيئة البيئة، لاحظ الحالة الأولية s.
اختيار الفعل ε-جشع: باحتمال ε اختر فعلاً عشوائياً (استكشاف)، وإلا اختر argmax_a Q(s,a) (استغلال). قلّص ε من 1.0 → 0.05 خلال التدريب.
نفّذ الفعل a، لاحظ المكافأة r والحالة التالية s'. خزّن (s,a,r,s') في ذاكرة التشغيل (DQN).
تحديث TD: Q(s,a) ← Q(s,a) + α[r + γ·max_a' Q(s',a') - Q(s,a)].
إضافات DQN: (1) إعادة تشغيل التجربة — دُفعات عشوائية لكسر الارتباطات. (2) الشبكة المستهدفة — نسخة مجمّدة Q_هدف(θ⁻)، تُزامن كل N خطوة. (3) DQN المزدوج — فصل اختيار الفعل عن تقدير القيمة لتقليل المبالغة.
التقارب: يتقارب Q-learning الجدولي إلى Q* للـMDPs المحدودة مع استكشاف كافٍ. شبكات Q العصبية غير مضمونة لكنها تعمل جيداً عملياً.
تعلم Q وDQN من الصفر
import numpy as np import gymnasium as gym from collections import deque import torch, torch.nn as nn, torch.optim as optim class="tok-comment"># ── class="tok-num">1. Tabular Q-Learning (FrozenLake) ─────────────────────────────────────── env = gym.make(class="tok-str">"FrozenLake-v1", is_slippery=False) n_states, n_actions = env.observation_space.n, env.action_space.n Q = np.zeros((n_states, n_actions)) alpha = class="tok-num">0.8 class="tok-comment"># learning rate gamma = class="tok-num">0.95 class="tok-comment"># discount epsilon = class="tok-num">1.0 class="tok-comment"># exploration rate for episode in range(class="tok-num">2000): s, _ = env.reset() done = False while not done: class="tok-comment"># ε-greedy if np.random.random() < epsilon: a = env.action_space.sample() else: a = np.argmax(Q[s]) s_next, r, terminated, truncated, _ = env.step(a) done = terminated or truncated class="tok-comment"># Q-learning update (Bellman target) td_target = r + gamma * np.max(Q[s_next]) * (class="tok-num">1 - terminated) Q[s, a] += alpha * (td_target - Q[s, a]) s = s_next epsilon = max(class="tok-num">0.01, epsilon * class="tok-num">0.999) class="tok-comment"># decay exploration class="tok-comment"># Evaluate greedy policy n_wins = class="tok-num">0 for _ in range(class="tok-num">100): s, _ = env.reset() done = False while not done: a = np.argmax(Q[s]) s, r, terminated, truncated, _ = env.step(a) done = terminated or truncated if r == class="tok-num">1.0: class="tok-comment"># reached the goal n_wins += class="tok-num">1 print(fclass="tok-str">"Win rate: {n_wins/class="tok-num">100:.class="tok-num">0%}") class="tok-comment"># ── class="tok-num">2. Deep Q-Network (CartPole) ───────────────────────────────────────────── class DQN(nn.Module): def __init__(self, obs_dim, n_actions): super().__init__() self.net = nn.Sequential( nn.Linear(obs_dim, class="tok-num">128), nn.ReLU(), nn.Linear(class="tok-num">128, class="tok-num">128), nn.ReLU(), nn.Linear(class="tok-num">128, n_actions) ) def forward(self, x): return self.net(x) env = gym.make(class="tok-str">"CartPole-v1") obs_dim = env.observation_space.shape[class="tok-num">0] n_actions = env.action_space.n q_net = DQN(obs_dim, n_actions) q_target = DQN(obs_dim, n_actions) class="tok-comment"># frozen target network q_target.load_state_dict(q_net.state_dict()) optimizer = optim.Adam(q_net.parameters(), lr=class="tok-num">1e-3) replay = deque(maxlen=10_000) class="tok-comment"># experience replay buffer gamma = class="tok-num">0.99 epsilon = class="tok-num">1.0 batch_size = class="tok-num">64 target_update_freq = class="tok-num">100 steps = class="tok-num">0 for episode in range(class="tok-num">500): s, _ = env.reset() total_reward = class="tok-num">0 done = False while not done: class="tok-comment"># ε-greedy action if np.random.random() < epsilon: a = env.action_space.sample() else: with torch.no_grad(): a = q_net(torch.FloatTensor(s)).argmax().item() s_next, r, terminated, truncated, _ = env.step(a) done = terminated or truncated replay.append((s, a, r, s_next, terminated)) s = s_next; total_reward += r; steps += class="tok-num">1 class="tok-comment"># Train when buffer has enough samples if len(replay) >= batch_size: batch = [replay[i] for i in np.random.choice(len(replay), batch_size, replace=False)] S, A, R, S_next, D = map(np.array, zip(*batch)) S_t = torch.FloatTensor(S); A_t = torch.LongTensor(A) R_t = torch.FloatTensor(R); S_next_t = torch.FloatTensor(S_next) D_t = torch.FloatTensor(D) with torch.no_grad(): max_next_q = q_target(S_next_t).max(class="tok-num">1)[class="tok-num">0] target = R_t + gamma * max_next_q * (class="tok-num">1 - D_t) current_q = q_net(S_t).gather(class="tok-num">1, A_t.unsqueeze(class="tok-num">1)).squeeze() loss = nn.functional.mse_loss(current_q, target) optimizer.zero_grad(); loss.backward(); optimizer.step() if steps % target_update_freq == class="tok-num">0: q_target.load_state_dict(q_net.state_dict()) epsilon = max(class="tok-num">0.05, epsilon * class="tok-num">0.995) if episode % class="tok-num">50 == class="tok-num">0: print(fclass="tok-str">"Episode {episode:4d} | reward={total_reward:class="tok-num">5.0f} | ε={epsilon:.3f}")
تدرج السياسة والفاعل-الناقد (A2C/PPO)
تُحسّن أساليب تدرج السياسة مباشرةً السياسةَ π_θ بدلاً من دالة قيمة. تستخدم بنية الفاعل-الناقد شبكتين: الفاعل π_θ يختار الأفعال، والناقد V_φ يُقدّر قيم الحالة كخط أساسي لتقليل تباين التدرج. تُضيف PPO (تحسين السياسة القريبة) آلية قطع لمنع تحديثات السياسة المدمرة الكبيرة — نسبة r_t(θ) = π_θ(a|s)/π_θ_القديمة(a|s) مقطوعة إلى [1-ε, 1+ε]. يجعل هذا PPO كافياً في كفاءة العينات للاستخدام العملي وهو الخوارزمية القياسية في RLHF لـLLMs.
الثالوث المميت وأوضاع فشل RL الشائعة
الثالوث المميت (Sutton & Barto): الجمع بين (1) تقريب الدوال (الشبكات العصبية)، (2) الإقلاع (تحديثات TD)، و(3) التعلم خارج السياسة قد يُسبّب التباعد. يتجنب DQN هذا بذاكرة التشغيل والشبكات المستهدفة لكن التدريب قد يظل غير مستقر. مخاطر RL العملية: (1) تشكيل المكافآت قد يُدخل اختصارات غير مقصودة — وكيل سباق القوارب الذي تعلّم الدوران في دوائر لجمع المكافآت. (2) المكافآت النادرة تجعل الاستكشاف شبه مستحيل — استخدم الدافعية الداخلية بحذر. (3) الفجوة بين المحاكاة والواقع — السياسات المدرّبة في المحاكاة تفشل على الروبوتات الحقيقية بسبب الفيزياء غير المُنمذجة. (4) التقييم بنقاط ابتداء ثابتة مضلِّل — أبلغ عن المتوسط ± الانحراف المعياري عبر 10+ نقاط ابتداء.
تعلّم وكيل سباق القوارب من OpenAI المدرَّب بمكافآت مُشكَّلة القيادةَ في دوائر لجمع العناصر بدلاً من إنهاء السباق — حالة فشل شهيرة لاختراق المكافأة.
?اختبار المعرفة
يتم حفظ التقدم في متصفحك — لا حاجة لحساب.