RLCard: 强化学习扑克游戏工具包

RLCard 是一个用于卡牌游戏强化学习的开源工具包, 为研究人员和开发者提供了一个统一的环境和接口来开发、评估和比较卡牌游戏 AI 算法。本文将对 RLCard 的主要功能和使用方法进行详细介绍。

1. RLCard 概述

RLCard 支持多种流行的卡牌游戏, 包括:

  • 黑杰克 (Blackjack)
  • Leduc Hold'em
  • 德州扑克 (Limit Hold'em 和 No-limit Hold'em)
  • 斗地主 (Doudizhu)
  • 麻将 (Mahjong)
  • UNO
  • 吉恩拉米 (Gin Rummy)
  • 桥牌 (Bridge)

RLCard 提供了统一的接口来访问这些游戏环境, 使得开发者可以方便地在不同游戏之间切换和对比算法。同时,RLCard 还内置了多种经典的强化学习算法实现, 如 DQN 、 CFR 等, 可以直接用于训练和评估。

RLCard 的主要特点包括:

  1. 统一的游戏环境接口
  2. 丰富的卡牌游戏支持
  3. 内置多种强化学习算法
  4. 灵活的评估工具
  5. 易于使用和扩展

接下来我们将通过几个具体的例子来详细介绍 RLCard 的使用方法。

2. 使用随机智能体

RLCard 提供了一个随机智能体, 可以在各个游戏环境中随机行动。下面是一个使用随机智能体的示例代码:

import rlcard
from rlcard.agents import RandomAgent
from rlcard.utils import set_seed

# 创建游戏环境
env = rlcard.make('leduc-holdem', config={'seed': 42})

# 设置随机种子
set_seed(42)

# 创建随机智能体
agent = RandomAgent(num_actions=env.num_actions)

# 设置智能体
env.set_agents([agent for _ in range(env.num_players)])

# 生成一局游戏数据
trajectories, payoffs = env.run(is_training=False)

# 打印轨迹和观察数据
print('Trajectories:', trajectories)
print('Sample raw observation:', trajectories[0][0]['raw_obs'])
print('Sample raw legal actions:', trajectories[0][0]['raw_legal_actions'])

这段代码创建了一个 Leduc Hold'em 游戏环境, 并使用随机智能体进行了一局游戏。通过打印轨迹和观察数据, 我们可以了解游戏的进行过程和状态表示。

3. 使用深度 Q 网络 (DQN) 训练智能体

RLCard 提供了 DQN 等经典强化学习算法的实现。下面是一个使用 DQN 在 21 点游戏上训练智能体的示例:

import rlcard
from rlcard.agents import DQNAgent
from rlcard.utils import (
    get_device,
    set_seed,
    tournament,
    Logger,
    plot_curve,
)

# 设置参数
num_episodes = 5000
num_eval_games = 2000
evaluate_every = 100

# 创建环境
env = rlcard.make('blackjack')
eval_env = rlcard.make('blackjack')

# 创建 DQN 智能体
agent = DQNAgent(
    num_actions=env.num_actions,
    state_shape=env.state_shape[0],
    mlp_layers=[64, 64],
    device=get_device(),
)

# 设置智能体
env.set_agents([agent])
eval_env.set_agents([agent, RandomAgent(num_actions=env.num_actions)])

# 开始训练
with Logger('experiments/blackjack_dqn_result/') as logger:
    for episode in range(num_episodes):
        # 生成训练数据
        trajectories, _ = env.run(is_training=True)

        # 训练智能体
        for ts in trajectories[0]:
            agent.feed(ts)

        # 定期评估
        if episode % evaluate_every == 0:
            logger.log_performance(
                episode,
                tournament(eval_env, num_eval_games)[0]
            )

# 绘制学习曲线
plot_curve(logger.csv_path, logger.fig_path, 'dqn')

这段代码在 21 点游戏上训练了一个 DQN 智能体。它定期评估智能体的性能, 并记录了训练过程中的奖励变化。最后, 它还绘制了学习曲线以可视化训练过程。

4. 使用 CFR 算法求解 Leduc Hold'em

对于一些较小规模的游戏, 我们可以使用反事实后悔最小化 (CFR) 等算法来求解纳什均衡。下面是一个在 Leduc Hold'em 上使用 CFR(机会采样) 的示例:

import rlcard
from rlcard.agents import CFRAgent, RandomAgent
from rlcard.utils import (
    set_seed,
    tournament,
    Logger,
    plot_curve,
)

# 设置参数
num_episodes = 5000
num_eval_games = 2000
evaluate_every = 100

# 创建环境
env = rlcard.make('leduc-holdem', config={'allow_step_back': True})
eval_env = rlcard.make('leduc-holdem')

# 创建 CFR 智能体
agent = CFRAgent(env)

# 设置智能体
eval_env.set_agents([
    agent,
    RandomAgent(num_actions=env.num_actions),
])

# 开始训练
with Logger('experiments/leduc_holdem_cfr_result/') as logger:
    for episode in range(num_episodes):
        agent.train()
        print(f'\rIteration {episode}', end='')

        # 定期评估
        if episode % evaluate_every == 0:
            agent.save() # 保存模型
            logger.log_performance(
                episode,
                tournament(eval_env, num_eval_games)[0]
            )

# 绘制学习曲线
plot_curve(logger.csv_path, logger.fig_path, 'cfr')

