强化学习(四)基于蒙特卡罗算法 Monte-Calo 的求解

news2024/10/6 14:32:31

文章目录

  • 1. 免模型学习的强化学习问题
  • 2. 利用蒙特卡洛法求解最优价值函数
    • 2.1 策略评估(预测)
    • 2.2 策略迭代(控制)


在《强化学习(三)基于动态规划 Dynamic Programming 的求解方法》的文末中提到,利用动态规划迭代地求解强化学预测和控制问题,当待更新估计价值的状态的后续状态过多时,每次迭代所消耗的计算资源将指数级增长直至动态规划不再适用。而且,运用动态规划还有一个重要前提是,环境的状态转移模型 P P P (状态转移概率)和奖励函数都是确定已知的,即解决的是模型依赖(Model-Based RL)的强化学习问题,对于模型无关(Model-Free RL)的问题则不适用。而本文将介绍的蒙特卡罗方法(Monte-Calo,MC)则是一种既能应对大规模问题,又适用于模型无关的强化学习问题的方法

1. 免模型学习的强化学习问题

前文提到,强化学习当中的两个基本问题为预测和控制,在运用动态规划求解的两类问题分别是:

  1. 预测问题(策略评估)。给定强化学习的状态集 S S S,动作集 A A A,模型状态转化概率矩阵 P P P,采取动作的即时奖励 R R R,奖励衰减因子 γ \gamma γ,以及动作策略 π \pi π,在这些条件下,求解策略 π \pi π 的状态价值函数 v ( π ) v(\pi) v(π)
  2. 控制问题(策略迭代)。给定强化学习的状态集 S S S,动作集 A A A,模型状态转化概率矩阵 P P P,采取动作的即时奖励 R R R,奖励衰减因子 γ \gamma γ,求解最优的状态价值函数 v ∗ v_* v 和最优策略 π ∗ \pi_* π

如上所述,运用动态规划求解的这类问题的环境状态转移概率矩阵 P P P 是已知的,一般称为有模型学习或基于模型的学习问题(Model-Based)。然而现实中的很多强化学习场景,是没有先验知识或者是环境模型的先验信息的,例如无法事先得到模型的状态转化概率矩阵 P P P,这类问题就称为免模型学习或不基于模型的学习问题(Model-Free),此时就需要通过与环境的直接交互来学习策略和值函数,而不用对环境的模型进行假设,因此免模型的强化学习方法天然地适应各种类型的问题,但也面临着需要更多的样本数据进行学习和某些情况下难以收敛于最优解等问题。

免模型的强化学习问题的两个基本问题可以重定义为:

  1. 预测问题(策略评估)。给定强化学习的状态集 S S S,动作集 A A A,采取动作的即时奖励 R R R,奖励衰减因子 γ \gamma γ,以及给定策略 π \pi π,在这些条件下(状态转移概率 P P P 未知),求解策略 π \pi π 的状态价值函数 v ( π ) v(\pi) v(π)
  2. 控制问题(策略迭代)。给定强化学习的状态集 S S S,动作集 A A A,采取动作的即时奖励 R R R,奖励衰减因子 γ \gamma γ,探索率 ϵ \epsilon ϵ,求解最优的状态价值函数 v ∗ v_* v 和最优策略 π ∗ \pi_* π

2. 利用蒙特卡洛法求解最优价值函数

蒙特卡罗方法(Monte-Calo,MC)是一种基于随机抽样和统计分析的数值计算方法,可以用于求解无模型的强化学习问题的策略评估和迭代。其基本思想就是,通过大量的随机抽样来近似未知信息,最终用得到的近似信息求解复杂的问题,因此该方法具有极高的适应性。

在强化学习当中,通过蒙特卡罗方法采样若干完整的状态序列(episode)来估计状态的价值,这里的完整序列指的是到达终点的状态序列,例如在《【项目案例】利用强化学习训练“井字棋”下棋策略的详细介绍》指的是对弈结束时,所存储的从开始到结束的状态序列。

