前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从零开始强化学习:在Python笔记本中设计和解决一个任务

从零开始强化学习:在Python笔记本中设计和解决一个任务

作者头像
用户7623498
发布2020-08-04 11:25:42
4810
发布2020-08-04 11:25:42
举报

本文介绍了一个强化学习项目,它对于那些想在Python中创建和解决简单任务的人非常有帮助。该项目创建了强化学习环境以及基本方法,所有代码都在Kaggle上进行了发布。此外,我们还创建了一个Meta”笔记本,它只包含环境定义,你可以用它来轻松的尝试、调整和应用自己的代码。

概 要

第一次开始学习强化学习时,我直接去复现在线指南和项目,但我发现自己越学越困惑。“为什么结果会这样呢?”这个参数是做什么的?环境以这种方式起什么作用?这些都是我开始问自己的问题。

直到我后退一步,从完全理解概率环境是如何定义的基础开始,建立一个我可以在纸上解决的小例子,事情才开始变得更有意义。但是,我发现很难找到不需要从外部导入就可以应用的任务环境。

因此,我给自己设定了一个挑战:

我可以在Python中为任务环境完全自包含地定义并找到最优操作吗?

通过跟踪我的工作,我希望其他人可以把这作为一个基本的起点来学习自己。

阶段1:定义任务环境

任务内容

很简单,我想知道从房间的任何位置将一张纸放入垃圾桶的最佳方法。我可以把纸扔向任何方向,也可以一次移动一步。

任务对人类来说很简单,因为人类可以通过视力判断垃圾桶的位置,并且有大量关于距离与位置的先验知识。但对于机器人,这些显然要从零开始学习。

我们定义了一种环境,在这种环境中,成功投掷的概率是根据投掷纸张的方向和当前距离计算的。

例如,在下面的图像中,我们有三个人分别被标记为A、B和c。

C人比B近,但扔的方向完全错误因此击中垃圾桶的概率很低。这看起来似乎不合逻辑,因为C会朝这个方向扔,但是,正如我们稍后将展示的,算法必须先尝试一系列的方向,以学习如何成功,而不会有关于垃圾箱在哪里的视觉指导。

为了在python中创建环境,我们将图转换为x和y值的二维维度,并使用方向代数(Bearing Mathematics)计算抛出的角度。我们使用了标准化的整数x和y值,所以它们必须以-10和10为界。

环境的概率

投掷成功的概率与投掷的距离和方向有关。因此,我们需要计算两个测度:

  • 当前位置到容器的距离
  • 扔纸的角度和扔到垃圾桶的真实方向之间的差

距离测量

如上图所示,A在set中的位置为(-5,-5)。这是它们的当前状态,它们到bin的距离可以用欧几里得距离度量来计算:

在最后的计算中,我们将其标准化,并将值反转,以便高分表示此人更接近目标箱:

因为我们已经在(- 10,10)之间固定了二维尺寸,所以这个人可能到垃圾箱的最大距离是14.14。因此我们对A的距离分数:

方向测量

然后A有一个决定要做,他们是移动还是扔向一个选择的方向。现在,假设他们选择扔纸,第一次是50度,第二次是从正北方向60度。A人的箱子方向可以用简单的三角法计算:

因此,第一个距离实际方向5度,第二个距离15度。

当我们考虑到有效的抛掷被限定在实际方向的任意一边45度(即没有以错误的方式抛掷),那么我们可以使用下面的方法来计算这个选择的方向有多好。任何超过45度界限的方向都会产生负值,并被映射到概率为0:

两个人都很接近,但他们的第一次投掷更有可能击中垃圾桶。

概率计算

因此,我们计算成功投掷的概率与这两种方法相对:

创建一个广义概率函数

虽然之前的计算相当简单,但在我们归纳这些时需要考虑一些因素,并开始考虑bin或当前位置不是固定的。

在之前的例子中,人物A在垃圾桶的西南方向,因此角度可以通过简单的方式计算,但如果这个人在垃圾桶的东北向,那么这将导致错误的计算结果。此外,因为箱子可以放置在任何地方,我们需要首先确定人与箱子的相对位置,然后再进行角度计算。

