引言

强化学习(Reinforcement Learning)是机器学习中的一个跨学科领域。由于它近年来在 Go 等游戏以及 自动驾驶汽车 等现实应用中的成功表现,它在过去十年间获得了广泛关注。这一增长也恰逢现代 GPU 的快速发展以及机器学习技术的不断演进。我们已经进入了机器能够轻松在电脑游戏中超越人类的阶段。深度 Q 网络(Deep Q-Network,简称 DQN)是一种新的强化学习算法,在处理 Atari 等电子游戏方面展现出巨大潜力,因为这些游戏通常具有高维状态空间,并需要长期规划能力。本教程将解释 DQN 的工作原理,并展示它如何有效解决 Gymnasium 的 Lunar Lander 环境。Gymnasium 的前身是 OpenAI Gym。

什么是强化学习?

强化学习整体循环结构示意图

强化学习(Reinforcement Learning,RL)是指智能体(agent)通过在环境中执行动作来进行决策,并以最大化累计奖励为目标的学习过程。强化学习的关键组成部分包括:

  • 智能体(Agent):与环境互动并进行决策的主体。
  • 环境(Environment):智能体所交互的外部系统。
  • 状态(State, S):环境当前的情况或配置。
  • 动作(Action, A):智能体可以采取的可能行为或决策。
  • 奖励(Reward, R):环境针对某个动作所给予的反馈,用以表示该动作的好坏。
  • 策略(Policy, π):将状态映射到动作的策略,用以定义智能体的行为方式。
  • 价值函数(Value Function, V):估计从某一状态开始所能获得的预期累计奖励。
  • Q 函数(Q-Function, Q):估计在给定状态下采取某个特定动作后所能获得的预期累计奖励。

强化学习的运作方式

  1. 初始化(Initialization):智能体一开始对环境没有或仅有极少的了解。
  2. 互动(Interaction):智能体依据其策略采取行动,并与环境进行互动。
  3. 反馈(Feedback):环境会针对每个动作返回新的状态以及对应的奖励。
  4. 学习(Learning):智能体会根据所获得的奖励更新其策略和/或价值函数,以改善未来的决策表现。

