强化学习笔记:基于策略的学习之策略迭代(python实现)

news2024/9/21 10:49:22

目录

 

1. 前言

2. 算法流程

3. 代码及仿真结果

3.1 class PolicyIterationPlanner()

3.2 测试代码

3.3 运行结果

3.3.1 价值估计结果

3.3.2 策略迭代得到的最终策略


1. 前言


        在强化学习中,根据是否依赖于(环境的)模型,可以分为有模型(model-based)学习和无模型(model-free)学习。根据行动的决策基准,可以分为基于价值的学习(value-based)和基于策略学习(policy-based)。

        在基于价值的学习中,根据状态值函数(state-value function)值或者动作值函数的值,进行行动决策。总是选择从当前状态出发可能到达的下一个状态中价值最大的那个状态所对应的行动。

        前面两篇分别介绍了直接求解贝尔曼方程进行价值计算以及以迭代的方式求解价值近似(value iteration):

        强化学习笔记:基于价值的学习之价值计算(python实现)

        强化学习笔记:基于价值的学习之价值迭代(python实现)

        本篇进一步介绍基于策略的学习的策略迭代算法原理及其实现。

2. 算法流程

        策略迭代包括策略评估(policy evaluation)和策略提升(policy improvement)。

        策略评估是指基于当前策略进行值函数评估,本身也是(可以)以迭代的方式求解。基于策略的价值评估应该是要计算价值的期望值,与价值迭代中的价值评估略有不同。但是,由于(如下所示,策略迭代所得到的策略本身是确定性的策略,所以这个期望值也退化成当前策略下最佳行动的价值了)。每次迭代中进行策略评估时,值函数(value function)的初始值是上一个策略(policy)的值函数,这样通常会提高策略评估的收敛速度,这是因为相邻两个策略的值函数改变很小。

        策略提升则是指当由策略所得到的行动与基于价值的最佳行动不一致时进行策略更新。

        Sutton-book#4.3所给出的策略迭代流程如下所示:

        翻成大白话如下所示:

        价值和策略初始化:价值初始化为0,各状态下所有各行动的概率指定为相等的概率(虽然初始化为任意值都可以,但是这是最合理的选择)

        Iteration直到收敛:

  1. 基于策略进行状态值评估(期望值):但是,实际上由于策略迭代中的策略是确定性的策略,所以这里的期望值退化成了最佳行动的状态值了。
  2. 基于状态值最大化准则更新策略。针对每一个状态
    1. 基于当前策略所得到的行动(即概率最大的那个行动)action_by_policy
    2. 评估各行动的价值Q(s,a)据此得到行动价值最大的行动best_action_by_value
    3. 判断两者是否一致(action_by_policy==best_action_by_value?)
      1. 如果每个状态下的都满足(action_by_policy==best_action_by_value),则停止迭代
      2. 否则,以贪婪(这个是必然的吗?)的方式更新策略。即将每个状态s下对应最佳行动的policy[s][a]置为1,其余置为0

        更简单地可以以如下的示意图表示: 

        策略迭代与值迭代之间的关系【3】:

        策略迭代中包含值迭代,策略评估是基于价值估计进行的,而价值估计是以值迭代的方式进行的。值迭代算法是策略评估过程只进行一次迭代的策略迭代算法。

3. 代码及仿真结果

3.1 class PolicyIterationPlanner()

        estimate_by_policy()用于在当前策略下估计状态期望值,该状态期望值用于第(2)步中的基于价值的最佳行动选择。estimate_by_policy()与ValueIterationPlanner中的价值估计略有不同,这里是估计期望值(但是实际上由于是确定性策略,所以实际上也退化为当前策略下的最佳行动的价值),而后者是直接估计最佳行动的价值。

        plan()实现了上一章所描述的流程。在迭代过程中将每次迭代后的价值估计结果打印出来,以方便结果的观测和理解。

        print_policy()用于将最后得到的策略打印出来。

