【强化学习】《动手学强化学习》动态规划算法

news/2024/5/6 23:55:09/文章来源:https://blog.csdn.net/dzc_go/article/details/126896965

【强化学习】《动手学强化学习》动态规划算法

      • 一、基本思想
      • 二、悬崖漫步环境
      • 三、策略迭代算法
        • 3.1 策略评估
        • 3.2 策略提升
        • 3.3 悬崖漫步环境下的策略迭代
      • 四、价值迭代算法

一、基本思想

  • 动态规划算法在计算机专业课中是特别重要的思想,将待求问题分解成若干个子问题,先求解子问题,然后利用子问题的解得到目标问题的解。贝尔曼方程将当前阶段的最优决策问题转化为下一阶段的最优决策问题,从而初始状态的最优决策可以由终状态的最优决策(一般易解)问题逐步迭代求解。
  • 本篇文章介绍如何用动态规划的思想来求解马尔可夫决策过程中的最优策略。基于动态规划的强化学习算法主要有两种:策略迭代价值迭代。策略迭代由两部分组成:策略评估与策略提升。策略评估使用贝尔曼期望方程来得到一个策略的状态价值函数;价值迭代直接使用贝尔曼最优方程来进行动态规划。
  • 所有的动态规划强化学习算法必须要求都是基于模型的(model-based),即知道完整的MDP信息才能够使用贝尔曼方程进行迭代更新。如果无法得知完整MDP信息,就只能通过和环境进行交互采样。

二、悬崖漫步环境

  • 4行12列的网格地图,左下角是起点,右下角是终点,最下方一行除了起点和终点以外都是悬崖。智能体的位置便是状态,在每个状态都可以执行上、下、左、右四个动作,如果触碰到边界则状态不变。终结状态是最下方一行除了起点以外的所有格子。智能体每走一步奖励-1,掉入悬崖奖励-100,在此激励下智能体想要用最短的步数到达终点。示意图如下
    在这里插入图片描述
class CliffWalkingEnv:""" 悬崖漫步环境"""def __init__(self, ncol=12, nrow=4):self.ncol = ncol  # 定义网格世界的列self.nrow = nrow  # 定义网格世界的行# 转移矩阵P[state][action] = [(p, next_state, reward, done)]包含下一个状态和奖励# P含有48个list,每个list包含4个list,每个list包含一个四元组(p,next_state,reward,done)self.P = self.createP()def createP(self):# 初始化P = [[[] for j in range(4)] for i in range(self.nrow * self.ncol)]# 4种动作, change[0]:上,change[1]:下, change[2]:左, change[3]:右。坐标系原点(0,0)定义在左上角change = [[0, -1], [0, 1], [-1, 0], [1, 0]]for i in range(self.nrow):for j in range(self.ncol):# 遍历每个位置,即每个状态for a in range(4):# 遍历每个状态的4个动作# 位置在悬崖或者目标状态,因为无法继续交互,任何动作奖励都为0if i == self.nrow - 1 and j > 0:P[i * self.ncol + j][a] = [(1, i * self.ncol + j, 0, True)]continue# 其他位置# 与0取max是判断是否触碰左边界,与self.ncol-1取min是判断是否触碰右边界。next_x = min(self.ncol - 1, max(0, j + change[a][0]))# 与0取max是判断是否触碰上边界,与self.nrow-1取min是判断是否触碰下边界。next_y = min(self.nrow - 1, max(0, i + change[a][1]))next_state = next_y * self.ncol + next_xreward = -1done = False# 下一个位置在悬崖或者终点if next_y == self.nrow - 1 and next_x > 0:done = Trueif next_x != self.ncol - 1:  # 下一个位置在悬崖reward = -100P[i * self.ncol + j][a] = [(1, next_state, reward, done)]return P
  • 上述环境代码的编写核心在于状态转移矩阵的编写。转移矩阵PPP共有48个(4x12)个list,每个list包含4个list对应4个动作,每个list包含一个4元组(转移概率,下一状态,奖励,是否终结)。

三、策略迭代算法

  • 策略迭代是策略评估和策略提升不断循环交替,直至最后得到最优策略的过程。策略评估是计算一个状态价值函数的过程;策略提升是优化当前策略的过程。如果策略提升之后的策略与之前相同说明此时策略迭代算法已达到了收敛状态,此时的策略即为最优策略。