关键概念

  • 探索(Exploration)与利用(Exploitation):在尝试新的动作与利用已知高回报动作之间取得平衡。
  • 折扣因子(Discount Factor, γ\gamma:用于决定未来奖励相对于即时奖励的重要程度。
  • 贝尔曼方程(Bellman Equation):描述某一状态的价值与其后续状态价值之间的关系。

贝尔曼方程(Bellman Equation)

贝尔曼方程是强化学习中的核心基础,它对价值函数提供了一种递归式分解方式。该方程将某一状态的价值与后续状态的价值联系起来。Q 函数的贝尔曼方程如下:

Q(s,a)=r+γmaxaQ(s,a)Q(s, a)=r+\gamma \max_{a'} Q(s', a')

其中:

  • Q(s,a)Q(s, a) 表示在状态 ss 下采取动作 aa 的 Q 值。
  • rr 表示执行动作 aa 后获得的奖励。
  • γ\gamma 表示折扣因子,用于决定未来奖励的重要程度。
  • maxaQ(s,a)\max_{a'} Q(s', a') 表示在下一个状态 ss' 中,所有可能动作 aa' 所对应的最大 Q 值。

时间差学习(Temporal Difference Learning)

时间差(TD)学习是强化学习中的一种关键方法,它结合了动态规划(Dynamic Programming)与蒙特卡洛方法(Monte Carlo Methods)的思想。TD 学习会根据预测值与实际获得的奖励加上下一个状态折扣价值之间的差异,也就是“时间差”,来更新价值函数。

Q-learning(Q 学习)作为 TD 学习的一种,其更新规则如下:

Q(s,a)Q(s,a)+α(r+γmaxaQ(s,a)Q(s,a))Q(s, a) \leftarrow Q(s, a) + \alpha \left( r + \gamma \max_{a'} Q(s', a') - Q(s, a) \right)

其中:

  • α\alpha 表示学习率(learning rate),用于控制新信息覆盖旧信息的程度。
  • r+γmaxaQ(s,a)r+\gamma \max_{a'} Q(s',a') 表示当前 Q 值的目标值,它结合了即时奖励以及对未来奖励的估计。

强化学习是一种用于解决复杂决策问题的强大框架。该框架通过与环境之间不断进行试错式互动,逐步学习出最优策略。

DQN 的运作方式

深度 Q 网络(Deep Q-Network,DQN)将 Q 学习(Q-learning)与深度神经网络(Deep Neural Networks)相结合,以处理具有大量状态与动作的复杂环境。

解释 DQN 训练循环、经验回放和目标网络的图示

从经验中学习(Learning from Experience)

Q 学习(Q-learning)是一种强化学习算法,其中智能体通过与环境互动来学习如何最大化奖励。它使用 Q 函数 Q(s,a)Q(s, a) 来预测未来奖励。智能体会利用贝尔曼方程更新 Q 值,并根据所获得的奖励以及对未来奖励的预期来调整其预测。

实际示例(Practical Example)

假设智能体当前处于状态 ss,并预测 Q(s,a)=100Q(s, a)=100。在执行动作 aa 后,智能体转移到状态 ss',并获得奖励 8。在状态 ss' 中,最佳动作的 Q 值为 95,折扣因子为 0.99。则时间差(Temporal Difference)为:

8+0.99×95100=2.058 + 0.99 \times 95 - 100 = 2.05

若学习率为 0.1,则更新后的 Q 值为:

100+0.1×2.05=100.205100 + 0.1 \times 2.05 = 100.205

深度 Q 学习(Deep Q-Learning)

传统的 Q 学习使用表格来储存 Q 值,但对于具有大量状态与动作的环境而言,这种方式并不可行。DQN 使用神经网络来近似 Q(s,a)Q(s, a),使智能体能够对未见过的状态—动作组合进行泛化。神经网络的输入为观测值(observation),输出则是每个可能动作对应的 Q 值。

DQN 算法

  1. 经验回放:将经验 (s,a,r,s)(s, a, r, s') 储存在回放缓冲区中。通过从缓冲区中随机抽样,可以打破时间上的相关性,使学习过程更加稳定。
  2. 目标网络:使用两个神经网络:主网络用于决策,目标网络则用于提供稳定的 Q 值目标。
  3. 训练步骤

初始化回放缓冲区与神经网络。

对于每个回合:

初始化起始状态。

对于每一步:

  1. 使用 ϵ\epsilon-greedy 策略选择动作 aa
  2. 执行动作,并观察奖励 rr 与下一个状态 ss'
  3. 将经验储存至回放缓冲区。
  4. 从回放缓冲区中抽取小批量样本。
  5. 计算目标 Q 值,并对损失函数执行梯度下降。
  6. 定期更新目标网络。

稳定性增强方法

为了确保训练过程的稳定性与收敛性,通常会采用以下几种增强机制:

  1. ϵ\epsilon-greedy 动作选择:通过随时间动态调整探索率,在“探索”与“利用”之间取得平衡。
  2. 经验回放:允许模型从过去经验所组成的批次数据中学习,以确保训练更加稳定,并提升收敛效果。
  3. 目标网络与本地网络:使用目标网络来提供稳定的 Q 值目标,从而减少训练过程中的震荡与发散问题。

目标网络与本地网络

在 DQN 中,会使用两个网络来稳定学习过程:

  • 本地网络:该网络会持续进行更新,并在训练过程中用于选择动作。它通过最小化预测 Q 值与目标 Q 值之间的损失来进行学习。
  • 目标网络:该网络用于为 Q 值更新提供稳定的目标。与本地网络不同,目标网络的权重更新频率较低,通常会每隔数千步复制一次本地网络的权重。

为什么要使用两个网络?

  1. 稳定性:本地网络的权重会频繁更新,这可能导致训练过程出现不稳定甚至发散的问题。通过使用目标网络来提供稳定的 Q 值目标,可以避免学习过程中的剧烈震荡。
  2. 一致性:目标网络由于仅会定期更新,因此能够维持较一致的学习目标。这使得 Q 值更新能够基于更稳定且更可靠的目标进行,从而让学习过程更加平稳与稳定。

更新机制

  1. 本地网络更新:在每次执行动作后,本地网络会根据预测 Q 值与目标网络所提供的目标 Q 值之间的差异所计算出的损失,来更新自身权重。
  2. 目标网络更新:每隔数千步,本地网络的权重会被复制到目标网络中,以确保目标网络在一定步数内都能提供稳定的学习目标,直到下一次更新为止。
Lunar Lander 场景,标注了着陆器以及左、右、下推进器的箭头,还有一条通向两面旗帜之间着陆点的曲线路径

以下是一个详细的代码示例

步骤 1:安装所需库
pip install swig gymnasium gymnasium[box2d] stable-baselines3 torch
步骤 2:导入库并设置环境
import gymnasium
from stable_baselines3 import DQN
from stable_baselines3.common.evaluation import evaluate_policy

# 创建 Lunar Lander 环境
env = gymnasium.make("LunarLander-v3")
步骤 3:定义 DQN 模型
# 定义 DQN 模型
model = DQN("MlpPolicy", env, verbose=1)
步骤 4:训练 DQN 模型
# 根据需要调整训练步数
model.learn(total_timesteps=750_000)
步骤 5:评估已训练完成的模型
mean_reward, std_reward = evaluate_policy(model, env, n_eval_episodes=10)
print(f"平均奖励:{mean_reward} +/- {std_reward}")

# 可选:保存模型
model.save("dqn_lunar_lander")
步骤 6:可视化已训练完成的模型
import time

# 如有需要,加载模型
model = DQN.load("dqn_lunar_lander")

# 可视化模型表现
episodes = 5

for episode in range(1, episodes + 1):
    obs, info = env.reset()
    done = False
    score = 0

    while not done:
        env.render()
        action, _states = model.predict(obs)
        obs, reward, terminated, truncated, info = env.step(action)
        done = terminated or truncated
        score += reward

    print(f"回合:{episode}, 分数:{score}")
    time.sleep(1)

env.close()

说明

  • 环境设置gymnasium.make("LunarLander-v3") 用于初始化 Lunar Lander 环境。
  • DQN 模型:使用 Stable Baselines3 中的 DQN 类,并采用 MLP 策略来定义模型。
  • 训练learn 方法会根据指定的时间步数对模型进行训练。
  • 评估evaluate_policy 函数用于评估模型在多个回合中的表现。
  • 可视化:通过循环渲染环境,以实时观察训练完成后的模型表现。

额外建议

  • 超参数:你可能需要调整超参数,例如学习率、批次大小等,以获得更好的表现。
  • 检查点保存:在训练过程中保存中间模型,以避免训练进度丢失。
  • 监控:使用 TensorBoard 实时监控训练指标。
分数随回合数变化的训练曲线:起始约为 -200 并偶有跌至 -500,在约 500 回合前快速上升,随后在 +250 到 +300 之间保持平稳直到 2600 回合

结论

DQN 是一种强大的强化学习算法,它结合了 Q 学习与深度神经网络。通过运用经验回放与目标网络等技术,DQN 能够有效学习并解决如 Gymnasium Lunar Lander 这类复杂环境,展现出其在游戏与现实世界应用中的潜力。目标网络与本地网络的配合使用,能够确保学习过程的稳定性与一致性,使 DQN 成为一种适用于各种强化学习问题的高效且稳健的算法。

额外学习资源

代码仓库与模型

Github 仓库

训练过程视频

早期检查点

200,000 次训练步数

智能体已经开始稳定控制,但着陆表现仍不够一致。
训练中期

400,000 次训练步数

学习到的策略展现出更干净的下降控制和更好的接近时机。
最佳检查点

最佳模型

最佳检查点在 LunarLander-v3 中达到了可靠的着陆策略。

模型表现

环境模型类型平均奖励总训练步数HuggingFaceGoogle Colab
LunarLander-v3DQN218.56 +/- 63.62750,000查看模型查看 Colab