class PolicyIterationPlanner(Planner):

    def __init__(self, env):
        super().__init__(env)
        self.policy = {}

    def initialize(self):
        super().initialize()
        self.policy = {}
        actions = self.env.actions
        states = self.env.states
        for s in states:
            self.policy[s] = {}
            for a in actions:
                # Initialize policy.
                # At first, each action is taken uniformly.
                self.policy[s][a] = 1 / len(actions)

    def estimate_by_policy(self, gamma, threshold):
        V = {}
        for s in self.env.states:
            # Initialize each state's expected reward.
            V[s] = 0

        while True:
            delta = 0
            for s in V:
                expected_rewards = []
                for a in self.policy[s]:
                    action_prob = self.policy[s][a]
                    r = 0
                    for prob, next_state, reward in self.transitions_at(s, a):
                        r += action_prob * prob * \
                             (reward + gamma * V[next_state])
                    expected_rewards.append(r)
                value = sum(expected_rewards)
                delta = max(delta, abs(value - V[s]))
                V[s] = value
            if delta < threshold:
                break

        return V

    def plan(self, gamma=0.9, threshold=0.0001):
        self.initialize()
        states = self.env.states
        actions = self.env.actions

        def take_max_action(action_value_dict):
            return max(action_value_dict, key=action_value_dict.get)

        while True:
            update_stable = True
            # Estimate expected rewards under current policy.
            V = self.estimate_by_policy(gamma, threshold)
            self.log.append(self.dict_to_grid(V))

            for s in states:
                # Get an action following to the current policy.
                policy_action = take_max_action(self.policy[s])

                # Compare with other actions.
                action_rewards = {}
                for a in actions:
                    r = 0
                    for prob, next_state, reward in self.transitions_at(s, a):
                        r += prob * (reward + gamma * V[next_state])
                    action_rewards[a] = r
                best_action = take_max_action(action_rewards)
                if policy_action != best_action:
                    update_stable = False

                # Update policy (set best_action prob=1, otherwise=0 (greedy))
                for a in self.policy[s]:
                    prob = 1 if a == best_action else 0
                    self.policy[s][a] = prob

            # Turn dictionary to grid
            self.V_grid = self.dict_to_grid(V)
            self.iters = self.iters + 1
            print('PolicyIteration: iters = {0}'.format(self.iters))
            self.print_value_grid()
            print('******************************')

            if update_stable:
                # If policy isn't updated, stop iteration
                break

    def print_policy(self):
        print('PolicyIteration: policy = ')
        actions = self.env.actions
        states = self.env.states
        for s in states:
            print('\tstate = {}'.format(s))
            for a in actions:
                print('\t\taction = {0}, prob = {1}'.format(a,self.policy[s][a]))

3.2 测试代码

        测试代码如下(作为对比,对valueIterPlanner也有一些修改,将中间结果打印出来了以方便对比):

if __name__ == "__main__":

    # Create grid environment
    grid = [
        [0, 0, 0, 1],
        [0, 9, 0, -1],
        [0, 0, 0, 0]
    ]
        
    env1 = Environment(grid)
    valueIterPlanner = ValueIterationPlanner(env1)
    valueIterPlanner.plan(0.9,0.001)
    valueIterPlanner.print_value_grid()

    env2 = Environment(grid)
    policyIterPlanner = PolicyIterationPlanner(env2)
    policyIterPlanner.plan(0.9,0.001)
    policyIterPlanner.print_value_grid()    
    policyIterPlanner.print_policy()    

3.3 运行结果

3.3.1 价值估计结果

ValueIteration: iters = 1
-0.040 -0.040  0.792  0.000
-0.040  0.000  0.434  0.000
-0.040 -0.040  0.269  0.058
******************************
......
ValueIteration: iters = 10
 0.610  0.766  0.928  0.000
 0.487  0.000  0.585  0.000
 0.374  0.327  0.428  0.189
******************************

PolicyIteration: iters = 1
-0.270 -0.141  0.102  0.000
-0.345  0.000 -0.487  0.000
-0.399 -0.455 -0.537 -0.728
******************************
......
PolicyIteration: iters = 4
 0.610  0.766  0.928  0.000
 0.487  0.000  0.585  0.000
 0.374  0.327  0.428  0.189
******************************

        价值迭代和策略迭代得到的最终价值估计结果是相同的。 但是策略迭代只用了4次迭代就收敛了,而价值迭代则用了10次迭代。

3.3.2 策略迭代得到的最终策略

        策略迭代最终得到的策略结果如下所示:

PolicyIteration: policy =
        state = <State: [0, 0]>
                action = Action.UP, prob = 0
                action = Action.DOWN, prob = 0
                action = Action.LEFT, prob = 0
                action = Action.RIGHT, prob = 1
        state = <State: [0, 1]>
                action = Action.UP, prob = 0
                action = Action.DOWN, prob = 0
                action = Action.LEFT, prob = 0
                action = Action.RIGHT, prob = 1
        state = <State: [0, 2]>
                action = Action.UP, prob = 0
                action = Action.DOWN, prob = 0
                action = Action.LEFT, prob = 0
                action = Action.RIGHT, prob = 1
        state = <State: [0, 3]>
                action = Action.UP, prob = 1
                action = Action.DOWN, prob = 0
                action = Action.LEFT, prob = 0
                action = Action.RIGHT, prob = 0
        state = <State: [1, 0]>
                action = Action.UP, prob = 1
                action = Action.DOWN, prob = 0
                action = Action.LEFT, prob = 0
                action = Action.RIGHT, prob = 0
        state = <State: [1, 2]>
                action = Action.UP, prob = 1
                action = Action.DOWN, prob = 0
                action = Action.LEFT, prob = 0
                action = Action.RIGHT, prob = 0
        state = <State: [1, 3]>
                action = Action.UP, prob = 1
                action = Action.DOWN, prob = 0
                action = Action.LEFT, prob = 0
                action = Action.RIGHT, prob = 0
        state = <State: [2, 0]>
                action = Action.UP, prob = 1
                action = Action.DOWN, prob = 0
                action = Action.LEFT, prob = 0
                action = Action.RIGHT, prob = 0
        state = <State: [2, 1]>
                action = Action.UP, prob = 0
                action = Action.DOWN, prob = 0
                action = Action.LEFT, prob = 0
                action = Action.RIGHT, prob = 1
        state = <State: [2, 2]>
                action = Action.UP, prob = 1
                action = Action.DOWN, prob = 0
                action = Action.LEFT, prob = 0
                action = Action.RIGHT, prob = 0
        state = <State: [2, 3]>
                action = Action.UP, prob = 0
                action = Action.DOWN, prob = 0
                action = Action.LEFT, prob = 1
                action = Action.RIGHT, prob = 0

        这个结果可以图示化如下(【4】,忽略以上结果中在[0,3]和[1,3]的结果):

【思考】

        以上策略迭代中的策略更新方式只能以greedy的方式进行吗?以greedy的方式进行策略更新,最后得到的策略也必然是确定性的策略,即在每个状态下,只有某一个最佳行动的概率为1,其余行动的概率为0。

强化学习笔记:强化学习笔记总目录

完整代码参见::reinforcement-learning/value_eval at main · chenxy3791/reinforcement-learning (github.com)

参考文献:

【1】Sutton, et, al, Introduction to reinforcement learning (2020)

【2】久保隆宏著,用Python动手学习强化学习

【3】策略迭代(Policy Iteration)和值迭代(Value Iteration) - 知乎 (zhihu.com)

【4】Policy iteration — Introduction to Reinforcement Learning (gibberblot.github.io)

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

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

相关文章

OAK相机与树莓派

编辑&#xff1a;OAK中国 首发&#xff1a;oakchina.cn 喜欢的话&#xff0c;请多多&#x1f44d;⭐️✍ 内容可能会不定期更新&#xff0c;官网内容都是最新的&#xff0c;请查看首发地址链接。 ▌前言 Hello&#xff0c;大家好&#xff0c;这里是OAK中国&#xff0c;我是助手…

机器人中的数值优化之修正阻尼牛顿法

本文ppt来自深蓝学院《机器人中的数值优化》 目录 1 Newtons Method 2 Pratical Newtons Method 1 Newtons Method 当我们引入函数的二阶信息就考虑到了curvature info&#xff0c;这里先对函数进行泰勒展开&#xff0c;取二阶近似&#xff0c;对近似后的函数取最优解&#…

springboot 线程池

为什么要使用线程池 使用线程池之后&#xff0c;不需要频繁的去创建和销毁线程&#xff08;比如项目中手动创建线程&#xff0c;new Thread 类&#xff0c;我们可以把创建和销毁的线程的过程去掉&#xff09;&#xff0c;从而让线程得到重复的使用。并且可以对线程进行统一的管…

手把手教你用 Python 搭建一个图像分类器

深度学习是使用人工神经网络进行机器学习的一个子集&#xff0c;目前已经被证明在图像分类方面非常强大。 尽管这些算法的内部工作在数学上是严格的&#xff0c;但 Python 库(比如 keras)使这些问题对我们所有人都可以接近。 在本文中&#xff0c;我将介绍一个简单的图像分类…

机器人中的数值优化之最速下降法

本文ppt来自深蓝学院《机器人中的数值优化》 目录 1 迭代方向 2 步长的选择 3 Armijo condition 4 非精确线搜索的优势 1 迭代方向 梯度方向是函数上升最快的方向&#xff0c;而负梯度方向则是函数下降最快的方向&#xff0c;因此最速下降法就是以负梯度方向为迭代方向…

二叉树的构造和相关功能的代码实现及解析

目录 一.二叉树类的定义 二.构造二叉树&#xff08;构造函数&#xff09; 三.为二叉树插入节点(insert_value) 四.移除根节点(remove_root,lchild_leaf) 五.移除二叉树中的某值(remove,remove_value) 六.清空二叉树 七.前、中、后序遍历 一.二叉树类的定义 二叉树类的定…

Django入门学习-了解基本模块

目录 MVT设计了解 认识MVT 实际操作 Template&#xff1a; View: 路由配置 Model: 默认的后台管理模块 初始化admin模块 应用中Admin注册 MVT设计了解 认识MVT Django的web设计模型是MVT&#xff1a; Model&#xff1a;数据存储层&#xff0c;处理所有数据相关的业…