这段代码使用 CFR 算法在 Leduc Hold'em 上训练了一个智能体。它同样定期评估智能体的性能, 并记录了训练过程。

5. 与预训练模型对战

RLCard 还提供了一些预训练模型, 允许人类玩家与之对战。以下是一个与 Leduc Hold'em 预训练 CFR 模型对战的示例:

import rlcard
from rlcard import models
from rlcard.agents import LeducholdemHumanAgent as HumanAgent
from rlcard.utils import print_card

# 创建环境
env = rlcard.make('leduc-holdem')

# 创建智能体
human_agent = HumanAgent(env.num_actions)
cfr_agent = models.load('leduc-holdem-cfr').agents[0]

# 设置智能体
env.set_agents([human_agent, cfr_agent])

while True:
    print(">> 开始新一局游戏")

    # 运行一局游戏
    trajectories, payoffs = env.run(is_training=False)

    # 打印结果
    if payoffs[0] > 0:
        print(f'你赢了 {payoffs[0]} 筹码!')
    elif payoffs[0] == 0:
        print('平局。')
    else:
        print(f'你输了 {-payoffs[0]} 筹码!')

    # 展示 CFR 智能体的手牌
    print('=============== CFR 智能体的手牌 ===============')
    print_card(env.get_perfect_information()['hand_cards'][1])

    input("按任意键继续...")

这段代码允许人类玩家与预训练的 CFR 模型进行 Leduc Hold'em 的对战。它展示了每局游戏的结果, 并在游戏结束后显示 CFR 智能体的手牌。

6. 使用深度蒙特卡洛 (DMC) 算法训练斗地主智能体

对于大规模游戏如斗地主, 我们可以使用深度蒙特卡洛 (DMC) 等算法进行训练。以下是一个使用 DMC 训练斗地主智能体的示例:

import rlcard
from rlcard.agents.dmc_agent import DMCTrainer

# 创建环境
env = rlcard.make('doudizhu')

# 初始化 DMC 训练器
trainer = DMCTrainer(
    env,
    cuda='',
    num_actors=5,
    training_device='0',
    savedir='experiments/doudizhu_dmc_result',
    save_interval=30,
    xpid='doudizhu',
)

# 开始训练
trainer.start()

这段代码使用 DMC 算法训练了一个斗地主智能体。 DMC 算法使用多个 actor 并行生成游戏数据, 然后在 GPU 上进行集中训练。

7. 评估智能体

RLCard 提供了方便的工具来评估和比较不同的智能体。以下是一个比较 DQN 智能体和随机智能体的示例:

import rlcard
from rlcard.agents import DQNAgent, RandomAgent
from rlcard.utils import get_device, tournament

# 创建环境
env = rlcard.make('leduc-holdem')

# 创建智能体
dqn_agent = DQNAgent(
    num_actions=env.num_actions,
    state_shape=env.state_shape[0],
    mlp_layers=[64, 64],
    device=get_device(),
)
random_agent = RandomAgent(num_actions=env.num_actions)

# 加载预训练模型
dqn_agent.load('models/leduc_holdem_dqn.pth')

# 进行锦标赛评估
num_games = 10000
agents = [dqn_agent, random_agent]
payoffs = tournament(env, num_games, agents)

# 打印结果
for i, payoff in enumerate(payoffs):
    print(f'Agent {i} average payoff: {payoff}')

这段代码比较了预训练的 DQN 智能体和随机智能体在 Leduc Hold'em 上的表现。它使用锦标赛方式进行了大量对局, 并计算了每个智能体的平均收益。

8. 总结

RLCard 为卡牌游戏强化学习提供了一个强大而灵活的平台。它支持多种流行的卡牌游戏, 提供了统一的接口和丰富的工具, 使得研究人员和开发者可以方便地开发、训练和评估卡牌游戏 AI 。

本文通过多个具体示例介绍了 RLCard 的主要功能, 包括:

  1. 使用随机智能体
  2. 使用 DQN 算法训练智能体
  3. 使用 CFR 算法求解小规模游戏
  4. 与预训练模型对战
  5. 使用 DMC 算法训练大规模游戏智能体
  6. 评估和比较不同智能体

这些例子涵盖了 RLCard 的核心功能, 展示了它在卡牌游戏 AI 研究和开发中的强大能力。研究人员和开发者可以基于这些示例, 进一步探索和开发更先进的卡牌游戏 AI 算法。

参考文献

  1. Zha, D. , Lai, K. H., Cao, Y., Huang, S., Wei, R., Guo, J., & Hu, X. (2019). RLCard: A Toolkit for Reinforcement Learning in Card Games. arXiv preprint arXiv:1910.04376.
  2. Heinrich, J. , & Silver, D. (2016). Deep reinforcement learning from self-play in imperfect-information games. arXiv preprint arXiv:1603.01121.
  3. Brown, N. , & Sandholm, T. (2019). Superhuman AI for multiplayer poker. Science, 365(6456), 885-890.
  4. Moravčík, M. , Schmid, M., Burch, N., Lisý, V., Morrill, D., Bard, N., … & Bowling, M. (2017). DeepStack: Expert-level artificial intelligence in heads-up no-limit poker. Science, 356(6337), 508-513.
  5. Silver, D. , Huang, A., Maddison, C. J., Guez, A., Sifre, L., Van Den Driessche, G., … & Hassabis, D. (2016). Mastering the game of Go with deep neural networks and tree search. nature, 529(7587), 484-489.

发表评论