3.1 策略评估

  • 策略评估说白了就是计算当前策略下的状态价值函数。
  • 首先来看一下之前提及的贝尔曼期望方程:
    Vπ(s)=∑a∈Aπ(a∣s)(r(s,a)+γ∑s′∈SP(s′∣s,a)Vπ(s′))V^{\pi}(s)=\sum_{a\in A}\pi(a|s)(r(s,a)+\gamma\sum_{s'\in S}P(s'|s,a)V^{\pi}(s')) Vπ(s)=aAπ(as)(r(s,a)+γsSP(ss,a)Vπ(s))
    其中π(a∣s)\pi(a|s)π(as)由策略决定,r(s,a),P(s′∣s,a)r(s,a),P(s'|s,a)r(s,a),P(ss,a)由MDP决定。因此上述贝尔曼期望方程可以看作,在策略确定以及MDP确定的情况下,利用状态sss可转移到的所有周边状态s′s's的价值函数来计算sss的价值函数。
  • 策略评估是一个循环迭代的过程,第k+1轮中状态sss的价值函数使用第k轮中与之相关的状态s′s's的价值函数来求解。当迭代轮次最够多时,认为当前价值函数逼近或者就是真正的价值函数。实际应用中策略评估使用贝尔曼期望函数进行迭代使用大量计算资源,无须迭代无限轮次,只需要某次迭代更新的幅度非常小时算法即可停止。

3.2 策略提升

  • 策略评估之后,我们获得了在当前策略下所有状态的价值函数,也就是得到了在当前策略下每个状态出发到达终结状态的期望回报。得到了状态价值函数,也就相当于得到了动作价值函数。我们便可以在当前策略的基础上每个状态都贪心地选择最优的动作aaa以最大化Qπ(s,a)Q^{\pi}(s,a)Qπ(s,a),从而实现策略提升。
    π′(s)=arg⁡max⁡aQπ(s,a)=arg⁡max⁡a{r(s,a)+γ∑s′P(s′∣s,a)Vπ(s′)}\begin{equation} \begin{split} \pi'(s)&=\arg \max_aQ^{\pi}(s,a)\\ &=\arg \max_a\{r(s,a)+\gamma \sum_{s'}P(s'|s,a)V^{\pi}(s')\}\\ \end{split} \end{equation} π(s)=argamaxQπ(s,a)=argamax{r(s,a)+γsP(ss,a)Vπ(s)}
  • 贪心算法与贪心策略我们需要考虑的问题是,局部最优的累积最终是否达到全局最优。在策略提升中需要考虑的问题是,每个状态都选择动作价值最大的动作得到的新策略π′\pi'π是否在每个状态的价值都不低于原策略π\piπ在该状态的价值。证明如下:
    Vπ(s)≤Qπ(s,π′(s))=Eπ′[Rt+γVπ(St+1)∣St=s]≤Eπ′[Rt+γQπ(St+1,π′(St+1))∣St=s]=Eπ′[Rt+γRt+1+γ2Vπ(St+2)∣St=s]≤Eπ′[Rt+γRt+1+γ2Rt+2+γ3Vπ(St+3)∣St=s]...≤Eπ′[Rt+γRt+1+γ2Rt+2+γ3Rt+3+...∣St=s]=Vπ′(s)\begin{equation} \begin{split} V^{\pi}(s)&\le Q^{\pi}(s,\pi'(s))\\ &=E_{\pi'}[R_t+\gamma V^{\pi}(S_{t+1})|S_t=s]\\ &\le E_{\pi'}[R_t+\gamma Q^{\pi}(S_{t+1},\pi'(S_{t+1}))|S_t=s]\\ &=E_{\pi'}[R_t+\gamma R_{t+1}+\gamma^2 V^{\pi}(S_{t+2})|S_t=s]\\ &\le E_{\pi'}[R_t+\gamma R_{t+1}+\gamma^2 R_{t+2} + \gamma^3 V^{\pi}(S_{t+3}) |S_t=s] \\ &...\\ &\le E_{\pi'}[R_t+\gamma R_{t+1}+\gamma^2 R_{t+2} + \gamma^3 R_{t+3}+... |S_t=s]\\ &=V^{\pi'}(s) \end{split} \end{equation} Vπ(s)Qπ(s,π(s))=Eπ[Rt+γVπ(St+1)St=s]Eπ[Rt+γQπ(St+1,π(St+1))St=s]=Eπ[Rt+γRt+1+γ2Vπ(St+2)St=s]Eπ[Rt+γRt+1+γ2Rt+2+γ3Vπ(St+3)St=s]...Eπ[Rt+γRt+1+γ2Rt+2+γ3Rt+3+...∣St=s]=Vπ(s)

3.3 悬崖漫步环境下的策略迭代

