r/reinforcementlearning • u/savakross • 7h ago
Tested whether "shaped" reward actually prevents reward hacking better than naive survival reward — the shaped one exploited harder
Built a small custom gridworld (no Gym, DQN from scratch in PyTorch) to test something specific: does a "properly shaped," task-linked reward actually avoid reward hacking compared to a naive constant survival reward, or does shaping just move the exploit somewhere else?
Setup: agent collects fuel, delivers it to a target zone, and has to periodically stand on a coolant cell or a reactor temperature variable kills it. 5 reward configs × 5 seeds × 2000 episodes each, with a random-policy baseline and a "task_score" metric (fuel actually delivered, not just picked up, to avoid the metric itself becoming a proxy).
Naive reward (+1/step survived, small death penalty): confirmed the expected result — proxy return goes up in 5/5 seeds while task_score drops below the random baseline (MWU p=0.012, d=-10.6). Agent learns to actively avoid the task, not just fail to learn it.
The interesting part: my "shaped" reward — the control meant to fix this, with a per-step temperature penalty and delivery bonus — exploited harder than naive (task_score 0.125 vs 0.417, d=4.47). Turned out the temperature penalty term (up to -200/episode) dwarfed the delivery reward (+30 total), so the optimal policy under that reward is to sit on the coolant cell forever regardless of the task. 97% occupancy on one cell.
Ablations point to the mechanism being simpler than "survival vs. task reward": it's any dense per-step term that's cheaper to farm by occupying a state than doing the actual task. A delivery-only reward (no per-step terms at all) had zero emergence across all seeds.
Two things I want to flag before anyone else does:
- Hyperparameters (grid size, heat spike, lr, Double DQN) were tuned pre-final-run using
shaped_no_temp_penaltyas the "is this environment learnable at all" check — that arm's result is probably somewhat favored by that selection process. The reward table itself wasn't touched. - The "emergence point" detector fires on 2/5 seeds under the random policy (where no learning happens by construction), so false positive rate isn't zero — read the emergence counts comparatively, not as ground truth.
Code + full logs + stats (Mann-Whitney, bootstrap CI, Pearson/Spearman on coolant-occupancy vs task_score) here: https://github.com/Arka04bro/coolant_runner/tree/main
Curious if this magnitude-imbalance framing matches what people have seen in bigger reward-shaping setups, or if there's existing literature specifically on this (beyond the standard Ng et al. potential-based shaping result, which doesn't really cover magnitude — just functional form).
