强化学习导论 -章5 蒙特卡洛

强化学习中的蒙特卡洛方法详解

1.为什么需要蒙特卡洛方法?

在强化学习中,我们面临以下挑战:

  • 环境模型未知
    • 之前的学习里面更新里面使用到的转移概率,很多时候是不知道的, 回报的概率也是不知道的,无法直接通过计算的方式来计算一个状态的回报的函数
  • 状态空间可能很大
    • 对于状态空间很大的情况,绝大部分情况是可能永远不会被访问的状态
  • 需要从经验中学习

2. 什么是蒙特卡洛方法?

蒙特卡洛方法是一种基于随机采样的数值计算方法,这里需要尤其注意的词是 采样
在强化学习中,主要通过真实的采样来用于估计状态价值函数和动作价值函数。其核心思想是通过多次采样和平均来逼近真实值。

蒙特卡洛方法提供了一种model-free的解决方案,不需要完整的环境模型(不知道模型的转移概率)就能学习。

3. 蒙特卡洛方法能做什么?

  1. 策略评估(Policy Evaluation)
  2. 策略改进(Policy Improvement)
  3. 价值函数估计
  4. 最优策略搜索

4. 策略评估

在开始讲解如何使用蒙特卡洛的方法来实现策略评估之前,我们先回顾一下幕的概念,一幕就是一个状态到结束时刻的T的所有的状态和动作以及回报的一个序列

定义回报函数,回报(Return):
G t = R t + 1 + γ R t + 2 + γ 2 R t + 3 + . . . = ∑ k = 0 ∞ γ k R t + k + 1 G_t = R_{t+1} + \gamma R_{t+2} + \gamma^2 R_{t+3} + ... = \sum_{k=0}^{\infty} \gamma^k R_{t+k+1} Gt=Rt+1+γRt+2+γ2Rt+3+...=k=0γkRt+k+1

4.1 首次访问型MC

每一幕的任意一个状态s第一次出现的时候开始,直到这一幕结束所得到的实际回报的gamma衰减的和,就是对于状态S的一个首次访问型MC,这个逻辑上很容易理解。因为一幕本来就是一个分布的一次真实采样,那么显然是一个独立的采样

4.2 每次访问性回报

显然,一个状态s可能在一幕的过程中出现多次,那么如果对于每一个出现的s都执行一次回报的更新,那么这个方法到底有没有作用,后文可能使用的资格trace,还有很多内容都需要使用每次访问性的回报
原文在收敛性的证明原文直接跳过了,如果大家有兴趣的可以参考我的这个文章,里面介绍了首次访问和每次访问的收敛性的定理的证明的过程,
收敛性证明过程及所需条件

21点的蒙特卡洛方法的证明

下面的代码是一个蒙特卡洛的方法,我们这里只是考虑两个动作,一个是hit 一个是stop,policy是默认的动作hit,returns,存放了一个state的所有的出现过的 G t G_t Gt,训练完毕了以后则不再使用training的get action,我们最后经过了20w次训练,完毕后的对抗庄家的胜率是42.7,需要完整代码的可以私信沟通
Episode 200000 completed
Win rate: 42.70%


class MonteCarloAgent:
    def __init__(self, epsilon=0.1):
        self.epsilon = epsilon
        self.Q = defaultdict(lambda: np.zeros(2))  # Q值表
        self.returns = defaultdict(lambda: defaultdict(list))  # 存储回报
        self.policy = defaultdict(lambda: 0)  # 策略
    
    def get_action(self, state, training=True):
        """选择动作"""
        if training and np.random.random() < self.epsilon:
            return np.random.randint(2)
        return self.policy[state]
    
    def update(self, episode):
        """更新策略"""
        states, actions, rewards = zip(*episode)
        
        # 计算回报
        G = 0
        for t in range(len(episode)-1, -1, -1):
            G = rewards[t] + 0.9*G
            state = states[t]
            action = actions[t]
            
            # 首次访问MC预测
            if (state, action) not in [(states[i], actions[i]) for i in range(t)]:
                self.returns[state][action].append(G)
                #更新value值
                self.Q[state][action] = np.mean(self.returns[state][action])
                # 更新策略
                self.policy[state] = np.argmax(self.Q[state])

输出最后的三维的热点图
在这里插入图片描述

5.蒙特卡洛动作价值估计

