从头开始强化学习:在Python中设计和解决任务(仅包含部分代码)
第1阶段:定义环境
任务
从一个房间的任何位置将一张纸投入垃圾桶。我可以将纸张向任何方向移动。
虽然对于能够通过视力判断垃圾桶位置并且具有关于距离的大量先验知识的人来说很简单,但是机器人必须从中学习。
这定义了这样的环境,其中成功投掷的概率是基于投掷纸张的方向和当前距离桶的距离来计算的。
例如,在下面的图像中,我们有三个标记为A,B和C的人.A和B都向正确的方向投掷,但是A比B更接近,因此着陆投射的概率更高。
C比B更接近但是朝着完全错误的方向投掷,因此击中垃圾桶的概率非常低。这可能看起来不合逻辑,C会向这个方向投掷,但是,正如我们稍后将要展示的那样,算法必须首先尝试一系列方向来确定成功的位置,并且没有关于bin是哪里的可视指南。
任务环境示例
为了在python中创建环境,我们将图表转换为x和y值的二维维度,并计算抛出的角度。我们使用归一化的整数x和y值,因此它们必须以-10和10为界。
环境映射到二维空间
环境概率
成功投掷的概率与投掷的距离和方向有关。因此,我们需要计算两个指标:
- 当前位置距离桶(bin)的距离
- 纸张投掷角度与桶真实方向之间的差异
距离测量
如上图所示,A的位置设置为(-5,-5)。这是他们当前的状态,他们与垃圾桶的距离可以使用欧几里德度量来计算:
对于最终计算,我们将其标准化并反转该值,以便高分表示该人更接近目标物:
因为我们已经在(-10,10)之间修正了二维维度,所以该人可能的最大可能距离是来自二进制位的sqrt {(100)+(100)} = sqrt {200}。因此,我对A人的距离得分是:
方向测量
然后,A要作出决定,他们是移动还是扔向一个选择的方向。现在,让我们假设他们选择扔纸,他们的第一次投掷是50度,第二次是从正北方向60度。A的位置可以通过简单的三角学计算:
因此,第一次投掷与真实方向相差5度,第二次投掷是15度。
当我们认为好的投掷在实际方向的任一侧(即没有投掷错误的方向)45度时,我们可以使用以下来计算这个选择方向的好坏。超出45度范围的任何方向将产生负值并映射到0的概率:
两者都相当接近但他们的第一次投掷更有可能击中垃圾桶。
概率计算
因此,我们计算成功投掷的概率与这两个指标相关:
创建一个通用函数
虽然之前的计算相当简单,但在我们推广这些计算并开始考虑目标物或当前位置不固定时,需要考虑一些因素。
在我们之前的例子中,A是从垃圾桶西南方向,因此角度是一个简单的计算,但如果我们应用相同的方式来说一个人在东北方,那么这将是不正确的。此外,因为垃圾桶可以放置在任何地方,我们需要首先找到人与此相关的位置,而不仅仅是原点,然后用于建立所需的角度计算。
这在下图中进行了总结,我们根据人与箱子的相对位置推广了每个三角计算:
角度计算规则
考虑到这个图,我们创建了一个函数,该函数仅从给定位置相对于bin计算投掷成功的概率。
然后,我们根据上图计算从人到垃圾桶的方位,并计算在+/- 45度窗口内限定的分数。与方位最接近的掷出的分数越高,而离得越远的掷出的分数越低,任何大于45度(或小于-45度)的掷出都是负的,然后将其设置为零概率。
最后,整体概率与给定当前位置的距离和方向有关,如前所示。
注意:我选择了45度作为边界,但您可以选择更改此窗口,也可以手动缩放概率计算,以不同方式对方向测量距离进行加权。
我们重新计算前面的例子并找到与预期相同的结果。
绘制每种状态的概率
现在我们将其作为一个函数,我们可以很容易地计算并绘制我们的二维网格中所有点的概率,以获得固定的投掷方向。
概率由我们在前一个函数中设置的角度定义,目前这是45度但是如果需要可以减少或增加,结果将相应地改变。我们可能还希望以不同方式缩放距离。
例如,对于每一个x/y位置,当纸张以180度方位抛出时的概率如下所示。
所有投掷方向的动画展示
为了进一步证明这一点,我们可以迭代一些投掷方向并创建一个交互式动画。代码变得有点复杂,你总是可以简单地使用前面的代码块并手动更改“throw_direction”参数来探索不同的位置。然而,这有助于探索概率。
第二阶段:寻找概率已知的环境的最优政策
基于模型的方法
我们的目标是通过向给定的方向投掷或移动来找到每种状态下的最佳动作。因为我们已经知道概率,所以我们实际上可以使用基于模型的方法并首先演示它,并且可以使用以下公式实现:
值迭代更新规则
值迭代从一个任意的函数V0开始,使用下面的等式得到k+1阶段的函数从k阶段的函数到k阶段的函数。
每个状态的初值
MOVE动作的计算相当简单,因为我已经确定了保证运动成功的概率(等于1)。因此,例如来自状态(-5,-5)的动作(1,1)的Q值等于:
Q(( - 5,-5),MOVE(1,1))= 1 *(R(( - 5,-5),(1,1),( - 4,-4))+ gamma * V( -4,-4)))
目前,奖励也都是0,因此第一次计算的价值就是:
Q(( - 5,-5),(1,1))= 1 *(0 + gamma * 0)= 0
移动操作的第一个Q更新
第一次更新中的所有移动操作都将以类似方式计算。成功抛出将值添加到系统中。因此,我们可以计算特定投掷动作的Q值。以前,我们发现投掷方向从(-5,-5)开始50度的概率等于0.444。因此,此操作的Q值会相应更新:
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-)))
同样,奖励设置为0,bin的正值为1,而bin的负值为-1。因此我们有:
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的向量,并使用它们创建一个箭袋图。
我们定义箭头的比例并使用它来定义标记为u的水平分量。对于移动动作,我们简单地将x方向上的移动乘以该因子,并且对于投掷方向,我们向左或向右移动1个单位(在0或180度时没有水平移动,在90或270度时没有垂直移动) 。
然后使用水平分量来计算具有一些基本三角函数的垂直分量,其中我们再次考虑将导致计算误差的某些角度。
我们看到一些方案有多项最佳行动。那些直接向北,向东,向西的东西可以在多个方向上移动,而状态(1,1),(1,-1),( - 1,-1)和(-1,1)可以移动或朝向垃圾桶。
最后,我决定通过导出每个绘图并传入一个小动画来显示每个更新的最优策略的变化。
第3阶段:通过强化学习找到最佳策略,其中概率被隐藏
Q-learning算法
我们现在将想象人的未知概率,因此需要经验来找到最佳动作。
首先,让我们尝试找到最佳动作,如果这个人在一个固定的位置开始并且bin像以前一样固定在(0,0)。
我们将应用Q-learning并初始化值为0的所有状态 - 动作对并使用更新规则:
Q-learning更新规则
我们给算法选择在任何360度方向(整个程度)投掷或移动到当前的任何周围位置。因此有8个地方可以移动。
当它选择扔纸时,它将获得+1的正奖励或-1的惩罚,具体取决于它是否扔到垃圾桶内。
它需要通过一系列试验和错误尝试来确定桶所在的位置,然后是先移动还是从当前位置扔出来更好。
Q-Learning伪代码
首先,和以前一样,我们用任意值0初始化Q表。
如果纸张被抛出,则每个过程自然结束,算法执行的动作由ε-贪婪动作选择过程决定,其中动作以概率epsilon随机选择并且贪婪地选择(当前最大值)。为了平衡移动或投掷动作之间的随机选择(因为只有8个移动动作但是360°投掷动作)我决定给算法移动或投掷50/50的机会,然后随后从这些中随机选择动作。
如前所述,随机移动动作不能超出房间的边界,并且一旦发现,我们根据所有可能的后续动作的最大Q(s',a)更新当前Q(s,a)。例如,如果我们从-9,-9移动到-8,-8,Q((-9,-9),(1,1))将根据Q的最大值更新((-8,-8) ),a)所有可能的行动,包括投掷行动。
如果算法抛出纸张,则计算此投掷的成功概率,并且我们模拟在这种情况下它是否成功并且获得奖励或者是不成功并且接收惩罚。
该算法继续更新每个状态 - 动作对的Q值,直到结果收敛。
结论
我们在Python中从头开始引入了一个环境,并找到了最优策略。