下面的图表总结了这一点,我们根据每个人与垃圾桶的相对位置,归纳出了每一个三角计算公式:

考虑到这个图,我们创建了一个函数,该函数仅从相对于箱子的给定位置计算投掷成功的概率。

然后,我们按照前面的图计算从人到箱子的方位,并计算在± 45度窗口内的分数范围。距离真实方位最近的投掷得分较高,而距离较远的投掷得分较低,任何大于45度(或小于-45度)的投掷都是负的,然后设置为零概率。

最后,总体概率与给定当前位置的距离和方向相关,如前所示。

注:我选择了45度作为边界,你可以选择改变这个窗口,也可以手动缩放概率计算,以不同的方式对方向测量的距离进行加权。

我们重新计算了前面的例子,得到了与预期相同的结果。

绘制每种状态的概率

现在我们有了这个函数,可以很容易地计算和绘制二维网格中所有点在一个固定的方向投掷的概率。

概率是由前一个函数中设置的角度来定义的,目前这个角是45度,但如果需要,这个角可以减小或增大,结果也会相应改变。我们也可以根据距离来调整概率。

例如,对于每一个x/y位置,当纸张以180度方位(正南)抛出时的概率如下所示。

所有投掷方向的动画情节

为了进一步演示这一点,我们可以遍历多个投掷方向并创建一个交互式动画。代码变得有点复杂,您总是可以简单地使用前面的代码块并手动更改“throw_direction”参数来探索不同的位置。然而,这有助于探索概率,可以在Kaggle笔记本中找到。

阶段2:为已知概率的环境找到最优策略

基于模型的方法

我们的目标是通过向给定的方向投掷或移动来找到每种状态下的最佳动作。因为我们知道概率,所以我们实际上可以使用基于模型的方法,并可以使用value-iteration来通过以下公式实现这一点:

值迭代从任意函数V0开始,使用下面的方程得到k+1阶段的函数从k阶段的函数得到 (参考https://artint.info/html/ArtInt_227.html)。

移动动作的计算相当简单,因为已经定义了一个动作成功的概率要保证(等于1),因此,从状态(- 5,5)开始的动作(1,1)的Q值等于:

代码语言:javascript
复制
Q((-5,-5),MOVE(1,1)) = 1*( R((-5,-5),(1,1),(-4,-4))+ gamma*V(-4,-4)))

目前,奖励也是0,因此第一次计算的值很简单:

代码语言:javascript
复制
Q((-5,-5),(1,1)) = 1*(0+gamma*0) = 0

第一次更新中的所有移动操作都将以类似的方式计算。通过成功的抛出向系统添加值。因此,我们可以计算特定抛出动作的Q值。之前,我们发现从(- 5,5)到50度的投掷方向的概率等于0.444。因此,此操作的Q值相应更新:

代码语言:javascript
复制
Q((-5,-5),THROW(50)) =0.444*(R((-5,-5),(50),bin) + gamma*V(bin+))) +(1–0.444)*(R((-5,-5),(50),bin) + gamma*V(bin-)))

再一次,奖励设置为o,箱子的正值是1,而箱子的负值是-1。因此,我们有:

代码语言:javascript
复制
Q((-5,-5),THROW(50)) =0.444*(0 + gamma*1) +(1–0.444)*(0 + gamma*1) = 0.3552–0.4448 = -0.0896

很明显,尽管在第一次更新之后移动不会改变初始值,但是由于距离和丢失的概率,在50度时抛出会更糟糕。

一旦计算出所有状态和操作的每个Q(s,a),每个状态的值V(s)将更新为该状态的最大Q值。这个过程反复进行,直到结果收敛。

这需要重复的次数没有限制,这取决于问题。因为我们的环境非常简单,它实际上只需要10次更新就可以收敛到最优策略。

我们首先通过如下所示的一个简单的彩色散点展示基于投掷或移动的最佳动作。

改善最优政策的可视化

虽然图表显示了最佳动作是抛还是移动,但它并没有告诉我们这些动作的方向。因此,我们将把每个最优操作映射到一个向量u和v,并使用它们创建一个抖动图,详见:

