RL - 强化学习 蒙特卡洛 (Monte-Carlo) 方法计算状态价值

2023-10-09 19:40

本文主要是介绍RL - 强化学习 蒙特卡洛 (Monte-Carlo) 方法计算状态价值,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

欢迎关注我的CSDN:https://spike.blog.csdn.net/
本文地址:https://blog.csdn.net/caroline_wendy/article/details/131102145

MC

在强化学习中,状态价值 (State Value) 是指在特定状态下,智能体能够从该状态开始执行一系列动作,并且按照某个策略进行决策,所能获得的期望累积回报。状态价值函数用于衡量状态的好坏程度,指导智能体在不同状态下,选择最优的行动。

蒙特卡洛方法是一种基于随机采样和统计的强化学习方法,用于估计值函数或优化策略,得名于摩纳哥的蒙特卡洛赌场,因为这种方法使用了大量的随机模拟。在蒙特卡洛方法中,智能体通过与环境的交互来学习,其基本思想是通过多次采样来估计状态或动作的值函数,并根据估计的值函数进行策略改进。蒙特卡洛方法不需要对环境模型进行假设,只需通过与环境的交互来获得样本。

使用蒙特卡洛方法计算状态价值的具体过程,如下:

  1. 使用策略 π \pi π 采样若干条序列。
  2. 对每一条序列中,每一时间步 t t t 的状态 s s s ,更新计数器 N ( s ) ← N ( s ) + 1 N(s) \leftarrow N(s)+1 N(s)N(s)+1,更新总回报 M ( s ) ← M ( s ) + G t M(s) \leftarrow M(s)+G_{t} M(s)M(s)+Gt
  3. 每一个状态的价值被估计为回报的平均值, V ( s ) = M ( s ) N ( s ) V(s)=\frac{M(s)}{N(s)} V(s)=N(s)M(s)

也可以使用增量更新,即
G ← r + γ ∗ G V ( s ) ← V ( s ) + 1 N ( s ) ( G − V ( s ) ) G \leftarrow r + \gamma*G \\ V(s) \leftarrow V(s) +\frac{1}{N(s)}(G-V(s)) Gr+γGV(s)V(s)+N(s)1(GV(s))
序列的单个步骤是(s,a,r,s_next),即从状态s中,(随机)选择a(s,a)的奖励是r,(随机)跳转至s_next

蒙特卡洛方法的采样源码:

# 把输入的两个字符串通过“-”连接,便于使用上述定义的P、R变量
def join(str1, str2):return str1 + '-' + str2def sample(MDP, Pi, timestep_max, number):"""采样函数:param MDP: MDP的元组:param Pi: 策略:param timestep_max: 最长时间步:param number: 采样的序列数:return: 全部采样"""S, A, P, R, gamma = MDPepisodes = []for _ in range(number):episode = []timestep = 0s = S[np.random.randint(4)]  # 随机选择一个除s5以外的状态s作为起点# 当前状态为终止状态或者时间步太长时,一次采样结束while s != "s5" and timestep <= timestep_max:timestep += 1rand, temp = np.random.rand(), 0# 在状态s下根据策略选择动作for a_opt in A:temp += Pi.get(join(s, a_opt), 0)   # 概率逐渐累加至1if temp > rand:  # 最终一定会选择某个动作 a_opta = a_optr = R.get(join(s, a), 0)breakrand, temp = np.random.rand(), 0# 根据状态转移概率得到下一个状态s_nextfor s_opt in S:temp += P.get(join(join(s, a), s_opt), 0)if temp > rand:  # 概率逐渐累加至1s_next = s_opt  # 最终一定会跳转至下个状态s_optbreakepisode.append((s, a, r, s_next))  # 把(s,a,r,s_next)元组放入序列中s = s_next  # s_next变成当前状态,开始接下来的循环episodes.append(episode)return episodes

计算状态价值的源码:

# 对所有采样序列计算所有状态的价值,不断更新V[s]
def MC(episodes, V, N, gamma):for episode in episodes:G = 0for i in range(len(episode) - 1, -1, -1):  #一个序列从后往前计算(s, a, r, s_next) = episode[i]G = r + gamma * GN[s] = N[s] + 1V[s] = V[s] + (G - V[s]) / N[s]

测试输出:

def main():np.random.seed(0)S = ["s1", "s2", "s3", "s4", "s5"]  # 状态集合A = ["保持s1", "前往s1", "前往s2", "前往s3", "前往s4", "前往s5", "概率前往"]  # 动作集合# 状态转移函数P = {"s1-保持s1-s1": 1.0,"s1-前往s2-s2": 1.0,"s2-前往s1-s1": 1.0,"s2-前往s3-s3": 1.0,"s3-前往s4-s4": 1.0,"s3-前往s5-s5": 1.0,"s4-前往s5-s5": 1.0,"s4-概率前往-s2": 0.2,"s4-概率前往-s3": 0.4,"s4-概率前往-s4": 0.4,}# 奖励函数R = {"s1-保持s1": -1,"s1-前往s2": 0,"s2-前往s1": -1,"s2-前往s3": -2,"s3-前往s4": -2,"s3-前往s5": 0,"s4-前往s5": 10,"s4-概率前往": 1,}gamma = 0.5  # 折扣因子MDP = (S, A, P, R, gamma)# 策略1,随机策略Pi_1 = {"s1-保持s1": 0.5,"s1-前往s2": 0.5,"s2-前往s1": 0.5,"s2-前往s3": 0.5,"s3-前往s4": 0.5,"s3-前往s5": 0.5,"s4-前往s5": 0.5,"s4-概率前往": 0.5,}# 采样5次,每个序列最长不超过20步episodes = sample(MDP, Pi_1, 20, 5)print('第一条序列\n', episodes[0])print('第二条序列\n', episodes[1])print('第五条序列\n', episodes[4])timestep_max = 20# 采样1000次,可以自行修改episodes = sample(MDP, Pi_1, timestep_max, 1000)gamma = 0.5V = {"s1": 0, "s2": 0, "s3": 0, "s4": 0, "s5": 0}N = {"s1": 0, "s2": 0, "s3": 0, "s4": 0, "s5": 0}MC(episodes, V, N, gamma)print("使用蒙特卡洛方法计算MDP的状态价值为\n", V)if __name__ == '__main__':main()

输出结果:

# 使用蒙特卡洛方法计算MDP的状态价值{'s1': -1.228923788722258, 's2': -1.6955696284402704, 's3': 0.4823809701532294, 's4': 5.967514743019431, 's5': 0}# 通过MRP计算的状态价值[[-1.22555411] [-1.67666232] [ 0.51890482] [ 6.0756193 ] [ 0.        ]]

状态价值,可以用于计算状态动作价值,具有指导意义。

这篇关于RL - 强化学习 蒙特卡洛 (Monte-Carlo) 方法计算状态价值的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/175120

相关文章

Python安装Pandas库的两种方法

《Python安装Pandas库的两种方法》本文介绍了三种安装PythonPandas库的方法,通过cmd命令行安装并解决版本冲突,手动下载whl文件安装,更换国内镜像源加速下载,最后建议用pipli... 目录方法一:cmd命令行执行pip install pandas方法二:找到pandas下载库,然后

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

SQL Server安装时候没有中文选项的解决方法

《SQLServer安装时候没有中文选项的解决方法》用户安装SQLServer时界面全英文,无中文选项,通过修改安装设置中的国家或地区为中文中国,重启安装程序后界面恢复中文,解决了问题,对SQLSe... 你是不是在安装SQL Server时候发现安装界面和别人不同,并且无论如何都没有中文选项?这个问题也

Java Thread中join方法使用举例详解

《JavaThread中join方法使用举例详解》JavaThread中join()方法主要是让调用改方法的thread完成run方法里面的东西后,在执行join()方法后面的代码,这篇文章主要介绍... 目录前言1.join()方法的定义和作用2.join()方法的三个重载版本3.join()方法的工作原

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

Spring Boot从main方法到内嵌Tomcat的全过程(自动化流程)

《SpringBoot从main方法到内嵌Tomcat的全过程(自动化流程)》SpringBoot启动始于main方法,创建SpringApplication实例,初始化上下文,准备环境,刷新容器并... 目录1. 入口:main方法2. SpringApplication初始化2.1 构造阶段3. 运行阶

Olingo分析和实践之ODataImpl详细分析(重要方法详解)

《Olingo分析和实践之ODataImpl详细分析(重要方法详解)》ODataImpl.java是ApacheOlingoOData框架的核心工厂类,负责创建序列化器、反序列化器和处理器等组件,... 目录概述主要职责类结构与继承关系核心功能分析1. 序列化器管理2. 反序列化器管理3. 处理器管理重要方

Python错误AttributeError: 'NoneType' object has no attribute问题的彻底解决方法

《Python错误AttributeError:NoneTypeobjecthasnoattribute问题的彻底解决方法》在Python项目开发和调试过程中,经常会碰到这样一个异常信息... 目录问题背景与概述错误解读:AttributeError: 'NoneType' object has no at

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数