import copyclass PolicyIteration:""" 策略迭代算法 """def __init__(self, env, theta, gamma):self.env = envself.v = [0] * self.env.ncol * self.env.nrow  # 初始化价值为0self.pi = [[0.25, 0.25, 0.25, 0.25] for i in range(self.env.ncol * self.env.nrow)]  # 初始化为均匀随机策略self.theta = theta  # 策略评估收敛阈值self.gamma = gamma  # 折扣因子def policy_evaluation(self):  # 策略评估cnt = 1  # 计数器while 1:max_diff = 0new_v = [0] * self.env.ncol * self.env.nrow  # 定义一个新容器for s in range(self.env.ncol * self.env.nrow):qsa_list = []  # 开始计算状态s下的所有Q(s,a)价值for a in range(4):qsa = 0for res in self.env.P[s][a]:p, next_state, r, done = resqsa += p * (r + self.gamma * self.v[next_state] * (1 - done))qsa_list.append(self.pi[s][a] * qsa)new_v[s] = sum(qsa_list)  # 状态价值函数和动作价值函数之间的关系max_diff = max(max_diff, abs(new_v[s] - self.v[s]))self.v = new_vif max_diff < self.theta:break  # 满足收敛条件,退出评估迭代cnt += 1print("策略评估进行%d轮后完成" % cnt)def policy_improvement(self):  # 策略提升for s in range(self.env.nrow * self.env.ncol):qsa_list = []for a in range(4):qsa = 0for res in self.env.P[s][a]:p, next_state, r, done = resqsa += p * (r + self.gamma * self.v[next_state] * (1 - done))qsa_list.append(qsa)maxq = max(qsa_list)cntq = qsa_list.count(maxq)  # 计算有几个动作得到了最大的Q值# 让这些动作均分概率self.pi[s] = [1 / cntq if q == maxq else 0 for q in qsa_list]print("策略提升完成")return self.pidef policy_iteration(self):  # 策略迭代while 1:self.policy_evaluation()old_pi = copy.deepcopy(self.pi)  # 将列表进行深拷贝,方便接下来进行比较new_pi = self.policy_improvement()if old_pi == new_pi:break
  • 读者可能会纳闷为啥代码中qsa的计算方法与公式不同?具体来说,公式中状态转移概率在括号内部,代码中状态转移概率在括号外部并且括号内还乘了(1−done)(1-done)(1done)。这个问题跟环境的设定有关。本文环境中,并不是在状态sss下做出动作决策aaa就立即获得当前轮次的奖励,而是在真正迁移到下一状态之后才获得对应奖励,这就解释了为什么转移概率在括号外面。本文还设定转移到终结状态后奖励为0,因此乘以(1−done)(1-done)(1done)
  • 策略提升部分,每次都是以混合策略的形式提升。得到每个状态sss动作价值函数最大的几个动作,将概率111平均分配到上述动作中。
  • 一个完整的强化学习项目一般包含三大模块,具体来说是三个.py文件。env.py、RL_brain.py、main.py。其中env.py定义了该问题的环境,包括智能体与环境的交互过程以及可视化过程;RL_brain.py定义了该问题所使用的RL算法;main.py包含该问题的主控逻辑。

