You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 08:25:33