动作价值和状态价值都是按照之前一样的方法,当访问的时候去更新,但是这里有一个很重要的问题,如果策略是固定策略,那么很有可能其他的很多的动作都永远得不到访问,问了确保所有的Q值都能得到更新,我们需要保证所有的action都有被访问的可能性

  • 试探性出发:确保所有的(s,a)都有不为0的被选为初始化节点的可能性,那么自然有无穷的次数会被选中(当无限幕时)
  • 随机策略:确保所有的动作都有可能被访问

5.1策略更新

当策略不变的时候,我们可以对于这个策略的价值函数的估计,当然也可以像策略迭代的方法一样,进行了策略评估以后,使用贪心策略来更新新的行动策略,这里需要注意的是依然需要保证前文说的两个方法,保证所有的action都会被选中

5.2 蒙特试探性出发

保证MC方法的前提条件已经提到了,但是无论是试探性出发还是要求无数次,还是上面的策略更新的方法,都要求有足够多的幕来更新,策略才能继续往下迭代,考虑到前面的价值迭代的方法(尤其是就地价值直接迭代的方法),我们也可以学习这种就地更新评估,就地更新策略的方法,我们叫做 蒙特卡洛ES
如同前面使用的21点的算的代码逻辑的update函数一一样,每次更新完了一个Q值,我们立马更新了s的动作函数

  • 练习5.4解答,这里存放了所有的return的序列,当然我们也可以直接使用一个count和上一轮的平均值,来更新即可

5.3 没有试探性出发的MC

如果试探性出发的前提条件无法被满足,那么我们需要保证在所有的状态所有的动作都有概率被选择,这里有同轨策略和离轨策略,on/off-policy,这里需要对这个概念加以讲解
同轨策略:生成样本的策略和实际更新的策略是同一个。(前面章节里面的都是这种策略)
离轨策略:生成样本的策略和实际更新的策略不同

举个例子,如果生成样本的策略20%向左,但是80%向右,但是更新的策略是80%向左,20%向右,根据贝尔曼方程可知显然同一个状态的不同返回值的权重和概率有关,那么我们需要将这个权重进行修正,才能从离轨策略得到价值函数的无偏估计

同轨策略的 ϵ \epsilon ϵ-软性策略:保证所有的动作都有一定的基于 ϵ \epsilon ϵ的概率被选中,显然21点中的get_action的训练策略是满足这个算法的条件

原文中证明了为什么 ϵ \epsilon ϵ-贪心策略是一个最好的 ϵ \epsilon ϵ-软策略,但是证明的过程非常的复杂,其实逻辑上很好理解,1:对于 ϵ \epsilon ϵ的随机情况,任何 ϵ \epsilon ϵ-软策略选择动作的概率都是一样的,那么回报也是一样的:
2:对于非 ϵ \epsilon ϵ的情况,贪心策略已经是选择的最大的回报的情况,显然大于任何其他的策略。
我这里不会放这个公式的证明过程,原文还证明了迭代只有一个不动点,我这里也会跳过

6.离轨策略

离轨策略的例子已经讲过了,实用性也是显而易见的,但是显然,离轨策略的不确定性更高,收敛的也是更慢
为了解决刚刚提到的无偏估计的问题,我们使用了一个新的东西叫做重要度采样,为什么使用重要度采样的原因和期望的权值有关系,上文也已经证明了
行动策略(采样策略)的序列在目标策略上发生的概率如下,从s0出发

P π ( τ ) = ∏ t = 0 T − 1 π ( a t ∣ s t ) / b ( a t ∣ s t ) P_π(τ) =\prod_{t=0}^{T-1} π(a_t|s_t)/b(a_t|s_t) Pπ(τ)=t=0T1π(atst)/b(atst)

需要注意的是,实际上还有一个p(s’,r| s, a)的转移概率加权,但是这是一个环境参数,在行动策略和目标策略上都是一样的值,所以可以被去掉(原文这里带过,没有讲到具体是什么东西)

6.1 普通重要度采样

基于这个模型,我们可以简单的对一个回报进行一个无偏估计,我们可以直接对任意的s的回报
∏ t T π ( a t ∣ s t ) b ( a t ∣ s t ) ⋅ G t = ρ t : H ⋅ G t \prod_t^{T}\frac{π(a_t|s_t)}{b(a_t|s_t)}\cdot G_t = \rho_{t:H}\cdot G_t tTb(atst)π(atst)Gt=ρt:HGt,那么对于v的价值函数就从原本的求平均值,变成了求带重要度采样的加权平均
普通重要的采样是期望是目标策略的期望

6.2 加权重要度采样

