前言

如果你问任何一个强化学习研究者“入门该读什么书”,99%的人会毫不犹豫地推荐这本《Reinforcement Learning: An Introduction》。作为强化学习领域的奠基之作,第一版自1998年出版以来,已经成为全球高校RL课程的标准教材,影响了整整一代AI研究者。2020年推出的第二版,在保留经典内容的基础上,全面更新了近20年的最新进展,包括深度强化学习、分布式RL、安全RL等前沿方向,厚度也从第一版的500多页增加到了近600页。

本书的两位作者都是强化学习领域的传奇人物:Richard S. Sutton被誉为“强化学习之父”,他提出了时序差分学习(TD)、策略梯度、Dyna架构等核心算法;Andrew G. Barto是Sutton的导师,两人共同提出了著名的Sutton-Barto经典条件反射模型,为RL与神经科学的交叉奠定了基础。

接下来,我们将从核心框架、经典算法、应用案例和前沿方向四个维度,带你深入理解这本RL圣经的精髓。


论文信息

  • 标题:Reinforcement Learning: An Introduction (Second Edition)
  • 作者:Richard S. Sutton, Andrew G. Barto
  • 出版:MIT Press, 2020
  • 代码:github.com/ShangtongZhang/reinforcement-learning-an-introduction
  • 论文:http://incompleteideas.net/book/RLbook2020.pdf

一、一切的起点:马尔可夫决策过程(MDP)

强化学习研究的是智能体(Agent)如何在与环境的交互中学习最优策略,以最大化长期累积奖励。这个交互过程可以用马尔可夫决策过程(Markov Decision Process, MDP)来完美建模。

1.1 MDP的五要素