四、价值迭代算法

  • 在策略迭代算法中显示定义了策略,策略具体来说是面对每个状态选择不同动作的混合策略。策略迭代的策略评估过程需要很多轮才可以收敛,整个算法运行下来需要很大的计算量。价值迭代算法直接通过选择最大化状态价值函数/动作价值函数来产生最优策略,每次“策略”更新(实际上就是状态价值函数更新)都只需要一次状态价值函数的更新。
  • 状态价值函数的贝尔曼最优方程如下所示:
    V∗(s)=max⁡a∈A{r(s,a)+γ∑s′∈SP(s′∣s,a)V∗(s′)}V^*(s)=\max_{a\in A}\{r(s,a)+\gamma \sum_{s'\in S}P(s'|s,a)V^*(s')\} V(s)=aAmax{r(s,a)+γsSP(ss,a)V(s)}
    将其写成迭代更新的方式如下:
    Vk+1(s)=max⁡a∈A{r(s,a)+γ∑s′∈SP(s′∣s,a)Vk(s′)}V^{k+1}(s)=\max_{a\in A}\{r(s,a)+\gamma \sum_{s'\in S}P(s'|s,a)V^k(s')\} Vk+1(s)=aAmax{r(s,a)+γsSP(ss,a)Vk(s)}
    迭代更新到Vk+1V^{k+1}Vk+1VkV^kVk相同或差距很小时,此时对应着最优状态价值函数V∗(s)V^*(s)V(s),利用最优状态价值函数便可以复原出最优策略。
    π(s)=arg⁡max⁡a{r(s,a)+γ∑s′∈SP(s′∣s,a)V∗(s′)}\pi(s)=\arg \max_{a}\{r(s,a)+\gamma \sum_{s'\in S}P(s'|s,a)V^*(s')\} π(s)=argamax{r(s,a)+γsSP(ss,a)V(s)}
  • 悬崖漫步环境下的价值迭代代码如下所示:
class ValueIteration:""" 价值迭代算法 """def __init__(self, env, theta, gamma):self.env = envself.v = [0] * self.env.ncol * self.env.nrow  # 初始化价值为0self.theta = theta  # 价值收敛阈值self.gamma = gamma# 价值迭代结束后得到的策略self.pi = [None for i in range(self.env.ncol * self.env.nrow)]def value_iteration(self):cnt = 0while 1:max_diff = 0new_v = [0] * self.env.ncol * self.env.nrowfor s in range(self.env.ncol * self.env.nrow):qsa_list = []  # 开始计算状态s下的所有Q(s,a)价值for a in range(4):qsa = 0for res in self.env.P[s][a]:p, next_state, r, done = resqsa += p * (r + self.gamma * self.v[next_state] * (1 - done))qsa_list.append(qsa)  # 这一行和下一行代码是价值迭代和策略迭代的主要区别new_v[s] = max(qsa_list)max_diff = max(max_diff, abs(new_v[s] - self.v[s]))self.v = new_vif max_diff < self.theta: break  # 满足收敛条件,退出评估迭代cnt += 1print("价值迭代一共进行%d轮" % cnt)self.get_policy()def get_policy(self):  # 根据价值函数导出一个贪婪策略for s in range(self.env.nrow * self.env.ncol):qsa_list = []for a in range(4):qsa = 0for res in self.env.P[s][a]:p, next_state, r, done = resqsa += p * (r + self.gamma * self.v[next_state] * (1 - done))qsa_list.append(qsa)maxq = max(qsa_list)cntq = qsa_list.count(maxq)  # 计算有几个动作得到了最大的Q值# 让这些动作均分概率self.pi[s] = [1 / cntq if q == maxq else 0 for q in qsa_list]

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Springboot 集成kafka

一、创建项目并导入pom依赖 <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId> </dependency> 二、修改application.yml配置 1. producer 生产端的配置 spring:#重要提示:kafka配置,该…

Redis介绍和安装

Redis介绍 Redis是一个开源的、基于Key-Value(键-值&#xff09;存储的NoSQL数据库。Redis因其丰富的数据结构、极快的速度、齐全的功能而为人所知&#xff0c;它是目前内存数据库方面的事实标准&#xff0c;是目前使用广泛的开源缓存中间件。 Redis特点 结构丰富&#xff0…

CS231a课程笔记:Lecture2 Camera Models

关于齐次坐标&#xff1a;(15条消息) 为什么要引入齐次坐标&#xff0c;齐次坐标的意义&#xff08;一&#xff09;_追求卓越583的博客-CSDN博客_齐次坐标的意义(15条消息) 为什么要引入齐次坐标&#xff0c;齐次坐标的意义&#xff08;二&#xff09;_追求卓越583的博客-CSDN博…

DNS 解析流程

一、背景 最近&#xff0c;在S3协议项目中调研通过DNS域名解析处理流量负载均衡问题。原来对dns也有一些粗浅的了解&#xff0c;知道通过DNS可以将域名转换为IP地址&#xff0c;也可以做负载均衡。但是DNS的解析流程以及缓存等机制&#xff0c;只是一知半解。正好&#xff0c;…

windows安装nginx并设置开机自启动

在macOS和linux中使用nginx我早已经轻车熟路。突然切到windows的环境中&#xff0c;我反而不会用了。 之前写了《windows使用nginx探索笔记》内容比较冗长&#xff0c;所以本文尽量精简一下。 环境 操作系统&#xff1a;windows 2008R2 Datacenter 已经安装的软件&#xff1…

C语言中malloc(),free(),calloc(),realloc()

申请内存malloc()在申请内存时不会对内存进行初始化赋值 在申请内存后&#xff0c;没有对内存进行初始化的话&#xff0c;这段内存中就存储着系统随机值。 int n 5; int* p (int*)malloc(n * sizeof(int));malloc(size):size就是你想开辟的内存的字节大小。我们通常想要用这段…

SpringCloud基础6——分布式事务,Seata

用于复习快速回顾。 目录 1.分布式事务问题 1.1.本地事务&#xff0c;ACID原则 1.2.分布式事务 1.3.演示分布式事务问题 2.理论基础 2.1.CAP定理 2.1.1.一致性&#xff0c;数据同步 2.1.2.可用性&#xff0c;节点正常访问 2.1.3.分区容错 2.1.4.矛盾 2.2.BASE理论 …

vulnhub-xxe lab: 1

ifconfig nmap 192.168.61.0/24 找到192.168.61.145 目录扫描&#xff08;御剑&#xff09; 192.168.61.145/xxe 192.168.61.145/admin.php 无法访问&#xff0c;但是robots.txt里面写的应该不会是无效网站&#xff0c;所以可能是被拒绝访问了 抓xxe的包 可以发现是用xml写的…

[ web基础篇 ] Burp Suite 爆破 Basic 认证密码

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

层次选择器

层次选择器 后代选择器简介后代选择器可以选择作为某元素后代的元素(包括儿子,孙子,重孙子) 两个元素之间的层次间隔可以是无限的示例<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><title>Title</t…

怎么把握住股票每天的最佳交易时机?

每个股民都希望自己能够在每天的股价最高点卖出&#xff0c;然后在最低点再买回来&#xff1b;但是怎么去判断最好的交易时机呢&#xff0c;很多人会想很多方法去识别判断最佳交易点&#xff0c;今天给大家分享一种方法&#xff1b;我一直在思考股票交易的底层逻辑是啥&#xf…

如何在基础镜像中安装指定python版本

背景 由于规范要求要使用指定的镜像版本,但是由于该镜像中的python与我使用的版本有差异,怕引起一些不必要的兼容问题,所以我需要自己按基础镜像基础上安装对应版本的python。 Dockerfile 直接上最终dockerfile,为什么这样写,后面说到。 FROM centos:7 # 指定工作目录 WOR…

【2022中国高校计算机大赛 微信大数据挑战赛】Top 1-6 方案总结

前段时间参加了 2022中国高校计算机大赛 微信大数据挑战赛&#xff0c;比赛链接&#xff1a;https://algo.weixin.qq.com/。 由于时间原因精力有限&#xff0c;我们队伍的方案做的比较简陋&#xff1a; 【初赛&#xff1a;rank-18&#xff0c;复赛&#xff1a;rank-40&#xff…

网课查题接口 搜题公众号对接题库教程 (附赠题库接口)

网课查题接口 搜题公众号对接题库教程 &#xff08;附赠题库接口&#xff09; 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 查…

bm19bm7

为什么不定义如果两点相等呢 等于的话峰值统一取右 以右来比较 波峰就行 不一定是最大的 在这里插入代码片 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** * param nums…

微信小程序转为App并上架应用市场

先说说背景吧&#xff0c;笔者开发了一款微信工具类小程序&#xff0c;刚开始&#xff0c;小程序的日访问量和用户数都还可以&#xff0c;但后面慢慢的发现&#xff0c;受限于微信小程序平台规则&#xff0c;很难对用户进行更深入的运营&#xff0c;用户流失问题也将逐渐凸显出…

‘std::thread‘ has not been declared

出现这个问题的原因就是 目前MinGW GCC64还不支持std::thread 这是我的gcc版本 PS D:\MyCode> gcc --version gcc.exe (x86_64-win32-seh-rev0, Built by MinGW-W64 project) 8.1.0 Copyright © 2018 Free Software Foundation, Inc. This is free software; see the s…

七、RequestResponse

Request&Response 第一章 Request 1. 目标 了解Request的概念了解Request的组成部分掌握Request获取请求行的信息掌握Request获取请求头的信息掌握Request获取请求参数掌握解决请求参数乱码掌握Request域对象掌握请求转发 2. 内容 2.1 Request概述 2.1.1 Request的概…

Part16:Pandas的分层索引MultiIndex怎么用?【详解】

Pandas的分层索引Multilndex 1为什么要学习分层索引Multilndex? 1、分层索引:在一个轴向上拥有多个索引层级&#xff0c;可以表达更高维度数据的形式; 2、方便的进行数据筛选&#xff0c;如果有序则性能更好; 3、groupby等操作的结果&#xff0c;如果是多KEY&#xff0c;结…

元宇宙产业委常务副主任委员甘华鸣:关于术语“元宇宙”以及相关问题

【央链知播-编者按&#xff1a;元宇宙产业委常务副主任委员甘华鸣就全国科学技术名词审定委员会元宇宙及核心术语概念研讨会提出的一个观点&#xff0c;发表自己的看法&#xff0c;写了《关于术语“元宇宙”以及相关问题》一文&#xff0c;现转发供元宇宙产业和学术界思考】 以…