加权重要度采样的更新规则是如下,显然加权重要度采样的期望是行动策略b的期望
∑ π ( a t ∣ s t ) / b ( a t ∣ s t ) ⋅ G t ∑ π ( a t ∣ s t ) / b ( a t ∣ s t ) \frac{\sum{π(a_t|s_t)/ b(a_t|s_t)}\cdot G_t}{\sum{π(a_t|s_t)/ b(a_t|s_t)}} π(atst)/b(atst)π(atst)/b(atst)Gt

为什么需要加权重要度采样,是普通重要的采样的偏差是无界的,正如我们前文所说,我们需要保证收敛的条件是方差有界,但是显然这里是无法保证这个点的,那么自然无法使用大数定律来家保证收敛性

6.3 离轨方法的控制

离轨方法的策略控制的问题,最主要的方式还是前面的GPI的形式,只是额外多了一些要求,一个就是要求行动策略b是软性的,确保所有的动作都有被访问到的可能性,一个是使用合适的重要度采样来实现期望和方差的控制

6.4 折扣敏感的重要度采样 DAIS

这个地方我看了很久才敏感他的核心的想要讲解的是什么,回到我们的普通重要度采样时候,开始讨论折扣敏感度采样之前,让我回顾下普通重要度采样上进行估算的公式 ρ t : H ⋅ G t \rho_{t:H}\cdot G_t ρt:HGt,所以对于任意的 G t G_t Gt,只要t到H步数足够多,那么会导致这个方差变得非常的恐怖
我们考虑一个核心的问题,回报里面显然包含了t+2时刻的R,但是实际上这个t+2时刻的R,在重要度采样里面也乘以了t+2以后所有的比率的积,这个是有问题的
考虑 G t G_t Gt的折扣问题 γ \gamma γ,对于任意一个 G t G_t Gt,我们将其变成带 γ \gamma γ的形式,然后只在这个真正对这个回报产生影响的 ρ \rho ρ才乘进来,我们将回报的 γ \gamma γ放到和 ρ \rho ρ一起,得到公式如下(巨长)
V ( s ) = ∑ t ∈ τ ( s ) ( ( 1 − γ ) ∑ h = t + 1 T ( t ) − 1 γ h − ( t + 1 ) ρ t : h − 1 G ˉ t : h + γ T ( t ) − ( t + 1 ) ρ t : T ( t ) − 1 G ˉ t : T ( t ) ) ∣ τ ( s ) ∣ V(s) = \frac{\sum_{t \in \tau(s)}((1-\gamma)\sum_{h=t+1}^{T(t) -1}\gamma^{h-(t+1)}\rho_{t:h-1}\bar G_{t:h } + \gamma^{T(t) -(t+1)}\rho_{t:T(t) -1}\bar G_{t:T(t)})}{|\tau(s)|} V(s)=τ(s)tτ(s)((1γ)h=t+1T(t)1γh(t+1)ρt:h1Gˉt:h+γT(t)(t+1)ρt:T(t)1Gˉt:T(t))
其中 G ˉ t : h = R t + 1 + R t + 2 + . . . + R h \bar G_{t:h }=R_{t+1} +R_{t+2} + ... + R_h Gˉt:h=Rt+1+Rt+2+...+Rh,称之为平价部分回报

讲解一下这个公式,和之前最大的区别在于单个 ρ \rho ρ只是在对应的回报才会有影响,而不是直接对整体的 G t G_t Gt有效
显然这个可以显著的减少对应的方差,例如我们前面讨论过,之前的方差是无解的,但是如果这里考虑一个极端的情况,我们假设单个 ρ \rho ρ有上界C,只要保证选取合适的gamma使得C* γ \gamma γ < 1时,则可以得到一个有界的方差,从而保证收敛性。

当然即使在不能保证有界的情况下,使用 γ \gamma γ衰减也会显著的减少方差的值

加权的折扣敏感的重要度采样的公式,怎么说呢,这复杂度谁爱用谁用吧~~~~
V ( s ) = ∑ t ∈ τ ( s ) ( ( 1 − γ ) ∑ h = t + 1 T ( t ) − 1 γ h − ( t + 1 ) ρ t : h − 1 G ˉ t : h + γ T ( t ) − ( t + 1 ) ρ t : T ( t ) − 1 G ˉ t : T ( t ) ) ∑ t ∈ τ ( s ) ( ( 1 − γ ) ∑ h = t + 1 T ( t ) − 1 γ h − ( t + 1 ) ρ t : h − 1 + γ T ( t ) − ( t + 1 ) ρ t : T ( t ) − 1 ) V(s) = \frac{\sum_{t \in \tau(s)}((1-\gamma)\sum_{h=t+1}^{T(t) -1}\gamma^{h-(t+1)}\rho_{t:h-1}\bar G_{t:h } + \gamma^{T(t) -(t+1)}\rho_{t:T(t) -1}\bar G_{t:T(t)})}{\sum_{t \in \tau(s)}((1-\gamma)\sum_{h=t+1}^{T(t) -1}\gamma^{h-(t+1)}\rho_{t:h-1}+ \gamma^{T(t) -(t+1)}\rho_{t:T(t) -1})} V(s)=tτ(s)((1γ)h=t+1T(t)1γh(t+1)ρt:h1+γT(t)(t+1)ρt:T(t)1)tτ(s)((1γ)h=t+1T(t)1γh(t+1)ρt:h1Gˉt:h+γT(t)(t+1)ρt:T(t)1Gˉt:T(t))