2.1 策略评估(预测)

在给定一个策略的前提下,对该策略下的各个状态价值进行评估。基于该策略 π \pi π 进行模拟并采集(确定的)完整的状态序列,可以通过下式,从结束状态的价值逆推得到各个状态的价值:

v π ( s ) = R t a + γ v π ( s ′ ) = G t v_{\pi}(s)=R_t^a +\gamma v_{\pi}(s')=G_t vπ(s)=Rta+γvπ(s)=Gt

由于 v π ( s ) = E π ( G t ∣ S t = s ) v_{\pi}(s)=\mathbb{E}_{\pi}(G_t|S_t=s) vπ(s)=Eπ(GtSt=s) 可得,每个状态的价值函数等于所有样本中,该状态所获价值的期望(平均)。因此,对于蒙特卡罗方法而言,如果要求某一个状态的状态价值,则需要求出所有的完整序列样本中出现该状态时的收获价值,再取平均即为该状态的近似价值,公式如下:

v π ( s ) ≈ mean ( G t ) , if    S t = s v_{\pi}(s) \approx \text{mean}(G_t), \text{if } \,S_t = s vπ(s)mean(Gt),if St=s

总体的思路即是用模拟产生的序列的状态价值的期望来估计实际的状态价值。但是实际的计算过程中,可能会有以下的一些问题:

(1)在一个状态序列中,可能重复出现同样的状态,该状态的 G t G_t Gt 值如何计算?

针对这个问题有两种解决办法:

  1. 将状态序列中首次出现该状态时的收获价值设为 G t G_t Gt
  2. 针对序列中每次出现的该状态 s s s,都计算对应的收获值并纳入平均值计算当中,即该状态序列下会有 G t 1 , G t 2 . . . G_{t1},G_{t2}... Gt1,Gt2... 多个 S t = s , ∀ t ∈ { t 1 , t 2... } S_t=s,\forall t\in \{t1,t2...\} St=s,t{t1,t2...}

(2)在模拟采样过程中,我们需要对所有状态的每次出现的 G t G_t Gt 结果值进行记录后再取平均,对于复杂问题,迭代到后期需要存储的数据量非常多,如何在迭代地更新状态价值以节约存储空间?

可以在每次迭代的时候都更新计算得到最新的状态价值,根据如下式子,每得到一个新的状态序列的状态价值 x k x_k xk,还需要记录总共的纳入均值计算的状态价值个数 k k k,即可根据前一个均值 μ k − 1 \mu_{k-1} μk1 计算出纳入新价值后的均值 μ k \mu_k μk,具体公式如下:

μ k = 1 k ∑ j = 1 k x j = 1 k ( x k + ∑ j = 1 k − 1 x j ) = 1 k ( x k + ( k − 1 ) μ k − 1 ) = μ k − 1 + 1 k ( x k − μ k − 1 ) \mu_k=\frac{1}{k}\sum_{j=1}^{k}x_j=\frac{1}{k}\left(x_k+ \sum_{j=1}^{k-1}x_j \right)=\frac{1}{k}\left(x_k+(k-1)\mu_{k-1} \right)=\mu_{k-1}+\frac{1}{k}(x_k-\mu_{k-1}) μk=k1j=1kxj=k1(xk+j=1k1xj)=k1(xk+(k1)μk1)=μk1+k1(xkμk1)

根据上面的公式可知,根据采样数据,状态每纳入一个新的用以求平均的值 G t G_t Gt 时,总数 N ( s ) = N ( s ) + 1 N(s)=N(s)+1 N(s)=N(s)+1,新的状态期望价值 v ( s ) v(s) v(s) 更新为:

v ( s ) = v ( s ) + 1 N ( s ) ( G t − v ( s ) ) v(s)=v(s)+\frac{1}{N(s)}\left( G_t-v(s) \right) v(s)=v(s)+N(s)1(Gtv(s))

该步骤的计算的渐进复杂度不变,空间复杂度却降至 O ( 1 ) O(1) O(1),显然地,当输入的完整状态序列越多,则 v ( s ) v(s) v(s) 的更新量越小,也越接近实际的状态价值。有时对于海量数据的分布迭代计算,可能会出现并行迭代的情况,因此无法准确估计当前一共纳入计算平均值的状态价值有多少个,因此常常会用一个学习率 α \alpha α 替代 1 / N 1/N 1/N,上式更新为 v ( s ) = v ( s ) + α ( G t − v ( s ) ) v(s)=v(s)+\alpha \left( G_t-v(s) \right) v(s)=v(s)+α(Gtv(s))

2.2 策略迭代(控制)

在前文中,动态规划进行值迭代的思路是,先对当前策略进行评估,计算出状态价值函数,然后基于一定方法(贪婪法),在每个状态处选择后续状态价值最大的动作,更新当前策略,迭代多次最后得到最优价值函数。

蒙特卡洛与动态规划除了在策略评估方法上的差异,在策略迭代上也有所不同。首先是优化对象,动态规划既可以优化状态价值函数,也可以优化动作价值函数,而蒙特卡洛由于每次模拟只得到具体的动作及状态序列,并不知道每一步的可选状态空间,因此一般优化的是动作价值函数 q ∗ q_* q,其次不同的是策略更新的方法,动态规划一般用贪婪法更新策略,这是在环境模型以及动作奖励都已知前提下,而蒙特卡罗法通常采用的是 ϵ − \epsilon- ϵ贪婪法,探索率 ϵ \epsilon ϵ 表示当前阶段随机选择动作的概率,而以 1 − ϵ 1-\epsilon 1ϵ 的概率按贪婪的方法选择动作,此时策略选择到最优的动作 a ∗ a^* a 的概率为: ϵ / m + 1 − ϵ \epsilon/m+1-\epsilon ϵ/m+1ϵ

在相关示例《【项目案例】利用强化学习训练“井字棋”下棋策略的详细介绍》中,模拟对弈阶段,设置一个探索率,使得在模拟过程中可以不断地生成新的状态序列,以避免错过更优价值动作序列。

同时在该案例中,棋手的价值函数会在每次模拟对弈后进行更新,这种智能体从历史数据中学习,并根据历史数据更新策略的方式称为离线学习(off-policy),而在线学习(on-policy)则是在与环境实时交互的过程中,不断地根据交互结果进行学习更新。

这里介绍在线蒙特卡罗方法求解强化学习可知问题的流程,输入内容为:状态集 S S S,动作集 A A A,采取动作的即时奖励 R R R,奖励衰减因子 γ \gamma γ,探索率 ϵ \epsilon ϵ;输出内容为:最优的动作价值函数 q ∗ q_* q 和最优策略 π ∗ \pi_* π。具体流程如下:

  1. 初始化所有的动作价值 Q ( s , a ) = 0 Q(s,a)=0 Q(s,a)=0,状态次数 N ( s , a ) = 0 N(s,a)=0 N(s,a)=0,采样次数 k = 0 k=0 k=0,初始策略为随机策略 π \pi π
  2. 在第 k = k + 1 k=k+1 k=k+1 代,基于策略 π \pi π 进行第 k k k 次蒙特卡罗采样,得到的完整状态序列: S 1 , A 1 , R 1 , S 2 , A 2 , . . . S t , A t , R t , . . . . S T − 1 , A T − 1 , R T − 1 , S T S_1,A_1,R_1,S_2,A_2,...S_t,A_t,R_t,....S_{T-1},A_{T-1},R_{T-1},S_T S1,A1,R1,S2,A2,...St,At,Rt,....ST1,AT1,RT1,ST
  3. 对于状态序列里出现的每一状态行为对 ( S t , A t ) (S_t,A_t) (St,At),按照前面策略评估的方式,先计算出动作价值 Q ( S t , A t ) Q(S_t,A_t) Q(St,At),再更新迭代状态行为对的价值:
    N ( S t , A t ) = N ( S t , A t ) + 1 Q ( S t , A t ) = Q ( S t , A t ) + 1 N ( S t , A t ) ( G t − Q ( S t , A t ) ) N(S_t,A_t)=N(S_t, A_t)+1\\Q(S_t,A_t)=Q(S_t,A_t)+\frac{1}{N(S_t,A_t)}\left( G_t-Q(S_t,A_t) \right) N(St,At)=N(St,At)+1Q(St,At)=Q(St,At)+N(St,At)1(GtQ(St,At))
  4. ϵ = 1 / k \epsilon=1/k ϵ=1/k,基于新计算出的动作价值,用 ϵ − \epsilon- ϵ 贪婪策略对当前策略进行调整;
  5. 循环迭代 2 ∼ 4 2\sim 4 24 步,直至所有的状态动作对 Q ( s , a ) Q(s,a) Q(s,a) 都收敛(更新量非常小),则所有的 Q ( s , a ) Q(s,a) Q(s,a) 对应的就是最优动作价值函数 q q q,对应的的策略 π ( a ∣ s ) \pi(a|s) π(as) 即为最优策略 π ∗ \pi_* π

这里我们为了方便比较,还是举 UCL 强化学习讲义中的例子(也可以在前面的文章中查看),如下图,这是已知环境转移概率模型 P P P 的前提下,用动态规划求解得到的各个状态动作对的最优动作函数 q q q

在这里插入图片描述
现在我们用上述的蒙特卡罗方法来计算最优动作价值函数,在每次迭代过程中,根据一定的探索率 ϵ = 1 / k \epsilon=1/k ϵ=1/k 生成一个完整状态序列,接着计算状态动作对的价值 G G G,并结合出现次数更新状态 s s s 下动作 a a a 的估计价值,具体代码如下:

import random

s_a = {"s1": {"facebook": ["s1"], "quit": ["s2"]},
       "s2": {"facebook": ["s1"], "study": ["s3"]},
       "s3": {"sleep": ["s0"], "study": ["s4"]},
       "s4": {"study": ["s0"], "pub": ["s2", "s3", "s4"]}}
q = {(s,a):0 for s in s_a for a in s_a[s]}
r = {("s1", "facebook"): -1, ("s1", "quit"): 0,
     ("s2", "facebook"): -1, ("s2", "study"): -2,
     ("s3", "sleep"): 0, ("s3", "study"): -2,
     ("s4", "study"): 10, ("s4", "pub"): 1}
     
num_s_a = {(s,a):0 for s in s_a for a in s_a[s]}
k = 0

for k in range(1, 2000):
    s = "s1"
    seq = []
    while s != "s0":
        if random.random() < 1/k:
            a = random.choice(list(s_a[s].keys()))
        else:
            a = max(s_a[s], key=lambda x: q[s,x])
        seq.append((s,a))
        s = random.choice(s_a[s][a])
    # print(seq)
    G = 0
    for pair in seq[::-1]:
        num_s_a[pair] += 1
        G += r[pair]
        q[pair] = q[pair] + (1/num_s_a[pair])*(G-q[pair])
            
print(q)

经过 10000 10000 10000 次迭代,求得的动作价值函数,与上图的最优价值函数绝对离差和为 2.4 2.4 2.4,结果已经非常地接近。

{('s1', 'facebook'): 5.0, ('s1', 'quit'): 5.994002998500746, ('s2', 'facebook'): 5.0, ('s2', 'study'): 5.994600539946007, ('s3', 'sleep'): 0.0, ('s3', 'study'): 7.999399699849905, ('s4', 'study'): 10.0, ('s4', 'pub'): 7.0}

在实验中发现,带有探索率的蒙特卡罗方法的求解结果具有一定的波动性,且在迭代次数较少时,这种波动性越大,而随着迭代采样的次数增大,求解结果的波动范围逐渐缩小,且更加靠近最优的动作状态函数。

注意这里的探索率 ϵ \epsilon ϵ,随着迭代的进行会逐渐减小,这是为了保证算法的收敛性。此外,过大的探索率会导致花费过多时间在探索上而忽视对已知优秀策略的学习;过小的探索率则可能导致策略早熟陷入局部最优,因此具体的探索率大小需要在实际中通过调参进行权衡。

这里不论怎么求,结果与实际最优价值函数总是有一定的误差,这是由于原题目在 s 4 s_4 s4 处采取了动作 pub 之后,状态转移至三个后续状态的概率不是均等的,而在代码中我直接用的是随机转移,用来模拟所谓的对环境先验知识未知的情况,但这种确定的分布概率也可以考虑进代码当中,模拟实际环境的状态反馈,这个留给大家试一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1602195.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

rust学习(BorrowMut异常)

现象&#xff1a; 编译没有问题&#xff0c;运行时出现&#xff1a; 代码&#xff1a; pub fn do_test() {let v Arc::new(RefCell::new(100));let v1 v.try_borrow_mut().unwrap();let v2 v.try_borrow_mut().unwrap(); } 原因&#xff1a; 一个cell貌似不能同时被借用…

书生·浦语大模型实战营之OpenXLab 部署 InternLM2 实践指南

书生浦语大模型实战营之OpenXLab 部署 InternLM2 实践指南 本文档将手把手教您如何在 OpenXLab 部署一个 InternLM2-7B chat 的应用 目录 资料介绍书生浦语 InternLM介绍OpenXLab浦源平台介绍部署 InternLM2-Chat-7B demo模型准备上传模型编写代码部署应用 资料介绍 书生浦语…

Matlab求矩阵的逆,3种常用方法总结

几种求逆矩阵的方法总结&#xff0c;以Matlab语言为例 *0* 引言*1* 简单描述函数实现*2* 方法调用计算对比 0 引言 最近在使用函数库求解逆矩阵的时候发现同一个矩阵使用不同的语言、不同的求解方法会产生不同精度的结果&#xff0c;特别是阶数很高的方阵&#xff0c;一些库中的…

基于LabVIEW的CAN通信系统开发案例

基于LabVIEW的CAN通信系统开发案例 介绍了基于LabVIEW开发的CAN通信系统&#xff0c;该系统主要用于汽车行业的数据监控与分析。通过对CAN通信协议的有效应用&#xff0c;实现了车辆控制系统的高效信息交换与实时数据处理&#xff0c;从而提升了车辆性能的检测与优化能力。 项…

【MySQL数据库】 (篇一 ) 让你快速上手——新手速通版

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、如何起步&#xff1f;&#x1f3c3;‍1.创建数据库&#xff1a;2.选择数据库&#xff1a;3.删除数据库&#xff1a;4.创建表&#xff1a;5.删除表&#xff…

贝锐蒲公英自研异地组网新技术:远程视频监控,流畅度、清晰度大幅提升

在远程视频监控过程中&#xff0c;若遇到网络带宽若遇到网络波动&#xff0c;如&#xff1a;丢包、高延迟等&#xff0c;往往会导致视频流传输时发生数据丢失或延迟现象&#xff0c;从而严重影响视频画面的清晰度和流畅度。 比如&#xff1a;在公司总部集中监看远程矿山或户外水…

华为ensp中静态路由和默认路由的原理及配置

作者主页&#xff1a;点击&#xff01; ENSP专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年4月17日17点37分 默认路由 [Router] ip route-static <目的网络> <目的网络掩码> <下一跳地址>默认路由的作用是将无法匹配路由表中其他路由表项的…

通过WSL在阿里云上部署Django项目MySQL

前端用Vue&#xff0c;后端用Django&#xff0c; nginx&#xff0c;Mysql 参照&#xff1a; 通过WSL在阿里云上部署Vue项目_阿里云 wsl-CSDN博客 阿里云重登录 采用Ubuntu系统&#xff0c; apt update #检查是否已经安装 mysql --version systemctl status mysql apt insta…

react v18 项目初始化

按照以下命令进行傻瓜式操作即可&#xff1a; 全局安装脚手架工具&#xff1a; npm install -g create-react-app创建项目my-react-app&#xff1a; create-react-app my-react-app安装 antd: yarn add antd安装 react-router-dom&#xff1a; yarn add react-router-dom启动项…

【模拟】Leetcode Z 字形变换

题目讲解 6. Z 字形变换 算法讲解 class Solution { public:string convert(string s, int numRows) {if(numRows 1)return s;string ret;int step 2 * numRows - 2;int n s.size();//记录第一行for(int i 0; i < n; i step){ret s[i];}//处理接下来的行for(int i …

C++练级之路——类和对象(中二)

1、运算符重载 C为了增强代码的可读性引入了运算符重载&#xff0c;运算符重载是具有特殊函数名的函数&#xff0c;也是具有其返回值类型&#xff0c;函数名字以及参数列表&#xff0c;其返回值类型和参数列表与普通的函数类似。 函数名字为&#xff1a;关键字operator后面接需…

【前端面试3+1】14 路由跳转的方式、如何取消已经发送的ajax请求、如何按顺序发起三个ajax请求并按顺序返回、【两个数组的并集】

一、路由跳转的几种方式 1、页面跳转 使用超链接 <a> 标签&#xff1a;通过在页面中定义超链接&#xff0c;用户点击超链接后会跳转到指定的URL页面。使用重定向&#xff1a;服务器端可以通过设置HTTP响应头中的Location字段&#xff0c;将用户重定向到指定的URL页面。使…

MySQL Prepared语句(Prepared Statements)

在数据库应用中&#xff0c;很多SQL语句都会重复执行很多次&#xff0c;每次执行可能只是where条件中的变量值不同&#xff0c;但MySQL依然会解析SQL语法并生成执行计划。对于这类情况&#xff0c;可以利用prepared语句来避免重复解析SQL的开销。 文章目录 一、prepared语句优…

职业技能鉴定服务中心(新闻系统+证书查询系统)

后端采用ThinkPHP8&#xff0c;最新tp框架 前端采用divcss布局 数据库采用MySQL 采用三种技术实现新闻系统和证书查询系统 源码&#xff1a;git clone https://gitee.com/3539949703/certificate-website.git 效果图如下&#xff1a;

2024年国内可用最强AI工具软件应用排行榜TOP8——优点和缺点

中国在2024年持续推动人工智能&#xff08;AI&#xff09;发展&#xff0c;受到政策、技术和市场的三重驱动。诞生了一批人工智能&#xff08;AI&#xff09;领域的新力军。我们通过对国内AI的逐一评测&#xff0c;从各个AI处理结果优略的角度&#xff0c;再结合网络上广大AI用…

bootstrap-select 搜索过滤输入中文问题,前2个字母输入转成空格

bootstrap是v3.3.7的 v1.6.3版本的bootstrap-select,注释以下2行 //that.$menu.find(li).filter(:visible:not(.divider)).eq(0).addClass(active).find(a).focus(); // $(this).focus();

学习在Debian系统上安装Shadowsocks教程

学习在Debian系统上安装Shadowsocks教程 安装shadowsocks-libev及其所需的依赖启动Shadowsocks服务&#xff1a;如果你想要通过代理本地流量&#xff0c;你可以使用ss-local&#xff1a;启动并设置ss-local&#xff1a;查看状态本地连接 安装shadowsocks-libev及其所需的依赖 …

mybatisPlus数据字段填充

这里用到的时实体类User import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import lombok.…

【Linux系统编程】第四弹---基本指令(二)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、echo指令 2、cat指令 3、more指令 4、less指令 4、head指令 5、tail指令 6、时间相关的指令 7、cal指令 8、find指…

Python数据结构【二】查找

前言 可私聊进一千多人Python全栈交流群&#xff08;手把手教学&#xff0c;问题解答&#xff09; 进群可领取Python全栈教程视频 多得数不过来的计算机书籍&#xff1a;基础、Web、爬虫、数据分析、可视化、机器学习、深度学习、人工智能、算法、面试题等。 &#x1f680;&a…