DQN训练CartPole-v1 1000轮无提升,求代码问题排查及优化方案
DQN CartPole-v1训练不收敛问题排查
你的代码存在多处核心逻辑错误,不是训练轮次不足的问题,修改后200个episode以内即可收敛,具体问题如下:
- 目标Q值终止条件判断错误
代码中计算采样样本的目标Q值时,使用的是当前交互步的done状态,而非采样样本自身的done_m状态:
这会导致所有采样样本的终止判断都和当前交互步一致,非终止样本的未来奖励被错误丢弃,Q值计算完全失真。# 错误写法 if done: Q[0,action] = reward_m else: Q_new = model.predict(preprocessing(state_next_m)) Q[0,action] = reward_m + 0.97*np.max(Q_new) - 目标Q值的基底选择错误
你在构造目标Q值时,所有采样样本都共用当前交互步状态预测出的Q作为基底,只修改同一个action位置的值,而非每个样本单独预测对应state_m的Q值、修改对应action_m的位置。这会导致所有样本的目标Q值完全错误,网络学习不到正确的映射关系。 - 缺失目标网络,训练不稳定
标准DQN需要单独维护一个固定参数的目标网络来计算未来奖励的Q值,你现在计算Q_new和训练用的是同一个实时更新的网络,Q值目标是不断移动的靶,训练会持续震荡无法收敛。 - 训练频率和轮次设置不合理
你每走一步环境就采样批次训练5个epoch,训练频率过高且单批次训练轮次过多,非常容易让网络过拟合到近期样本,遗忘之前学到的有效策略。 - 不必要的模型保存操作
每个episode一开始就保存模型,此时模型还没经过当前episode的训练,保存的是上一轮的旧权重,无实际意义。
核心修改建议
- 修正Q值计算逻辑:对每个采样样本,单独预测其
state_m对应的Q值,使用样本自身的done_m判断是否终止,修改对应action_m位置的Q值作为训练目标。 - 增加目标网络:每隔N步将主网络的权重同步到目标网络,计算
Q_new时使用目标网络而非主网络。 - 调整训练策略:等经验回放池积累到至少等于批次大小的样本后再开始训练,每走N步环境训练一次,每次训练1个epoch即可。
- 可优化epsilon衰减:最低降到0.01后停止衰减,避免后期探索率过高影响最优策略的发挥。
内容的提问来源于stack exchange,提问作者Jeongjin Shin
相关产品推荐
相关产品推荐