《Reinforcement Learning: An Introduction, 2nd Edition》是由Richard S. Sutton和Andrew G. Barto合著的经典教材,是强化学习领域的权威入门书籍之一。该书系统地介绍了强化学习的基本概念、算法及其理论基础,并通过实例展示了如何将这些方法应用于实际问题中。 书中涵盖了从马尔可夫决策过程(MDP)到动态规划、蒙特卡洛方法、时序差分学习等核心主题[^3]。此外,它还讨论了函数逼近技术以及深度强化学习的基础知识,为读者提供了深入理解现代强化学习技术的框架。 对于希望动手实践的学习者来说,《Reinforcement Learning: An Introduction, 2nd Edition》官方网站及GitHub上有相关的Python代码示例,可以帮助理解和实现书中的图表与实验结果[^1]。同时,在线社区也提供了部分练习题解答参考,这对于自学非常有帮助[^2]。 值得注意的是,这本书在第三末尾强调了一个重要观点:奖励信号不应该用来直接告诉智能体如何达成目标,而是应该设计成反映环境状态的变化,让智能体通过自身的探索来找到最优策略[^4]。这一原则对于构建有效的强化学习系统至关重要。 ### 强化学习基础 强化学习是一种机器学习范式,其中智能体通过与环境交互以最大化某种形式的累积奖励来学习策略。不同于监督学习和非监督学习,强化学习关注的是长期回报而非即时反馈。 ### 马尔可夫决策过程 (MDP) MDP提供了一个数学框架用于描述具有确定性和随机性的序列决策问题。一个MDP由状态空间S、动作空间A、转移概率P以及奖励函数R组成。解决MDP通常意味着找到一个策略π,使得预期的总回报最大。 ### 动态规划 (DP) 动态规划是一类基于完整模型假设下的规划算法,能够求解已知环境动力学的问题。尽管DP方法理论上可以精确求解许多强化学习问题,但由于其对计算资源的需求随着状态数量的增长呈指数级增加,因此在处理大规模问题时存在局限性[^3]。 ### 蒙特卡洛方法与时序差分学习 蒙特卡洛方法利用完整的episode来进行价值估计和策略改进,而不需要环境模型;相比之下,时序差分学习则结合了动态规划和蒙特卡洛方法的优点,能够在没有完整episode的情况下更新估计值,从而更高效地进行学习。 ### 函数逼近 当状态空间变得庞大或者连续时,使用表格形式存储每个状态的价值变得不可行。这时就需要引入函数逼近器如神经网络来泛化不同状态之间的价值估计。 ### 深度强化学习简介 深度强化学习结合了深度学习的强大表示能力与传统强化学习的方法,使得智能体可以在高维感知输入下做出复杂决策。这开启了像AlphaGo这样的突破性成就的可能性。 ```python # 示例:简单的Q-learning更新规则 def q_learning_update(q_table, state, action, reward, next_state, alpha=0.1, gamma=0.9): """ 更新Q表中的特定状态-动作对的估计值。 参数: q_table (dict): 当前的Q表 state (any): 当前状态 action (int): 执行的动作 reward (float): 收到的即时奖励 next_state (any): 下一状态 alpha (float): 学习率 gamma (float): 折扣因子 """ # 获取当前状态-动作对的Q值 current_q = q_table[state][action] # 计算下一状态的最大Q值 max_future_q = max(q_table[next_state].values()) # 应用Q-learning更新规则 new_q = (1 - alpha) * current_q + alpha * (reward + gamma * max_future_q) # 更新Q表 q_table[state][action] = new_q ``` 上述代码片段演示了Q-learning算法的一个基本组成部分——Q值的更新过程。这种类型的算法允许智能体根据经验调整其对未来奖励的预测,进而优化其采取行动的方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值