Skip to content

fix(rl): credit hit reward to the action that caused the collision#6

Open
GERD0GDU wants to merge 1 commit into
mainfrom
claude/add-progress-tracking-PXfJh
Open

fix(rl): credit hit reward to the action that caused the collision#6
GERD0GDU wants to merge 1 commit into
mainfrom
claude/add-progress-tracking-PXfJh

Conversation

@GERD0GDU

Copy link
Copy Markdown
Owner

Sorun

RL ajanı (AIReinforcementAgent) sürekli yukarı veya aşağı yöne yığılıyor, topu takip etmeyi öğrenmiyor. Önceki PR'da (#5 / Faz 3.5) Xavier init + baseline + hiperparametre ayarları denendi ama collapse çözülmedi.

Asıl kök neden bir off-by-one credit assignment hatası:

GameSimulator.Update() içinde sıralama şudur:

  1. UpdateBall(dt) — top hareket eder, paddle ile çarpışma kontrol edilir → çarpışma varsa paddle.HasHitBall = true
  2. UpdatePaddles(dt) — paddle bu frame'in action'ı ile hareket eder

Yani frame N'de HasHitBall=true görüldüğünde, çarpışma paddle'ın action N-1 sonrası pozisyonu ile gerçekleşti — bu frame'de Decide()'da seçilen action N henüz paddle'a uygulanmadan önce.

Ama MainWindow.UpdateRL:

if (paddle.HasHitBall)
    rl.RegisterReward(+1.0);

RegisterReward, _episodeBuffer[Count-1]'e yazıyordu — bu da bu frame'de Decide()'da az önce buffer'a eklenen action N. Yani topla alakası olmayan bir action'a kredi veriliyordu.

Vanilla REINFORCE'da tek pozitif sinyal hit reward'ı olduğu için, bu sinyal sürekli rastgele action'lara dağıtılınca politika kararlı bir yön (sürekli yukarı/aşağı) öğrenmeye yöneliyor — kollaps.

Çözüm

AIReinforcementAgent'a yeni metod ekledim:

public void RegisterRewardForPreviousAction(double reward)
{
    if (_episodeBuffer.Count < 2)
        return;

    _episodeBuffer[_episodeBuffer.Count - 2].Reward += reward;
}

MainWindow.UpdateRL'de hit reward bu metodu kullanıyor. Terminal reward (EndEpisode içinden çağrılan RegisterReward) hâlâ son action'a yazıyor — bu doğru, çünkü kaçırılan top için suçlu son action'tır.

Değişen dosyalar

  • src/PingPongAI.AI/Agents/AIReinforcementAgent.cs — yeni RegisterRewardForPreviousAction metodu
  • src/PingPongAI.App/MainWindow.xaml.csUpdateRL içinde tek satır değişiklik

Test planı

  • VS2022'de derle (warning/error olmamalı)
  • weights/left.json ve weights/right.json varsa SİL (eski politika yanlış kredilemeyle eğitilmiş, baştan başlamak gerek)
  • RL vs Rule-Based çalıştır, 5–10 dk gözlemle: paddle topu takip etmeye başlamalı, sadece bir yöne yığılmamalı
  • RL vs Supervised AI çalıştır: skor farkı en azından zamanla daralmalı
  • Bir sezgi: collapse hâlâ olursa, sıradaki adım entropy regularization eklemek olur

Generated by Claude Code

GameSimulator.Update runs UpdateBall (which sets paddle.HasHitBall)
before UpdatePaddles applies the current frame's action. When
HasHitBall is true in frame N, the collision happened with the
paddle position established by action N-1, not the action just
buffered in this frame's Decide().

RegisterReward(+1) was attaching the only positive signal to
buffer[Count-1] — the unrelated action just decided — turning the
hit reward into pure noise and explaining the persistent policy
collapse (paddle always drifts up or down without learning to
track the ball).

Add RegisterRewardForPreviousAction that writes to buffer[Count-2]
and use it for the hit-step reward. Terminal reward in EndEpisode
still uses the last action (correct: it credits the action that
preceded the miss).

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014E7V6Etbi1qzrTDpFbtsp2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants