强化学习(reinforcement learning)教程_强化学习教程-程序员宅基地

技术标签: 技术分享  q学习算法  学习点滴  reinforcement learni  强化学习  

前一阵研究强化学习,发现中文的资料非常少,实例就更少。于是翻译一篇q学习算法的教程,供需要的人学习。

原文链接:http://mnemstudio.org/path-finding-q-learning-tutorial.htm

正文:

Q学习算法是一种用来解决马尔可夫决策过程中最优化问题的方法。Q学习算法最大的特点是它具有选择瞬时奖励和延迟奖励的能力。在每一步中,agent通过观察状态s的向量,然后选择并执行行动a,随着状态从s转移到s‘agent能够收到一个强化值rs a)。训练的目标是发现一条行动的路径,从而使得整个过程强化值的和最大,也就是从起点到终点间的一条最短路径。

Q学习算法的转移规则表示为以下形式:

Q (state action) = R(state action) + gamma * Max[Q(next state all actions)]

参数gamma的范围是[01],从而保证结果收敛。如果gamma更接近0agent趋向于只考虑瞬时奖励值,反之如果更接近1,则agent为延迟奖励赋予更大的权重,更侧重于延迟奖励。

Q学习算法的步骤表示如下:

设置gamma以及环境奖励矩阵R

将矩阵Q初始化为0

对于每次迭代(episode):

随机选择一个初始状态;

直到达到目标状态:

从所有可能的行动中选择一个行动;

执行行动到达下一状态;

获取下一状态所有行动中最大的Q值;

利用公式更新Q

下面的教程通过一个简单而详细的数值例子介绍Q学习算法的概念。本例描述了一个通过agent利用非监督学习学习未知的环境。对比该例和的源代码,你可能也会发现很有帮助。

假设一个建筑内有的5间房间,房间之间通过门连接,如下图所示。我们为每个房间进行标号,记为0-4。建筑外面也可以认为是一个大的房间(5),注意门14均可以到达5


我们可以用图的形式表示房间的连接情况,每个房间对应一个节点,每扇门对应节点间的弧。


在本例中,我们假设在其中任意一个房间中放置一个agent,然后要求agent从该房间走出该建筑(即目标房间)。换而言之,目标房间就是5。为了把这个房间作为目标,我们需要为每个门关联一些奖励值(节点间的弧)。与目标直接相连的门具有瞬时奖励,值设为100。其他没有直连的门的奖励为0。注意因为门是双向的,因此弧是双向的,弧之间瞬时奖励值如下图所示。


当然,房间5和自己相连,拥有100的奖励值,其它与5直连的房间都有100的奖励值。在Q学习中,目标是以最高的奖励值到达目标状态,因此,如果agent到达了目标,他将永远停留,这种类型的目标称为"absorbing goal"

假设我们的agent是一个能够通过实验学习的“哑巴虚拟机器人”。Agent能够从一个房间到达另一个房间,但是对环境一无所知,而且也不知道哪些门通向外面。

假设我们要为可能处于任意房间的agent建立模型。现在我们假设agent在房间2,我们希望agent能够通过学习达到5


Q学习中术语包括状态和行为。

我们把0-5每个房间称为状态,把agent从一个房间移动到另一房间称为行为(action),在图中,状态表示一个节点,行为表示一条有向弧。


假设agent在状态2,因为23直连,因此可以从状态2可以移动到状态3。从状态2不能直接到状态1因为两者不直连。同理,从状态3可以到状态14或者回到2。如果agent在状态4,那么就有3个可能的行为,到05或者3。如果agent在状态1,那么可以到53,从0只能到达4

我们可以根据状态间的关系和瞬时奖励值创建矩阵R


-1表示状态间不直连。例如0不能直接到达1

现在可以增加一个相似的矩阵Q,它可以看作是agent的“大脑”,表示了agent通过学习环境留下的“记忆”,矩阵Q的行表示agent当前的状态,列表示到达下一状态可能的行为。

在开始时agent对环境一无所知,因此矩阵Q初始化为0。在本例中,为了简单起见,我们假设状态的数量已知,如果状态数量未知,矩阵Q初始化时只有一个元素,如果发现新状态后再添加行和列。

Q学习的转移规则是一个很简单的方程:

Q(state action) = R(state action) + Gamma * Max[Q(next state all actions)]

根据这个方程,一个值被赋予给矩阵Q中一个特定值,它等于R矩阵中对应值的和和学习参数gamma,乘以下一状态中所有行为中Q值最高的值。

虚拟的agent通过经验进行学习,没有老师(称为无监督学习)。Agent从一个状态转移到另一状态不断的探索直到到达目标。我们把每一次探索称为一次迭代(episode)。每一个episode包含agent从初始状态移动到目标状态。每当agent到达目标状态,程序继续下一episode

Q学习算法步骤如下:

设置gamma参数以及矩阵R

初始化矩阵Q

对于每次episode

随机选择一个初始状态;

目标状态没有到达:

从当前状态的所有行为中选择一个

转移到下一状态;

计算;

将下一状态设为当前状态;

Agent通过以上算法进行学习,每次episode相当于一次训练。在每一次训练中,agent探索环境(矩阵R表示),接受奖励直到到达目标状态。训练的目的是增强agent的大脑,即矩阵Q。训练越多,Q结果越好。通过这种方式,如果Q被加强了,而不是反复探索,不断回到同一房间,就能快速找到目标状态。

参数gamma的取值范围是0-1,如果gamma趋近于0,则agent趋向于考虑瞬时奖励,如果接近1,则趋向于未来的奖励,延迟奖励。

为了使用矩阵Qagent仅仅跟踪状态,从初始状态到目标状态。算法能够根据矩阵Q中记录的奖励值为当前状态找到具有最大奖励值的行为。

为了更好理解Q学习算法的工作原理,我们一步一步的进行演示,剩下的步骤可以参考源代码。

首先设置gamma参数=08,初始状态为1

将矩阵Q全部初始化为0


观察矩阵R的第二行,当前状态有两个行为,到达状态3或者状态5。通过随机的选择,我们选择到达状态5


现在我们想像下如果agent到达状态5后会发生什么?观察矩阵R的第6行,它有三个行为,到达状态14,、5

Q(state action) = R(state action) + Gamma * Max[Q(next state all actions)]

Q(1 5) = R(1 5) + 0.8 * Max[Q(5 1) Q(5 4) Q(5 5)] = 100 + 08 * 0 = 100

因为矩阵Q初始化为0Q(51) Q(54)Q(55)的值都为0Q(15)的计算结果为100因为矩阵RR(51)的瞬时奖励为100

下一状态5,成为当前状态。因为5是目标状态,我们结束一次episode。更新后的矩阵Q为:


下一个episode,我们随机选择一个初始状态。这一次我们选择状态3

观察矩阵R的第4行,它有三个行为,到达状态124。通过随机选择,我们到达状态1

现在假设到达状态1,观察矩阵R的第二行,它有两个行为,到达状态35,接下来计算Q

Q(state action) = R(state action) + Gamma * Max[Q(next state all actions)]

Q(1 5) = R(1 5) + 08 * Max[Q(1 2) Q(1 5)] = 0 + 08 * Max(0 100) = 80

我们用更新过的矩阵Q进行计算。Q(13)=0Q(15)=100Q(31)的结果=80因为奖励为0。矩阵Q变为:


 此时状态1成为当前状态,我们重复Q算法的内循环因为状态1不是目标状态。

开始新的循环,状态1有两个行为,到达状态3或者5,很幸运,我们选择状态5


现在假设在状态55有三个行为,145。我们利用这三个行为中最大的奖励值更新矩阵Q

Q(state action) = R(state action) + Gamma * Max[Q(next state all actions)]

Q(1 5) = R(1 5) + 0.8 * Max[Q(5 1) Q(5 4) Q(5 5)] = 100 + 08 * 0 = 100 

更新后的矩阵QQ(51) Q(54) Q(55)全部为0Q(15)的计算结果为100因为矩阵RR(51)的瞬时奖励为100

因为5是目标状态,我们结束这次episode,矩阵Q更新为:


如果agent不断地学习,矩阵Q最终会收敛,如下图所示。


接下来可以对矩阵Q进行标准化


一旦矩阵Q趋于收敛,我们知道agent学到了到达目标状态的最优路径。跟踪最优状态的序列和弧就可以得到最高的奖励值。


例如,从初始状态2agent以矩阵Q为指导;

从状态2,最大Q值指向状态3

状态3,最大Q指指向14,假设随机选择1

从状态1最大Q值指向状态5

因此序列为2-3-1-5

1


Q Matrix values:

0 0 0 0 396 0

0 0 0 316 0 496

0 0 0 316 0 0

0 396 252 0 396 0

316 0 0 316 0 496

0 396 0 0 396 496


Shortest routes from initial states:

1 5

3 1 5

5 5

2 3 1 5

4 5

0 4 5

2 2和例1相比,仅仅增加了节点。类似的代码,少量的优化


Shortest routes from initial states:

1 0 4 8 9 5 6 2 3 7 11 15

3 7 11 15

5 6 2 3 7 11 15

2 3 7 11 15

4 8 9 5 6 2 3 7 11 15

0 4 8 9 5 6 2 3 7 11 15



版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xudong0612/article/details/9304811

智能推荐

open-spider开源爬虫工具:抖音数据采集_抖音直播爬虫采集_抖音爬虫网站-程序员宅基地

文章浏览阅读313次,点赞3次,收藏10次。基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**_抖音爬虫网站

HashSet和TreeSet的介绍和案例演示_演示hashset、treeset的使用方法、遍历、区别-程序员宅基地

文章浏览阅读254次。HashSet保证元素唯一 HashSet 底层数据结构是哈希表. HashSet 不是线程安全的 集合元素可以是 null ​ 哈希表:是一个元素为链表的数组,综合了数组和链表的优点 (像新华字典一样) (JDK1.7之前) 。 当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,..._演示hashset、treeset的使用方法、遍历、区别

Sublime text 3设置用用空格替换tab键_sublime 替换table-程序员宅基地

文章浏览阅读5.3w次,点赞4次,收藏8次。制表符,又爱又恨的。因为这个东西只用一个字符却能代替一个空间。但是有的开发工具却将制表符替换成空格,这样一来,我修改的代码别人的工具编辑后,就会出现很多不符的问题。导致代码混乱难以阅读。这时候,最好的方法就是将制表符统一。更关键的是如果你在写Python代码,那么会出现很多问题,Python是以严格的缩进和对齐来标识代码段的,但是混合使用空格和tab键,就会出现诸多问题,报各种各样的格式错_sublime 替换table

QVBoxLayout,QHBoxLayout不同部分比例大小设置方法 Python_qhboxlayout分配左右大小-程序员宅基地

文章浏览阅读7.6k次。#layout不同的比例区分大小 self.vbox.setStretchFactor(self.tableWidget1, 1) self.vbox.setStretchFactor(self.tableWidget2, 4)给tablewidget赋值 for i in range(len(valuelist)): ..._qhboxlayout分配左右大小

matlab使用笔记_ubuntu matlab 缩放-程序员宅基地

文章浏览阅读826次。下载安装包和破解文件链接: https://pan.baidu.com/s/1X09GAchToEqyMRol3msGAA 密码: wak6–来自百度网盘超级会员V4的分享下载完成后解压右击.iso镜像文件,选择使用其他程序打开选择磁盘映像挂载器打开后会在桌面上看到对应的磁盘,双击打开会进入下图的目录,在该目录右键在终端打开然后在终端输入pwd得到当前路径然后新开一个终端,输入sudo /media/xj/MATHWORKS_R2019A/install不同的电脑sudo后面的路径可能不一样_ubuntu matlab 缩放

pytorch系列文档之Pooling layers详解(MaxPool1d、MaxPool2d、MaxPool3d)_maxpooling1d和maxpooling3d的区别-程序员宅基地

文章浏览阅读1.1w次,点赞4次,收藏35次。MaxPool1dtorch.nn.MaxPool1d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)输入size为(N,C,L),在L维进行池化参数:kernel_size – 池化窗口大小stride – 步长. Default value is kernel_sizepadding – padding的值,默认就是不paddingdilation – 控制扩_maxpooling1d和maxpooling3d的区别

随便推点

el-upload 多文件上传_el-upload上传多个文件-程序员宅基地

文章浏览阅读3.2k次。el-upload 多文件上传_el-upload上传多个文件

php okhttp3 上传文件,Android使用OKHttp库实现视频文件的上传到服务器功能-程序员宅基地

文章浏览阅读715次。1 服务器接口简介此处我使用的服务器接口是使用Flask编写,具体实现代码:# -*- coding: utf-8 -*-from flask import Flask, render_template, jsonify, requestimport timeimport osimport base64app = Flask(__name__)UPLOAD_FOLDER = 'E:\myuploa..._okhttp3上传视频

VUE Axios 传递数组到基于SpringBoot的Java后台_vue传数组到springboot-程序员宅基地

文章浏览阅读5.1k次,点赞3次,收藏5次。背景前台使用axios.request({url: url,params: dataList,method: 'post'})传递数组到后台。后台使用RequestParam接收(String dataList)当数组长度非常小的时候可以进入后台,当数组长度大一点的时候前台报错400,不进后台。分析使用params传递参数实际上还是通过url传..._vue传数组到springboot

ImageNet VID-程序员宅基地

文章浏览阅读53次。有谁知道ImageNet VID数据集在哪可以下载吗。_imagenet vid

Unity C# 之 使用 HttpWebRequest 基础知识/HttpWebRequest 进行异步Post 网络访问/数据流形式获取数据(Task/async/await)的代码简单实现_httpwebrequest post-程序员宅基地

文章浏览阅读4.2k次,点赞4次,收藏13次。可以使用 UnityWebRequest 访问,不过好似只能用协程的方式,并且访问只能在主线程中;所以这里使用 C# 中的 HttpWebRequest,进行网络访问,而且 HttpWebRequest,允许在子线程中访问,在一些情况下可以大大减少主线程的网络访问压力;这里使用 HttpWebRequest ,进行 Post 访问,并且Task 结合 async (await) 的进行异步访问,最后使用 Stream 流式的形式获取数据,在这里做一个简单的记录,以便后期使用的时候参考。_httpwebrequest post

linux进程家族树的形成,使用Linux版的MEGA构建某一基因家族的基因进化树-程序员宅基地

文章浏览阅读647次。最近碰到了个需求,让我构建某一基因家族的进化树,并根据进化关系进行相应的分类。这让我想起了之前上课的时候,一个做进化的老师给我们讲过,如果不是纯做进化方向的课题,MEGA完全够用了。由于windows的内存等有限,做几十个基因还凑合,要是上百个基因就吃不消了,于是就想到了用Linux下的MEGA来做。1.下载链接2.获取该基因家族3.进行多序列比对上一步我得到了该基因家族的所有基因家族的蛋白序列,..._用mega建基因家族树如何分组

推荐文章

热门文章

相关标签