超参数优化后奖励值为NaN问题求助(Ray、Gym)
解决HyperOpt调参时episode_reward_mean全为NaN的问题
针对你用Ray Tune+HyperOpt在自定义Gym环境调PPO超参数时,所有迭代的奖励值都是NaN的问题,整理几个直接的排查和修复方向:
1. 修复超参数配置冲突
你的参数里存在明显逻辑冲突,会直接导致PPO训练异常:
sgd_minibatch_size=1000远大于train_batch_size=200:PPO的小批量大小不能超过总训练批次大小,这会引发内部错误、中断训练,自然无法生成有效奖励数据。num_sgd_iter=100过大:过高的迭代次数容易导致训练发散,出现NaN损失,进而影响奖励统计。
修改示例:
config = { "env": "affecta", "sgd_minibatch_size": 100, # 设为小于等于train_batch_size的数值 "num_sgd_iter": 15, # 先调低到10-20的合理范围 "lr": tune.uniform(5e-6, 5e-2), "lambda": tune.uniform(0.6, 0.99), "vf_loss_coeff": tune.uniform(0.6, 0.99), "kl_target": tune.uniform(0.001, 0.01), "kl_coeff": tune.uniform(0.5, 0.99), "entropy_coeff": tune.uniform(0.001, 0.01), "clip_param": tune.uniform(0.4, 0.99), "train_batch_size": 200, "monitor": True, # 打开monitor,让Ray正确收集奖励统计 "num_workers": 6, "num_gpus": 0, }
2. 确保环境返回有效奖励
检查自定义Gym环境的step函数:
- 每一步返回的
reward必须是int或float类型,不能是None或非数值。 - 终端状态(
done=True时)必须返回明确的奖励值,不能遗漏。 - 单独运行环境测试,确认能正常输出奖励,排除环境本身的问题。
3. 调整Ray Tune的配置
- 去掉
config = explore(config):这个探索函数可能会修改你的配置参数导致异常,先直接用原始配置测试。 - 调高训练迭代次数:
stop={"training_iteration":3}次数太少,可能还没完成一个完整episode,改成training_iteration: 10以上。 - 统一指标配置:要么在
HyperOptSearch里指定metric和mode,要么在TuneConfig里设置,避免混淆。
修改后的Tuner配置示例:
# 去掉explore(config),直接使用原始config optimizer = HyperOptSearch(metric="episode_reward_mean", mode="max", n_initial_points=20, random_state_seed=7, space=config) tuner = tune.Tuner( "PPO", tune_config=tune.TuneConfig( search_alg=optimizer, num_samples=10, ), run_config=air.RunConfig(stop={"training_iteration": 10}, local_dir="test_avec_inoffensifs"), ) results = tuner.fit()
4. 检查日志排查错误
查看local_dir指定的日志目录里的训练日志,搜索NaN或error关键词,确认是否有训练过程中的报错(比如损失NaN、环境交互错误等),这些都会导致奖励统计失败。
内容的提问来源于stack exchange,提问作者Clm28
相关产品推荐
相关产品推荐