(https://matplotlib.org/api/as_gen/matplotlib.axes.axes.quiver.html)

我们定义箭头的大小和使用这个标签定义水平分量u。对于运动动作,我们只是在x方向上运动乘以这个因素。对于方向,我们要么向左或向右移动一个单位(占没有为0或180度水平运动和垂直运动在90或270度)。

然后,水平分量用一些基本的三角学知识来计算垂直分量,在这里,我们再考虑一些可能导致计算误差的角度。

我们看到一些州有多个最佳行动。那些直接朝北,朝东,朝西的可以向多个方向移动而状态(1,1)(1,1,-1)(1,1,-1)(1,1,-1)和(-1,1)可以向垃圾桶移动或朝垃圾桶扔。

最后,我决定通过导出每个情节并将其传递到一个小动画中来显示每次更新时最优策略的变化。

第3阶段: 概率未知时,寻找最优策略

Q学习算法

我们现在假设这个人不知道概率,因此需要经验来找到最优的行动。

首先,让我们试着找出最优的行动,如果这个人开始在一个固定的位置,垃圾桶是固定的(0,0)像以前一样。

我们将应用Q-Learning,初始化所有值为0的状态-动作对,并使用更新规则:

我们让算法可以选择在任意360度方向(到整个角度)或移动到当前位置的任何位置。因此,它可以移动的地方有8个:北部、东北部、东部等等。

当它选择扔纸的时候,它要么得到+1的正面奖励,要么得到-1的负面奖励,这取决于它是否扔到垃圾桶里,这一集是否结束。

它需要通过多次尝试和错误尝试来确定垃圾箱的位置,然后确定是先移动还是从当前位置抛出更好。

Q学习的伪代码

首先,与前面一样,我们使用任意值0初始化q表。

现在,这一迭代周期的开始的位置将被固定在一个状态,我们也会对每一周期的动作数量设置一个上限,这样它就不会意外地没完没了地进行下去。

如果纸张被抛出,这一周期都会自然结束。算法执行的操作由epsilon-greedy 操作选择过程决定。在该过程中,操作根据epsilongreedily(当前最大值)的值进行随机选择。

为了在移动或抛出操作之间稍微平衡随机选择(因为只有8个移动操作,但是有360个抛出操作),我决定给算法50/50的移动或抛出机会,然后从这些操作中随机选择一个操作。

和之前一样,随机动作不能超出房间的边界,一旦发现,我们会根据所有可能的后续动作的最大Q(s,a)更新当前的Q(s,a)。例如,如果我们从(-9,-9)移动到(-8,-8),Q((-9,-9),(1,1))将根据包括抛出操作在内的所有可能操作的最大Q((-8,-8),a)进行更新。

如果算法抛出纸张,则计算该抛出成功的概率,我们模拟在这种情况下,该抛出是成功,则获得正的奖励,而失败则获得负奖励。

算法继续更新每个状态对的Q值,直到结果收敛。

我们将在下一篇文章中分析不同参数的影响,但现在只介绍一些任意参数的选择:

代码语言:javascript
复制
  — num_episodes = 100
 — alpha = 0.5
 — gamma = 0.5
 — epsilon = 0.2
 — max_actions = 1000
 — pos_terminal_reward = 1
 — neg_terminal_reward = -1

使用这些参数运行算法10次,我们为状态- 5,5产生以下“最优”操作:

很明显,这些并不是一致的,这意味着这些行动实际上并不是最优的。因此,我们需要考虑我们选择的参数如何影响输出,以及如何改进结果。

结 论

我们在Python中从头引入了一个环境,并找到了最佳策略。此外,我还介绍了用Q-learning寻找最优策略的方法。

我们将在后续文章中继续这一过程,并通过改变参数来改进这些初始结果。现在,我希望这足以让您开始在这个示例中尝试他们自己的算法。

原文链接:

https://towardsdatascience.com/reinforcement-learning-from-scratch-designing-and-solving-a-task-all-within-a-python-notebook-48c40021da4

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 决策智能与机器学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档