为何我的DQN智能体训练效率极低?井字棋训练无进展求助
训练DQN井字棋后手智能体无进展的问题排查
我尝试用tf-agents里的DQN智能体训练井字棋后手(先手随机落子),但训练效率极低。练了10万步模型完全没提升,虽说不至于现在就完成训练,但至少该有一点效果才对。找不到代码问题,相关代码如下:
LOG_PERIOD = 1000 PRINT_PERIOD = 100 LEARNING_RATE = 0.001 NUM_ITERATIONS = 100_000 graph = Graphic(LOG_PERIOD) tf_env = TFPyEnvironment(RandomTicTacToeEnvironment()) q_net = QNetwork( tf_env.observation_spec(), tf_env.action_spec(), fc_layer_params=(100,) ) train_step_counter = tf.Variable(0) agent = DqnAgent( time_step_spec=tf_env.time_step_spec(), action_spec=tf_env.action_spec(), q_network=q_net, optimizer=Adam(learning_rate=LEARNING_RATE), td_errors_loss_fn=common.element_wise_squared_loss, epsilon_greedy=0.1, train_step_counter=train_step_counter ) agent.initialize() eval_policy = agent.policy collect_policy = agent.collect_policy replay_buffer = tf_uniform_replay_buffer.TFUniformReplayBuffer( data_spec=agent.collect_data_spec, batch_size=tf_env.batch_size, max_length=1000 ) collect_driver = dynamic_step_driver.DynamicStepDriver( tf_env, collect_policy, observers=[replay_buffer.add_batch], num_steps=10 ) collect_driver.run = common.function(collect_driver.run) agent.train = common.function(agent.train) initial_collect_policy = random_tf_policy.RandomTFPolicy( tf_env.time_step_spec(), tf_env.action_spec() ) dataset = replay_buffer.as_dataset( num_parallel_calls=3, sample_batch_size=8, num_steps=2, single_deterministic_pass=False ).prefetch(3) iterator = iter(dataset) dynamic_step_driver.DynamicStepDriver( tf_env, initial_collect_policy, observers=[replay_buffer.add_batch], num_steps=10 ) time_step = tf_env.reset() for _ in np.arange(NUM_ITERATIONS+1): time_step, _ = collect_driver.run(time_step) experience, _ = next(iterator) step = agent.train_step_counter.numpy() train_loss = agent.train(experience).loss if step % PRINT_PERIOD == 0: print('step = {0}: loss = {1}'.format(step, train_loss)) for reward in tf.reshape(experience.reward, [-1]): graph.check(step, reward)
完整项目代码可在Colab环境中查看。
核心问题排查
- 初始化经验回放池未执行:你创建了用随机策略填充回放池的
DynamicStepDriver,但没有调用run()方法执行初始化。回放池初始为空,训练初期只能采样无效数据,直接导致模型无法学习。 - 经验回放池容量不足:1000的容量太小,无法存储足够多样的井字棋状态经验,容易造成训练数据重复、模型过拟合。建议调整到5000-10000。
- Q网络结构过于简单:仅一层100神经元的全连接层,难以捕捉井字棋的空间逻辑(比如三子连线的模式)。可以改为两层全连接(例如
fc_layer_params=(256, 128)),或者加入卷积层提取棋盘的空间特征。 - 训练数据采样参数错误:
as_dataset中num_steps=2是多步TD学习配置,但DQN默认使用单步TD误差。建议改为num_steps=1,否则采样的经验格式与DQN训练逻辑不匹配。 - 训练与收集节奏失衡:每次收集10步就训练一次,训练频率过高,模型还未稳定学习到特征就被新数据覆盖。可以改为收集多步后训练多次,或者调整收集步长。
- 稀疏奖励问题:如果奖励仅设置为赢(+1)、输(-1)、平(0),稀疏的奖励信号会让DQN难以获取有效学习梯度。可以加入中间奖励,比如阻止对手形成连线时给予小奖励,加快学习信号传递。
内容的提问来源于stack exchange,提问作者Karasic
相关产品推荐
相关产品推荐