idea+ApifoxUploader+Apifox真是内外双修,香

前言 最近部门为整合后端组、前端组、测试组、需求组、产品组等组之间的工作流程&#xff0c;旨在提高协调与高效&#xff0c;其中之一就是希望开发组&#xff08;后端、前端&#xff09;开发的接口能及时更新&#xff0c;测试组能做接口测试&#xff0c;后期方便出文档&#x…

大公司为什么禁止SpringBoot项目使用Tomcat?

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/…

【2】burpsuite屏蔽浏览器无用流量包方法

0x01 问题描述经常会使用火狐或者谷歌去burpsuite对站点进行测试&#xff0c;但是在测试的过程中burpsuite经常抓到火狐浏览器自身的数据包或者其他无用的数据包&#xff0c;这就对我们工作的效率大有影响&#xff0c;所以这里来告诉大家如何解决此类问题。0x02 问题复现访问网…

星环科技数据治理与数据价值评估实践分享

数据价值评估背景 自2015年8月国务院《促进大数据发展行动纲要》提出“数据已成为国家基础性战略资源”以来&#xff0c;我国出台了诸多政策和法案&#xff0c;推进数据的发展和数据要素的资产化。 2019年10月&#xff0c;第十九届四中全会关于《推进国家治理体系和治理能力现…

Node.js安装详细教程

安装 Node.js 官网下载安装包https://nodejs.org/zh-cn/&#xff0c;一直【下一步】安装即可。 设置Windows操作系统全局环境变量 为什么设置环境变量&#xff1f; 当我们在cmd命令行中输入命令时&#xff0c;系统首先会在当前目录下去找命令对应的可执行程序&#xff0c;如果…

后端校验(hibernate-validator)

目录一、介绍和依赖二、方法的 Model 参数校验三、方法的非 Model 参数校验四、常用注解五、快速失败六、自定义校验规则一、介绍和依赖 hibernate-validator 是 Java 中常用的后端校验框架 https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/【…

提取各种数据结构中的元素将提取结果合并为迭代对象 itertools.chain(*a,b)

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 提取各种数据结构中的元素 将提取结果合并为迭代对象 itertools.chain(*a,b) [太阳]选择题 以下python代码最后输出正确的一项是? from itertools import chain a[(1, A), (2, B), …

Java高效率复习-线程基础[线程]

内容大纲 线程相关概念 并发并行 当只有一个CPU时&#xff0c;会执行并发的效果&#xff0c;在多个应用程序之间快速切换&#xff0c;而有多个CPU时&#xff0c;则多个CPU独立执行&#xff0c;而当进程多于CPU个数时&#xff0c;则会出现并发并行的情况&#xff0c;总有一个CPU…

如何炼就数据分析的思维?

目录 前言结构化思维假说演绎思维指标化思维维度分析思维 前言 面对数据异常&#xff0c;我们经常会出现“好像是A原因引起的&#xff1f;”“貌似和B原因也相关&#xff1f;““有可能是 C操作不当“的主观臆测。 或者&#xff0c;拿到一个分析议题&#xff0c;分析”11 月销售…

@ConfigurationProperties注解使用方法(内含源代码)

ConfigurationProperties注解使用方法&#xff08;内含源代码&#xff09; 源代码下载链接地址&#xff1a;https://download.csdn.net/download/weixin_46411355/87400774 目录ConfigurationProperties注解使用方法&#xff08;内含源代码&#xff09;源代码下载链接地址&…

怎么识别截图中的文字?这三个方法让你轻松学会

在日常工作或学习中&#xff0c;我们会经常在网上查阅一些资料&#xff0c;当遇到一些优美的句子或者段落时&#xff0c;都会手动摘抄下来&#xff0c;这种记录方式不仅很耗时&#xff0c;还耗费精力&#xff0c;并且现在很多网站都已经不支持文本复制了&#xff0c;遇到这种情…

6.验证面试高频问题整理(附答案)

目录 Q126.top-down phase、bottom-up phase有哪些 Q127.为什么build_phase是top-down phase&#xff0c;connect_phase是bottom-up phase Q128.$size用于packed array和unpacked array分别得到的什么 Q129.class和struct的异同 Q130.class和module的异同 Q131.对象创建的…

MAC系统 LightGBM模型转为pmml格式

一、配置JAVA环境和Maven环境 参考以下两个博客即可 MAC 系统安装 JDK 及环境变量配置_蜗牛的博客-CSDN博客_mac jdk环境变量配置 MAC 系统安装 Maven 及环境变量配置_蜗牛的博客-CSDN博客_mac安装mpv 二、下载JPMML-LightGBM 先在Git上下载 直接下载或使用git clone http…