一个MDP由五个基本元素组成:

  • 状态空间SSS:智能体可能处于的所有状态的集合
  • 动作空间AAA:智能体在每个状态下可以执行的所有动作的集合
  • 转移概率P(s′∣s,a)P(s'|s,a)P(ss,a):在状态sss执行动作aaa后,转移到状态s′s's的概率
  • 奖励函数R(s,a,s′)R(s,a,s')R(s,a,s):在状态sss执行动作aaa转移到s′s's后,获得的即时奖励
  • 折扣因子γ\gammaγ:取值范围[0,1][0,1][0,1],用于折现未来的奖励,越远的奖励权重越低

通俗解释
MDP就是你的股票投资生涯:

  • 你就是那个投资者(智能体
  • 你现在有多少本金、持有哪些股票、大盘行情如何,这就是你的状态
  • 你可以选择买入、卖出、持有、加仓、减仓,这就是你的动作
  • 你买入一只股票,可能第二天涨停,也可能跌停,这就是转移概率
  • 股票涨了赚钱是正奖励,跌了亏钱是负奖励,分红是额外奖励,这就是奖励
  • 你的目标不是某一次交易赚最多,而是十年二十年下来资产增值最多(长期累积奖励最大化

1.2 价值函数与贝尔曼方程

为了评估每个状态或动作的好坏,我们引入价值函数的概念。最常用的是状态价值函数vπ(s)v_\pi(s)vπ(s),表示在状态sss下遵循策略π\piπ所能获得的期望长期累积奖励。

状态价值函数的贝尔曼方程(Bellman Equation)是RL中最重要的公式之一:
vπ(s)=Eπ[Rt+1+γvπ(St+1)∣St=s]v_\pi(s) = \mathbb{E}_\pi[R_{t+1} + \gamma v_\pi(S_{t+1}) | S_t = s]vπ(s)=Eπ[Rt+1+γvπ(St+1)St=s]
公式解释

  • vπ(s)v_\pi(s)vπ(s):状态sss在策略π\piπ下的价值
  • Eπ\mathbb{E}_\piEπ:在策略π\piπ下的数学期望
  • Rt+1R_{t+1}Rt+1:时刻t+1t+1t+1获得的即时奖励
  • γ\gammaγ:折扣因子,γ=0\gamma=0γ=0表示只关心即时奖励,γ=1\gamma=1γ=1表示未来奖励和即时奖励同等重要
  • vπ(St+1)v_\pi(S_{t+1})vπ(St+1):下一状态St+1S_{t+1}St+1的价值
  • St=sS_t = sSt=s:条件是当前时刻ttt处于状态sss

贝尔曼方程的核心思想是:当前状态的价值 = 即时奖励 + 下一状态价值的折现。这是一个递归定义,也是所有RL算法的基础。

除了状态价值函数,还有动作价值函数qπ(s,a)q_\pi(s,a)qπ(s,a),表示在状态sss执行动作aaa后遵循策略π\piπ的期望长期奖励:
qπ(s,a)=Eπ[Rt+1+γqπ(St+1,At+1)∣St=s,At=a]q_\pi(s,a) = \mathbb{E}_\pi[R_{t+1} + \gamma q_\pi(S_{t+1}, A_{t+1}) | S_t = s, A_t = a]qπ(s,a)=Eπ[Rt+1+γqπ(St+1,At+1)St=s,At=a]

通俗解释:最优策略就是在每个状态下,选择能带来最大长期奖励的动作。你手里这只股票现在值多少钱,等于你马上能拿到的钱,加上这只股票未来价值的折现。比如你现在持有某只股票,它的“总价值”不是只看今天的涨跌,而是今天的收益,加上明天、后天、未来所有收益按时间打了折之后的总和。

我们用炒股来理解贝尔曼方程,把公式里的每一项都对应成炒股里的概念:

vπ(s)=Eπ[Rt+1+γvπ(St+1)∣St=s]v_\pi(s) = \mathbb{E}_\pi\left[R_{t+1} + \gamma v_\pi(S_{t+1}) \mid S_t = s\right]vπ(s)=Eπ[Rt+1+γvπ(St+1)St=s]

  • vπ(s)v_\pi(s)vπ(s):你现在手里的这只股票(状态sss),在你当前的买卖策略(π\piπ)下,未来能给你带来的总收益预期
  • Rt+1R_{t+1}Rt+1:你现在持有这只股票,下一刻能拿到的即时收益,比如股息、分红,或者立刻卖出能赚到的差价。
  • vπ(St+1)v_\pi(S_{t+1})vπ(St+1):下一刻,股价变动后,你持有的这只股票(新状态St+1S_{t+1}St+1),按你的策略未来能带来的总收益预期。
  • γ\gammaγ折扣因子,就像你对未来收益的“信任度”。γ\gammaγ越大,你越看重长期持有带来的收益;γ\gammaγ越小,你越想落袋为安,只关心眼前的利润。

1.3 最优价值函数与最优策略

我们的最终目标是找到最优策略π∗\pi_*π,使得在所有状态下的价值函数最大。对应的最优状态价值函数v∗(s)v_*(s)v(s)和最优动作价值函数q∗(s,a)q_*(s,a)q(s,a)满足:
v∗(s)=max⁡aE[Rt+1+γv∗(St+1)∣St=s,At=a]v_*(s) = \max_a \mathbb{E}[R_{t+1} + \gamma v_*(S_{t+1}) | S_t = s, A_t = a]v(s)=amaxE[Rt+1+γv(St+1)St=s,At=a]
q∗(s,a)=E[Rt+1+γmax⁡a′q∗(St+1,a′)∣St=s,At=a]q_*(s,a) = \mathbb{E}[R_{t+1} + \gamma \max_{a'} q_*(S_{t+1}, a') | S_t = s, A_t = a]q(s,a)=E[Rt+1+γamaxq(St+1,a)St=s,At=a]

在这里插入图片描述

图片1:MDP智能体-环境交互示意图(出处:本书图3.1)
分析:智能体执行动作AtA_tAt,环境返回奖励Rt+1R_{t+1}Rt+1和新状态St+1S_{t+1}St+1,这个循环不断进行,直到任务结束。



二、三大经典算法家族:从动态规划到深度强化学习

基于MDP框架,RL算法可以分为三大经典家族:动态规划(DP)、蒙特卡洛方法(MC)和时序差分学习(TD)。这三类算法各有优缺点,适用于不同的场景。
这三类算法就像三种炒股策略——动态规划(DP)是拿着完整的历史行情表做完美推演,蒙特卡洛(MC)是实盘全仓试错,靠完整交易结果复盘,时序差分(TD)则是边看实时行情边修正判断,每一步都更新对股票价值的估计

2.1 动态规划:已知模型的完美解法

动态规划(Dynamic Programming, DP)是最早的RL算法,它假设我们完全知道MDP的模型(即转移概率PPP和奖励函数RRR)。DP算法通过迭代求解贝尔曼方程来得到最优价值函数和最优策略。

最常用的DP算法是值迭代(Value Iteration)

  1. 初始化所有状态的价值v(s)=0v(s)=0v(s)=0
  2. 迭代更新每个状态的价值:
    vk+1(s)=max⁡a∑s′P(s′∣s,a)[R(s,a,s′)+γvk(s′)]v_{k+1}(s) = \max_a \sum_{s'} P(s'|s,a) [R(s,a,s') + \gamma v_k(s')]vk+1(s)=amaxsP(ss,a)[R(s,a,s)+γvk(s)]
  3. 当价值函数收敛后,通过贪心策略得到最优策略:
    π∗(s)=arg⁡max⁡a∑s′P(s′∣s,a)[R(s,a,s′)+γv∗(s′)]\pi_*(s) = \arg\max_a \sum_{s'} P(s'|s,a) [R(s,a,s') + \gamma v_*(s')]π(s)=argamaxsP(ss,a)[R(s,a,s)+γv(s)]

DP的优点是理论保证收敛,缺点是需要知道环境模型,而且计算复杂度是O(∣S∣2∣A∣)O(|S|^2|A|)O(S2A)对于大状态空间的问题不适用。

2.2 蒙特卡洛方法:从经验中学习

蒙特卡洛方法(Monte Carlo, MC)不需要知道环境模型,它通过采样完整的轨迹来估计价值函数。MC算法的核心思想是:一个状态的价值等于从该状态出发,所有采样轨迹的平均累积奖励

MC算法的步骤:

  1. 初始化所有状态的价值v(s)=0v(s)=0v(s)=0,计数N(s)=0N(s)=0N(s)=0
  2. 采样一条完整的轨迹:s0,a0,r1,s1,a1,r2,...,sTs_0, a_0, r_1, s_1, a_1, r_2, ..., s_Ts0,a0,r1,s1,a1,r2,...,sT
  3. 从后往前计算每个状态的累积奖励Gt=rt+1+γrt+2+...+γT−t−1rTG_t = r_{t+1} + \gamma r_{t+2} + ... + \gamma^{T-t-1} r_TGt=rt+1+γrt+2+...+γTt1rT
  4. 更新状态价值:v(st)=(v(st)∗N(st)+Gt)/(N(st)+1)v(s_t) = (v(s_t) * N(s_t) + G_t) / (N(s_t) + 1)v(st)=(v(st)N(st)+Gt)/(N(st)+1)N(st)+=1N(s_t) += 1N(st)+=1
  5. 重复步骤2-4,直到价值函数收敛

MC的优点是不需要环境模型,计算简单;缺点是需要完整的轨迹,学习速度慢,方差大。

2.3 时序差分学习:结合DP和MC的优点

时序差分学习(Temporal Difference, TD)是RL中最核心的算法,它结合了DP的 bootstrapping(自举,用估计值更新估计值)和MC的采样学习,不需要环境模型,也不需要完整的轨迹。

最基础的TD算法是TD(0),用于估计状态价值函数:
V(St)←V(St)+α[Rt+1+γV(St+1)−V(St)]V(S_t) \leftarrow V(S_t) + \alpha [R_{t+1} + \gamma V(S_{t+1}) - V(S_t)]V(St)V(St)+α[Rt+1+γV(St+1)V(St)]
公式解释

  • V(St)V(S_t)V(St):当前状态StS_tSt的价值估计
  • α\alphaα:学习率,取值范围(0,1](0,1](0,1],控制更新的步长
  • Rt+1+γV(St+1)R_{t+1} + \gamma V(S_{t+1})Rt+1+γV(St+1):TD目标,即当前状态的新估计值
  • Rt+1+γV(St+1)−V(St)R_{t+1} + \gamma V(S_{t+1}) - V(S_t)Rt+1+γV(St+1)V(St):TD误差,即新估计值与旧估计值的差值

TD(0)的核心思想是:用下一个状态的价值估计来更新当前状态的价值。与MC相比,TD不需要等到轨迹结束,每走一步就可以更新一次,学习速度更快,方差更小。就像你不用等股票卖出才复盘,而是每天看一下行情,就根据当天涨跌和对未来的预判,立刻修正自己对这只股票价值的判断,学得快还不容易被单次极端行情带偏。

除了TD(0),还有更通用的TD(λ)算法,它结合了多步TD的优点,通过引入资格迹(Eligibility Trace)来平衡偏差和方差:
et(s)=γλet−1(s)+1(St=s)e_t(s) = \gamma \lambda e_{t-1}(s) + \mathbb{1}(S_t = s)et(s)=γλet1(s)+1(St=s)
δt=Rt+1+γV(St+1)−V(St)\delta_t = R_{t+1} + \gamma V(S_{t+1}) - V(S_t)δt=Rt+1+γV(St+1)V(St)
V(s)←V(s)+αδtet(s)V(s) \leftarrow V(s) + \alpha \delta_t e_t(s)V(s)V(s)+αδtet(s)
公式解释

  • et(s)e_t(s)et(s):状态sss在时刻ttt的资格迹,表示该状态对当前TD误差的贡献
  • λ\lambdaλ:迹衰减参数,取值范围[0,1][0,1][0,1]λ=0\lambda=0λ=0时退化为TD(0),λ=1\lambda=1λ=1时退化为MC
  • 1(St=s)\mathbb{1}(S_t = s)1(St=s):指示函数,当St=sS_t=sSt=s时为1,否则为0
  • δt\delta_tδt:TD误差

在这里插入图片描述

图片2:TD(λ)在19状态随机行走问题上的均方根误差(出处:本书图6.2)
分析:当λ\lambdaλ取中间值(约0.3)时,TD(λ)的性能最好,说明多步TD结合了TD(0)(低方差)和MC(低偏差)的优点。

2.4 控制算法:从价值函数到策略

上面讲的都是预测算法(估计价值函数),而我们的最终目标是控制(找到最优策略)。最经典的控制算法是Q-learningSARSA

Q-learning:异策略(Off-policy)控制

Q-learning是最著名的RL算法之一,它是异策略的,即行为策略(用于收集数据的策略)和目标策略(我们要优化的策略)不同。Q-learning的更新公式:
Q(St,At)←Q(St,At)+α[Rt+1+γmax⁡aQ(St+1,a)−Q(St,At)]Q(S_t, A_t) \leftarrow Q(S_t, A_t) + \alpha [R_{t+1} + \gamma \max_a Q(S_{t+1}, a) - Q(S_t, A_t)]Q(St,At)Q(St,At)+α[Rt+1+γamaxQ(St+1,a)Q(St,At)]
公式解释

  • Q(St,At)Q(S_t, A_t)Q(St,At):当前状态-动作对的价值估计
  • max⁡aQ(St+1,a)\max_a Q(S_{t+1}, a)maxaQ(St+1,a):下一状态的最大动作价值,即目标策略是贪心策略
  • 其他符号与TD(0)相同

Q-learning的优点是可以从任意行为策略的经验中学习,数据利用率高;缺点是容易高估Q值,导致训练不稳定。就像你既能从自己的实盘操作里学经验,也能从别人的交易记录里学教训,不管别人是追涨杀跌还是长线持有,你都能从中提炼出最优买卖策略,数据利用率超高。

SARSA:同策略(On-policy)控制

SARSA是同策略的,即行为策略和目标策略相同(通常是ε-贪心策略)。SARSA的更新公式:
Q(St,At)←Q(St,At)+α[Rt+1+γQ(St+1,At+1)−Q(St,At)]Q(S_t, A_t) \leftarrow Q(S_t, A_t) + \alpha [R_{t+1} + \gamma Q(S_{t+1}, A_{t+1}) - Q(S_t, A_t)]Q(St,At)Q(St,At)+α[Rt+1+γQ(St+1,At+1)Q(St,At)]
公式解释

  • Q(St+1,At+1)Q(S_{t+1}, A_{t+1})Q(St+1,At+1):下一状态-动作对的价值,由当前的行为策略选择
  • 其他符号与Q-learning相同

SARSA的优点是训练更稳定,适合在线学习;缺点是数据利用率低。SARSA就像你只从自己的真实交易里复盘学习,更稳更保守,不容易踩坑,但没法借鉴别人的经验,数据利用率低。

在这里插入图片描述

图片3:Q-learning与SARSA在悬崖行走问题上的性能对比(出处:本书图6.5)
分析:SARSA学习到的是更安全的路径(远离悬崖),因为它是同策略的,会考虑探索时掉入悬崖的风险;而Q-learning学习到的是最优路径(沿着悬崖边缘走),因为它是异策略的,目标策略是贪心的,不会考虑探索的风险。

2.5 函数近似与深度强化学习

当状态空间很大(比如图像,状态数是像素值的组合,达到101000010^{10000}1010000以上)时,表格型RL算法(用表格存储价值函数)不再适用,这时我们需要用函数近似来表示价值函数或策略。最常用的函数近似器是深度神经网络,这就是深度强化学习(Deep RL)。当市场上股票多到数不清(没法给每只股票建个表记录价值),我们就用神经网络来 “估算” 每只股票的价值,而不是靠手工查表,这就像用经验模型代替死记硬背。

最经典的深度RL算法是DQN(Deep Q-Network),它用深度神经网络来近似Q函数,解决了Atari游戏的问题。DQN的核心创新是:

  1. 经验回放(Experience Replay):将智能体的经验存储在回放缓冲区中,每次训练时随机采样一批经验,打破数据的相关性
  2. 目标网络(Target Network):用一个独立的目标网络来计算TD目标,每隔一定步数更新一次,提高训练稳定性

DQN的损失函数:
L(θ)=E(s,a,r,s′)∼U(D)[(r+γmax⁡a′Qθ−(s′,a′)−Qθ(s,a))2]L(\theta) = \mathbb{E}_{(s,a,r,s') \sim U(D)} \left[ \left( r + \gamma \max_{a'} Q_{\theta^-}(s', a') - Q_\theta(s,a) \right)^2 \right]L(θ)=E(s,a,r,s)U(D)[(r+γamaxQθ(s,a)Qθ(s,a))2]
公式解释

  • L(θ)L(\theta)L(θ):损失函数,参数是神经网络的权重θ\thetaθ
  • U(D)U(D)U(D):从回放缓冲区DDD中均匀采样
  • Qθ(s,a)Q_\theta(s,a)Qθ(s,a):当前Q网络的输出
  • Qθ−(s′,a′)Q_{\theta^-}(s', a')Qθ(s,a):目标Q网络的输出,权重θ−\theta^-θ每隔NNN步从θ\thetaθ复制一次
  • 其他符号与Q-learning相同

在这里插入图片描述

图片4:DQN在49个Atari游戏上的归一化得分(出处:本书图16.6)
分析:DQN在大多数Atari游戏上超过了人类专家的水平,证明了深度强化学习可以直接从原始像素中学习到复杂的策略。


三、强化学习的经典应用:从游戏到机器人

本书第16章详细介绍了RL的多个经典应用案例,展示了RL在不同领域的强大能力。

3.1 西洋双陆棋:TD-Gammon

1992年,Tesauro开发的TD-Gammon是RL的第一个里程碑式应用。TD-Gammon使用TD(λ)算法训练一个神经网络来评估棋盘状态,最终达到了人类世界冠军的水平。

TD-Gammon的成功证明了:

  1. RL可以在复杂的博弈问题中达到人类顶级水平
  2. 自玩(Self-play)是一种有效的训练方式
  3. 神经网络可以很好地近似价值函数

3.2 围棋:AlphaGo与AlphaZero

2016年,DeepMind的AlphaGo击败了世界围棋冠军李世石,震惊了全世界。AlphaGo结合了深度强化学习、蒙特卡洛树搜索(MCTS)和监督学习,是RL在博弈领域的又一个里程碑。

2017年,DeepMind推出了AlphaZero,它不需要任何人类知识,完全通过自玩学习,在围棋、国际象棋和将棋三个游戏上都击败了之前的顶级AI。

3.3 个性化网页服务

RL在互联网领域的一个重要应用是个性化推荐和广告投放。本书介绍了两个经典案例:

  1. 雅虎首页新闻推荐:使用上下文老虎机(Contextual Bandit)算法,根据用户特征选择新闻,点击率提高了12.5%
  2. Adobe营销云的广告推荐:使用基于MDP的终身价值(LTV)优化算法,考虑用户的长期访问,提高了用户的终身价值
指标 定义 贪心算法表现 LTV优化算法表现
CTR(点击率) 总点击数 / 总访问数 最优 较差
LTV(终身价值) 总点击数 / 总用户数 较差 最优

表格1:CTR与LTV指标对比(出处:本书表16.1)
分析:贪心算法只关心单次点击,所以在CTR上表现更好;而LTV优化算法关心用户的长期访问,所以在LTV上表现更好,说明考虑长期收益的策略能提高用户的忠诚度和终身价值。

3.4 热滑翔机器人

RL在机器人领域的一个精彩应用是热滑翔机器人。热滑翔是指利用上升的热气流来获得高度,从而实现无动力飞行。鸟类和滑翔机飞行员都擅长这项技能,但对于机器人来说非常困难。

本书介绍了Reddy等人的工作,他们使用SARSA算法训练一个滑翔机在湍流环境中进行热滑翔。实验结果表明,学习后的滑翔机可以成功地利用热气流上升,达到了与人类飞行员相当的水平。

在这里插入图片描述

图片5:热滑翔轨迹对比(出处:本书图16.10)
分析

  • 左图:学习前的随机策略,滑翔机从顶部开始,快速下降,最终坠毁
  • 右图:学习后的策略,滑翔机从底部开始,通过螺旋上升获得高度,成功地利用了热气流

这个案例证明了RL可以用于解决复杂的连续控制问题,并且可以为机器人提供与生物相当的技能。


四、强化学习的前沿方向:挑战与未来

本书第17章介绍了RL的多个前沿研究方向,这些方向是当前RL研究的热点,也是未来RL发展的关键。

4.1 通用价值函数与辅助任务

传统的价值函数只预测未来的累积奖励,而通用价值函数(General Value Functions, GVFs)可以预测任意的未来信号,比如未来的像素值、未来的传感器读数等。

GVF的定义:
vπ,γ,C(s)=Eπ[∑k=t∞(∏i=t+1kγ(Si))Ck+1∣St=s]v_{\pi,\gamma,C}(s) = \mathbb{E}_\pi \left[ \sum_{k=t}^\infty \left( \prod_{i=t+1}^k \gamma(S_i) \right) C_{k+1} \bigg| S_t = s \right]vπ,γ,C(s)=Eπ[k=t(i=t+1kγ(Si))Ck+1 St=s]
公式解释

  • vπ,γ,C(s)v_{\pi,\gamma,C}(s)vπ,γ,C(s):通用价值函数
  • π\piπ:策略
  • γ(Si)\gamma(S_i)γ(Si):状态依赖的折扣因子
  • Ck+1C_{k+1}Ck+1:累积量(Cumulant),即我们要预测的信号
  • 其他符号与传统价值函数相同

GVF的一个重要应用是辅助任务(Auxiliary Tasks)。通过学习多个辅助任务(比如预测未来的像素、预测未来的奖励等),可以帮助智能体学习更好的特征表示,从而加速主任务的学习。

4.2 时间抽象:选项框架

传统的RL算法在原始动作层面进行决策,对于需要长时间序列的任务(比如从家到公司)效率很低。选项框架(Options Framework)引入了时间抽象的概念,将一系列原始动作组合成一个“选项”,智能体可以在选项层面进行决策。

一个选项ω\omegaω由三个部分组成:

  1. 策略πω\pi_\omegaπω:选项内部的动作选择策略
  2. 终止函数γω(s)\gamma_\omega(s)γω(s):在状态sss下选项终止的概率
  3. 初始集IωI_\omegaIω:选项可以被启动的状态集合

选项框架的核心思想是:将复杂的任务分解为多个简单的子任务,每个子任务由一个选项完成。这样可以大大提高RL的效率和可扩展性。

4.3 部分可观测马尔可夫决策过程(POMDP)

在很多实际问题中,智能体无法完全观测到环境的状态(比如机器人只能通过传感器获得部分信息),这时MDP不再适用,需要用部分可观测马尔可夫决策过程(Partially Observable MDP, POMDP)来建模。

POMDP在MDP的基础上增加了:

  • 观测空间OOO:智能体可以观测到的所有信号的集合
  • 观测概率O(o∣s,a)O(o|s,a)O(os,a):在状态sss执行动作aaa后,观测到ooo的概率

POMDP的核心挑战是如何从历史观测和动作中推断出环境的状态。常用的方法是使用信念状态(Belief State),即对环境状态的概率分布。

4.4 奖励信号设计

奖励信号是RL中最重要的部分之一,它定义了智能体的目标。设计一个好的奖励信号非常困难,因为:

  1. 稀疏奖励:很多任务只有在完成时才有奖励,中间没有任何反馈
  2. 奖励黑客:智能体可能会找到意想不到的方式来获得奖励,而不是完成我们真正想要的任务
  3. 长期目标:很多任务的目标是长期的,很难用即时奖励来表示

本书介绍了多种解决方法,包括:

  • 塑形(Shaping):逐步增加任务的难度,从简单的任务开始,逐步过渡到复杂的任务
  • 逆强化学习(Inverse RL):从专家的演示中学习奖励函数
  • 内在奖励(Intrinsic Reward):给智能体提供内在的奖励,比如好奇心、新颖性等

4.5 安全强化学习

随着RL在现实世界中的应用越来越广泛(比如自动驾驶、医疗机器人),安全强化学习(Safe RL)变得越来越重要。Safe RL的目标是在学习过程中保证智能体的安全,避免发生危险的行为。

常用的Safe RL方法包括:

  • 约束优化:在优化奖励函数的同时,满足安全约束
  • 风险敏感RL:考虑风险的价值函数,比如使用条件风险价值(CVaR)
  • 安全探索:在探索过程中避免危险的动作
  • 离线RL:从离线数据中学习,不需要与真实环境交互

五、核心代码实现:Q-learning解决悬崖行走问题

下面我们用Python实现Q-learning算法,解决经典的悬崖行走问题。悬崖行走问题是一个网格世界问题,智能体需要从起点走到终点,同时避免掉入悬崖。

import numpy as np
import matplotlib.pyplot as plt

# 环境定义
class CliffWalkingEnv:
    def __init__(self):
        self.rows = 4
        self.cols = 12
        self.start = (3, 0)  # 起点
        self.end = (3, 11)   # 终点
        self.cliff = [(3, i) for i in range(1, 11)]  # 悬崖位置
        self.state = self.start  # 当前状态

    def reset(self):
        """重置环境,返回初始状态"""
        self.state = self.start
        return self.state

    def step(self, action):
        """执行动作,返回下一个状态、奖励、是否结束"""
        row, col = self.state
        # 动作:0=上,1=下,2=左,3=右
        if action == 0:
            row = max(row - 1, 0)
        elif action == 1:
            row = min(row + 1, self.rows - 1)
        elif action == 2:
            col = max(col - 1, 0)
        elif action == 3:
            col = min(col + 1, self.cols - 1)
        
        next_state = (row, col)
        # 奖励函数
        if next_state in self.cliff:
            reward = -100
            done = True
            next_state = self.start  # 掉入悬崖,回到起点
        elif next_state == self.end:
            reward = 0
            done = True
        else:
            reward = -1
            done = False
        
        self.state = next_state
        return next_state, reward, done

# Q-learning算法
class QLearningAgent:
    def __init__(self, env, alpha=0.1, gamma=0.9, epsilon=0.1):
        self.env = env
        self.alpha = alpha  # 学习率
        self.gamma = gamma  # 折扣因子
        self.epsilon = epsilon  # ε-贪心策略的探索率
        # 初始化Q表:rows x cols x 4
        self.Q = np.zeros((env.rows, env.cols, 4))

    def choose_action(self, state):
        """ε-贪心策略选择动作"""
        if np.random.uniform(0, 1) < self.epsilon:
            # 探索:随机选择动作
            return np.random.choice(4)
        else:
            # 利用:选择Q值最大的动作
            row, col = state
            return np.argmax(self.Q[row, col])

    def learn(self, state, action, reward, next_state, done):
        """Q-learning更新"""
        row, col = state
        next_row, next_col = next_state
        # Q-learning更新公式
        if done:
            target = reward
        else:
            target = reward + self.gamma * np.max(self.Q[next_row, next_col])
        self.Q[row, col, action] += self.alpha * (target - self.Q[row, col, action])

# 训练函数
def train(env, agent, episodes=500):
    rewards = []
    for episode in range(episodes):
        state = env.reset()
        total_reward = 0
        done = False
        while not done:
            action = agent.choose_action(state)
            next_state, reward, done = env.step(action)
            agent.learn(state, action, reward, next_state, done)
            state = next_state
            total_reward += reward
        rewards.append(total_reward)
        if (episode + 1) % 50 == 0:
            print(f"Episode {episode+1}, Total Reward: {total_reward}")
    return rewards

# 测试函数
def test(env, agent):
    state = env.reset()
    total_reward = 0
    done = False
    path = [state]
    while not done:
        action = np.argmax(agent.Q[state[0], state[1]])
        next_state, reward, done = env.step(action)
        state = next_state
        total_reward += reward
        path.append(state)
    print(f"Test Total Reward: {total_reward}")
    print("Path:", path)
    return path

# 主程序
if __name__ == "__main__":
    env = CliffWalkingEnv()
    agent = QLearningAgent(env)
    rewards = train(env, agent, episodes=500)
    
    # 绘制奖励曲线
    plt.plot(rewards)
    plt.xlabel("Episode")
    plt.ylabel("Total Reward")
    plt.title("Q-learning on Cliff Walking")
    plt.show()
    
    # 测试
    path = test(env, agent)

代码解释

  1. CliffWalkingEnv类:定义了悬崖行走环境,包括状态空间、动作空间、转移函数和奖励函数
  2. QLearningAgent类:实现了Q-learning算法,包括ε-贪心动作选择和Q值更新
  3. train函数:训练智能体,返回每集的总奖励
  4. test函数:测试训练好的智能体,返回最优路径

运行结果

  • 训练过程中,总奖励会逐渐上升,最终收敛到-13左右(最优路径的奖励)
  • 测试时,智能体会沿着悬崖边缘走,从起点(3,0)走到终点(3,11),总奖励为-13

六、总结

《Reinforcement Learning: An Introduction》第二版是一本全面、系统、深入的强化学习教材,它从基础的MDP框架讲起,详细介绍了三大经典RL算法家族,然后扩展到函数近似、深度强化学习、多智能体RL等高级内容,最后介绍了RL的经典应用和前沿方向。

本书的特点是:

  1. 理论扎实:所有算法都有严格的数学推导和理论证明
  2. 通俗易懂:用大量的例子和比喻来解释复杂的概念
  3. 内容全面:覆盖了RL的所有核心内容和最新进展
  4. 实用性强:提供了大量的实验结果和应用案例

无论你是RL的初学者,还是有经验的研究者,这本书都值得反复阅读。它不仅是一本教材,更是一本RL领域的百科全书,是每一个RL从业者的必备读物。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