强化学习Q-learning算法——Python实现

news/2024/9/17 3:17:41/文章来源:https://www.cnblogs.com/haohai9309/p/18203233

Q-learning是一种基于值迭代的强化学习(Reinforcement Learning, RL)算法,主要用于在给定环境中学习一个策略,使得智能体(agent)能够在与环境交互的过程中获得最大累计奖励。它通过学习一个状态-动作值函数(Q函数)来指导智能体的行为选择,适用于各种离散状态和动作的任务环境。Q-learning在各种应用领域中都有显著表现,包括机器人控制、游戏AI、交通系统优化以及金融市场分析等。通过不断改进和扩展,Q-learning在未来将有望在更多复杂的实际任务中发挥重要作用,特别是在结合其他机器学习技术和多智能体系统的研究中。

一、Q-learning算法

强化学习是做出最佳决策的科学。它可以帮助我们制定活的物种所表现出的奖励动机行为。比方说,你想让一个孩子坐下来学习考试。要做到这一点非常困难,但是如果每次完成一章/主题时都给他一块巧克力,他就会明白,如果他继续学习,他会得到更多的巧克力棒。所以他会有一些学习考试的动机。这里孩子代表着Agent代理。奖励制度和考试代表了Environment环境。今天的题目是类似于强化学习的States状态。所以,孩子必须决定哪些话题更重要(即计算每种行为的价值)。这将是我们的工作的 Value-Function价值方程,每次他从一个国家(States)到另一个国家(States)旅行时,他都会得到Reward奖励,他用来在时间内完成主题的方法就是我们的Policy决策。

1.1 Q-learning计算步骤

Q-learning的核心思想是通过不断地更新状态-动作值(\(Q\)值)来逼近最优Q函数(\(Q^*\)),从而得到最优策略。我们可以构建一个矩阵 \(Q\), 它用来表示 agent 已经从经验中学到的知识。矩阵 \(Q\)\(R\) 是同阶的, 其行表示状态,列表示行为,\(R(s,a)\)表示在状态\(s\)是采取行为\(a\)获得的奖励。由于刚开始时 agent 对外界环境一无所知, 因此矩阵 \(Q\) 应初始化为零矩阵,对于状态数目未知的情形, 我们可以让 \(Q\) 从一个元素出发, 每次发现一个新的状态时就可以在 \(Q\) 中增加相应的行列。
Q-learning 算法的转移规则比较简单, 如下式所示:

\[Q(s, a)=R(s, a)+\gamma \cdot \max _{\widetilde{a}}\{Q(\widetilde{s}, \widetilde{a})\} \tag{1} \]

其中 \(s, a\) 表示当前的状态和行为, \(\widetilde{s}, \widetilde{a}\) 表示 \(s\) 的下一个状态及行为, 学习参数 \(\gamma\) 为满足 \(0 \leq \gamma<1\) 的常数。式 (1) 中的 \(\gamma\) 满足 \(0 \leq \gamma<1\),如果\(\gamma=0\),对立即的奖励更有效;如果接近1,整个系统会更考虑将来的奖励。
在没有老师的情况下, 我们的 agent 将通过经验进行学习 (也称为无监督学习)。它不断从一个状态转至另一状态进行探索, 直到到达目标。我们将 agent 的每一次探索称为一个 episode。在每一个 episode 中, agent 从任意初始状态到达目标状态。当 agent 达到目标状态后, 一个 episode 即结束, 接着进入另一个 episode。下面给出整个 \(Q\)-learning 算法的计算步骤:

Step 1 给定参数 \(\gamma\) 和 reward 矩阵 \(R\)
Step 2 今 \(Q:=0\)
Step 3 For each episode:
3.1 随机选择一个初始的状态 \(s\)
3.2 若未达到目标状态, 则执行以下几步
(1) 在当前状态 \(s\) 的所有可能行为中选取一个行为 \(a\)
(2) 利用选定的行为 \(a\), 得到下一个状态 \(\widetilde{s}\)
(3) 按照公式(1),计算 \(Q(s, a)\)
(4) 令 \(s:=\widetilde{s}\).

Agent 利用上述算法从经验中进行学习。每一个 episode 相当于一个 training session.在一个 traiming session 中, agent 探索外界环境, 并接收外界环境的 reward, 直到达到目标状态. 训练的目的是要强化 agent 的 “大脑” (用 \(Q\) 表示)。训练得越多, 则 \(Q\) 被优化得更好,当矩阵 \(Q\) 被训练强化后, agent 便很容易找到达到目标状态的最快路径了。利用训练好的矩阵 \(Q\), 我们可以很容易地找出一条从任意状态 \(s_0\) 出发达到目标状态的行为路径, 具体步骤如下:

令当前状态 \(s:=s_0\)
确定 \(a\), 它满足 \(Q(s, a)=\max _{\tilde{a}}\{Q(s, \widetilde{a})\}\)
令当前状态 \(s:=\widetilde{s}(\widetilde{s}\) 表示 \(a\) 对应的下一个状态 \()\)
重复执行步 2 和步 3 直到 \(s\) 成为目标状态.

通过不断迭代更新 $Q(s, a) $ 的值,Q-Learning算法可以学习到最优策略 \(\pi^*\) 下的状态-动作对的价值函数$ Q^*(s, a)$。这个过程不需要环境的动态模型,因此Q-Learning是一种无模型的强化学习算法。

1.2 Q-Learning解的推导

Q-Learning算法的目标是找到一个策略\(\pi^*\),使得\(Q(s,a)\) 最大化,即:

\[\pi^* = \arg\max_{\pi} Q^{\pi}(s, a) \]

Q-Learning的更新规则如下:

\[Q_{t+1}(s_t, a_t) \leftarrow Q_t(s_t, a_t) + \alpha \left[ R_{t+1} + \gamma \max_{a} Q_t(s_{t+1}, a) - Q_t(s_t, a_t) \right] \]

其中:

  • $ Q_t(s_t, a_t)$是时间 \(t\)下状态\(s_t\) 和动作 $ a_t$ 的\(Q\)
  • $ R_{t+1} $ 是在 $(s_t, a_t) $下的即时奖励
  • \(\alpha\)是学习率,$0 \leq \alpha < 1 $
  • $ \gamma$ 是折扣因子

假设我们有一个策略 $\pi $,其对应的Q值函数为 $ Q^{\pi}$。根据贝尔曼动态规划方程,我们有:

\[Q^{\pi}(s, a) = R(s,a) + \gamma \sum_{s' \in \mathcal{S}} P(s'|s,a) V^{\pi}(s') \]

由于 $$V^{\pi}(s') = \max_{a'} Q^{\pi}(s', a')$$,我们可以将 $ V^{\pi}(s')$替换为 $ \max_{a'} Q^{\pi}(s', a')$:

\[Q^{\pi}(s, a) = R(s,a) + \gamma \sum_{s' \in \mathcal{S}} P(s'|s,a) \max_{a'} Q^{\pi}(s', a') \]

如果我们取 $ \pi $为最优策略 $ \pi^*$,那么我们得到:

\[Q^*(s, a) = R(s,a) + \gamma \sum_{s' \in \mathcal{S}} P(s'|s,a) \max_{a'} Q^*(s', a') \]

这个方程表明,最优\(Q\)值 $ Q^*(s, a)$ 可以通过对未来状态的最优Q值的加权和来计算。这就是Q-Learning算法的马尔科夫解。

二、Q-learning算例

一只小白鼠在迷宫里面,目的是找到出口,如果他走出了正确的步子,就会给它正反馈(糖),否则给出负反馈(点击),那么,当它走完所有的道路后。无论比把它放到哪儿,它都能通过以往的学习找到通往出口最正确的道路。假设迷宫有5间房,如图1所示,这5间房有些房间是想通的,我们分别用0-4进行了标注,其中5代表了是是出口。

图1 迷宫 图2 状态转移收益

在这个游戏里,我们的目标是能够走出房间,就是到达5的位置,为了能更好的达到这个目标,我们为每一个门设置一个奖励。比如如果能立即到达5,那么我们给予100的奖励,其它没法到5的我们不给予奖励,权重是0了;5因为也可以到它自己,所以也是给100的奖励,其它方向到5的也都是100的奖励。 在Q-learning中,目标是权重值累加的最大化,所以一旦达到5,它将会一直保持在这儿,如图3所示。

图3 权重图 图4 收益矩阵

2.1 \(Q\)\(R\)矩阵

想象一下小白鼠(或虚拟的机器人),它对环境一无所知,但它需要通过自我学习知道怎么样到外面,就是到达5的位置。好啦,现在可以引出Q-learning的概念了,“状态”以及“动作”,我们可以将每个房间看成一个state,从一个房间到另外一个房间的动作叫做action,state是一个节点,而action是用一个剪头表示。现在假设我们在状态2,从状态2可以到状态3,而无法到状态0、1、4、5,因为2没法直接到0、1、4;从状态3,可以到1、4或者2,而无法到达0、5;而4可以到0、3、5,而无法到达1、2;其它依次类推。所以我们能够把这些用一个矩阵来表示,这个矩阵就是这里的\(Q\)矩阵了,这个矩阵的列表表示的是当前状态,而行标表示的则是下一个状态。如\(Q\)矩阵的第三行的行标是2,如果取第四列,列标为3,就表示从状态2转移到状态3。
鉴于状态2可以转移到状态3,这时记这个转移收益为0(不奖不罚);如果从状态2转移不到状态4,就记2->4的转移收益是-1(负激励,尽量不这样走),如果从某个状态转移到了目标状态5(达成目标,正激励),其收益就记为100,就构造了收益矩阵\(R\)
Q矩阵初始化的时候全为0,因为它的状态我们已经全部知道了,这里总的状态是6,因为后面要求最大值,所以初始化都为0。如果我们并不知道有多少个状态,那么请从1个状态开始,一旦发现新的状态,那么为这个矩阵添加上新的行和列,如图4所示。
我们的小白鼠(或虚拟机器人)将通过环境来学习,机器人会从一个状态跳转到另一个状态,直到我们到达最终目标状态。我们把从开始状态开始一直达到最终目标状态的这个过程称之为一个场景,小白鼠会从一个随机的开始场景出发,直到到达最终状态完成一个场景,然后立即重新初始化到一个开始状态,从而进入下一个场景。

2.2 计算episode

为进一步理解上一节中介绍的 Q-learning 算法是如何工作的, 下面我们一步一步地迭代几个 episode。
首先取学习参数 \(\gamma=0.8\),初始状态为房间 1,并将 \(Q\) 初始化为一个零矩阵。观察矩阵 \(R\) 的第二行 (对应房间 1 或状态 1 ), 它包含两个非负值, 即当前状态 1 的下一步行为有两种可能: 转至状态 3 或转至状态 5。 随机地, 我们选取转至状态 5。

初始\(Q\)矩阵 收益矩阵

想象一下, 当我们的 agent 位于状态 5 以后, 会发生什么事情呢? 观察矩阵 \(R\) 的第 6 行 (对应状态 5 ), 它对应三个可能的行为: 转至状态 1,4 或 5 ,根据公式 (1), 我们有

\[\begin{aligned} Q(1,5) & =R(1,5)+0.8 * \max \{Q(5,1), Q(5,4), Q(5,5)\} \\ & =100+0.8 * \max \{0,0,0\} =100 \end{aligned} \]

现在状态 5 变成了当前状态。因为状态 5 即为目标状态, 故一次 episode 便完成了, 至此, 小白鼠的 “大脑” 中的 \(Q\) 矩阵刷新为

一次 episode 后的 \(Q\) 矩阵 一次 episode 后的 \(Q\) 矩阵

接下来, 进行下一次 episode 的迭代, 首先随机地选取一个初始状态, 这次我们选取状态 3 作为初始状态。
观察矩阵 \(R\) 的第四行 (对应状态 3 ), 它对应三个可能的行为: 转至状态 1,2 或 4。 随机地, 我们选取转至状态 1 ,因此观察矩阵 \(R\) 的第二行 (对应状态 1 ), 它对应两个可能的行为: 转至状态 3 或 5,根据公式 (1),我们有

\[Q(3,1)=R(3,1)+0.8 * \max \{Q(1,3), Q(1,5)\}\\= 0+0.8 * \max \{0, 100\} = 80 \]

若我们执行更多的episode 迭代,最终将得到一个收敛矩阵(理论上可以证明这个矩阵一定存在),见下图所示。

状态转移图 \(Q\)收敛矩阵
规范化处理\(Q\)矩阵(用矩阵元素最大值除所有元素) 转移的最优行为

最终策略:在状态 0 下,选择动作 4 作为最优策略;在状态 1 下,选择动作 5 作为最优策略;在状态 2 下,选择动作 3 作为最优策略;在状态 3 下,选择动作 4 作为最优策略;在状态 4 下,选择动作 5 作为最优策略;在状态 5 下,选择动作 5 作为最优策略。所以从状态2出发的最优路径序列为2-3-4-5。

三、算法Python程序

import numpy as np# 定义参数
gamma = 0.8  # 折扣因子
alpha = 0.1  # 学习率
epsilon = 0.1  # 探索概率
episodes = 10000  # 学习的总回合数# 定义收益矩阵
R = np.array([[-1, -1, -1, -1, 0, -1],[-1, -1, -1, 0, -1, 100],[-1, -1, -1, 0, -1, -1],[-1, 0, 0, -1, 0, -1],[0, -1, -1, 0, -1, 100],[-1, 0, -1, -1, 0, 100]
])# 初始化Q值矩阵
Q = np.zeros_like(R, dtype=float)# Q-learning算法
for episode in range(episodes):# 随机选择初始状态state = np.random.randint(0, R.shape[0])while True:# 选择动作:采用ε-贪婪策略if np.random.rand() < epsilon:action = np.random.randint(0, R.shape[1])else:action = np.argmax(Q[state])# 执行动作,获取即时奖励和下一个状态next_state = actionreward = R[state, action]# 只在奖励不为 -1 时进行 Q 值更新if reward != -1:# Q值更新Q[state, action] = Q[state, action] + alpha * (reward + gamma * np.max(Q[next_state]) - Q[state, action])# 状态转移state = next_state# 如果达到了终止状态,结束本回合if reward == 100:break# 对 Q 矩阵进行规范化,使最大值为100
max_value = np.max(Q)
if max_value > 0:Q = (Q / max_value) * 100# 保留两位小数
Q = np.round(Q, 2)# 输出最终的Q值矩阵
print("最终的Q值矩阵(规范化后):")
print(Q)# 输出最终策略
policy = np.argmax(Q, axis=1)
print("最终策略:")
print(policy)# 解释最终策略
for state in range(len(policy)):print(f"在状态 {state} 下,选择动作 {policy[state]} 作为最优策略。")

总结

Q-learning是一种基于价值迭代的强化学习算法,其主要特点是不需要知道环境的动态模型。智能体通过与环境的直接交互来学习策略,适用于各种不确定和复杂的环境。Q-learning采用离线更新方法,在每次交互后立即更新Q值,使得算法在训练过程中不断优化。Q-learning的基本思想是通过更新状态-动作值函数(Q值),来评估每个动作在每个状态下的价值。具体而言,智能体在每个状态选择一个动作,接收到环境的反馈(奖励)和转移到的新状态,然后使用Bellman方程更新Q值。该过程持续进行,直到Q值函数收敛,最终得到最优策略。
Q-learning在许多领域取得了显著成功,如游戏、机器人控制和自动化。然而,它也存在一些挑战和局限性。首先,在处理高维状态空间和连续动作空间时,Q-learning的表现不佳。其次,在大型复杂环境中,Q-learning的学习效率较低,需要大量时间和计算资源来收敛。为克服这些挑战,未来研究方向包括:结合深度学习的方法,例如深度Q网络(DQN),以处理高维和复杂任务;多智能体系统中的Q-learning算法,研究智能体之间的协作和竞争;迁移学习,将一个任务中学到的知识迁移到另一个相关任务,提高学习效率和泛化能力;确保Q-learning算法在无人驾驶、医疗等高风险领域的安全性和鲁棒性。

参考资料

  1. A Painless Q-learning Tutorial (一个 Q-learning 算法的简明教程)
  2. 《深入浅出机器学习》之强化学习
  3. 强化学习:Q-learning由浅入深:简介1
  4. 强化学习之Q-learning简介

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

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

相关文章

mysql: Syntax error or access violation: 1055 Expression #2 of SELECT (错误解决办法)

Mysql报错:SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column seo.ryc_combo_class_cate_list_113.fid which is not functionally dependent on columns in GROUP BY cla…

【APIM】Azure APIM抛出 java.lang.RuntimeException 错误定位

问题描述 Azure APIM服务日志中发现 java.lang.RuntimeException 错误,在进一步通过Application Insights采集的错误信息日志,发现真实的请求错误为:‘The remote name could not be resolved xxxx.xxx.xx"。问题解答 APIM服务,在没有配置自定义的DNS服务器时,默认会…

原型设计工具——Pixso

Pixso 定位于产品设计协作一体化工具,能一站式完成原型、设计、交互与交付,打通产品、设计到研发的工作链路,全面覆盖产品原型、UI/UX设计、原型交互、设计交付全流程,浏览器即开即用。 Pixso的核心特点快捷的图形绘制:Pixso内设有许多快捷键方便用户一键绘图,也可以导入…

三维坐标转2维坐标

最近在帮朋友调代码,他们想出份报告,需要把三维的坐标系以一定的角度画到纸面上。 公式:x = xCosα + zCosβ y = y - zSinβ + xCosα 以下是公式推导过程 1. 先画平面直角坐标系(xy坐标系)和空间直角坐标系(xyz坐标系,本文用x,y,z表示),x轴和x轴之间的夹角为α,…

Windows安装Docker Desktop找不到hyper-v(Windows11家庭中文版没有hyper-v)

新建文本文件复制下面代码放进去pushd "%~dp0" dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hyper-v.txt for /f %%i in (findstr /i . hyper-v.txt 2^>nul) do dism /online /norestart /add-package:"%SystemRoot%\servicing\Packages\%%i&…

伙伴活动|W3C 标准带头人开讲 WebGPU 前沿趋势

提及 2023 年前端大事件,「WebGPU 的正式发布」无疑占据了一席之地。经过六年的精心打磨,WebGPU 的首个实现版本正式登陆 Chrome,不仅标志着浏览器图形性能的一大飞跃,也让众多从业者兴奋不已。WebGPU 允许网页代码以一种高性能且安全可靠的方式访问 GPU 功能,这一规范正由…

java中WGS84坐标(ios)转换BD-09坐标(百度坐标)

iPhone的GPS定位(CLLocationManager)获得的经纬坐标是基于WGS-84坐标系(世界标准),Google地图使用的是GCJ-02坐标系(中国特色的火星坐标系),百度的经纬坐标在GCJ-02的基础上再做了次加密,就是BD-09坐标系。public class CoordinateConversion {static double x_PI = 3.1…

【地图导航有讲究】教你识别合法地图

在这个数字化时代,地图已成为我们日常生活中不可或缺的导航工具。无论是纸质地图还是手机中的电子地图,准确合法的地图不仅能为我们指引方向,还关乎国家安全和社会秩序。那么,如何确保你手中的地图是合法的呢?今天,就让我们一起学习几个识别合法地图的小技巧。 了解地图的…

可视化理解constructor、prototype、__proto__形成的指向图

Person类和person实例 首先给出一段js代码:function Person() {} const person = new Person()根据以下规则:每个实例都有一个__proto__指向其原型对象。 每个构造函数都有一个prototype属性指向其实例的原型对象 每一个原型都有一个prototype指向其实例的构造函数。于是就有…

记一次MySQL执行修改语句超时问题

异常问题原因分析这个问题发生在开发环境,怀疑是提交事务时终止项目运行,没有提交该事务,造成死锁 调试该事务时时间太长,为什么说有这个原因呢,因为通过查找日志显示The client was disconnected by the server because of inactivity. See wait_timeout and interactive…

高抗干扰触摸芯片VK36N系列1/2/3/4/5/6/7/8/9/10按键/通道适用于家电/玩具【FAE技术支持】

概述. VK36N1D具有1个触摸按键,可用来检测外部触摸按键上人手的触摸动作。该芯片具有较 高的集成度,仅需极少的外部组件便可实现触摸按键的检测。 提供了1个1对1输出脚,可通过IO脚选择上电输出电平,有直接输出和锁存输出2个型号 可选。芯片内部采用特殊的集成电路,具有高电…

初识yolo

确认版本 cuda我的是11.3.121,后面安装的CUDA toolkit和cuDNN大版本不能超过它 pythonAnoconda version虚拟环境 # 创建虚拟环境 conda create -n yolov8 python=3.8.0 # 激活虚拟环境(切换至这个环境) conda activate yolov8 # 查看已创建的虚拟环境 conda info -e #删除 con…