课程实录|PPO × Family 第二课:解构复杂动作空间(上) | 您所在的位置:网站首页 › 旋翼无人机原理图 › 课程实录|PPO × Family 第二课:解构复杂动作空间(上) |
本节课将进入 PPO × Family 系列课程的第一个专题:解构复杂动作空间。 如果想将各种各样的深度强化学习算法应用在实际问题中,那么第一步就是需要将原始的自然决策问题转化为标准的马尔科夫决策过程(MDP),具体来说就是需要去定义清楚 MDP 五元组的各个元素,比如状态,动作,奖励等等。而本节课将会从动作空间入手,首先,概述性地讲解动作空间的特点,然后,会选取四种主流的决策动作空间(离散、连续、多维离散、混合)一一展开,最终希望能够使用一个 PPO 算法去解决上述四种动作空间,从“算法-代码-应用”三合一的角度来探索各类决策输出的最佳方案,做到真正意义上的决策万能钥匙。 动作是智能体(Agent)与环境交互时做出的决策行为,即决策算法的输出,动作空间 (Action Space) 是指所有可能动作的集合,是马尔科夫决策过程的五元组元素之一。将原始决策问题的输出端抽象为合适的动作空间,并配合使用相应的决策算法,是通向高效强大决策智能体的必经之路。 动作空间的分类离散和连续动作是最经典最基本的两类动作空间,在此基础上,又可以推广到更复杂的多维离散动作空间和混合动作空间。在经典的强化学习学术环境中,如图3所示,离散动作空间的例子包括 Super Mario Bros 和 Procgen 环境,相应的,连续动作空间一般则会和机器人更相关,例如图中所示的 DeepMind Control 和 PyBullet 环境,而多维离散(multi-discrete)和混合(hybrid)动作空间,则更多对应生活实际中的一些决策应用。总结来看,动作空间可以总结出如下几条特点: 不同的动作空间常需要不同的算法:例如处理离散动作空间常用一些 value-based 方法(DQN)和策略梯度方法(PPO),而连续动作空间则会涉及更多策略梯度方法的变体,例如 PPO、DDPG、SAC。这些算法在设计之初就会为对应的动作空间做一些特殊的设计,进而使得它们在这些场景上会有一定的优势。标准的 RL 算法常需要对特定动作进行适配和定制化:比如想将标准的 PPO 算法应用到上述四种动作空间上,那么就需要针对具体的动作空间添加一些算法设计和技巧,这也是 PPO × Family 课程设计的重要动机之一。同一个环境可以用不同的动作空间:基于对决策问题(环境)的领域知识,基于对强化学习算法的使用经验,可以对原有环境的动作空间做一些改造,让改造后的动作空间更适合于算法训练和部署。动作塑形(Action Shaping)上文中提到的动作空间改造,又被称为动作塑形(Action Shaping),即对原始的动作空间进行各种预处理和特征工程操作,转化为更适合 RL 的空间,下表就总结了实践中[1] 常用的一些动作塑形操作和变换前后动作空间的类型,其中标明的三种最常用的变换分别为: DC:连续动作空间离散化RA:去除部分冗余或无意义的动作CMD:将多维离散动作空间转换为离散动作空间基于上述 Action Shaping 方法的结果,本节课将会关注跟算法设计联系更加紧密的部分,结合 PPO × Family 在不同动作空间上的算法理论设计、代码实现、衍生应用三方面的相关知识,详细讲述 PPO 如何解构各类动作空间。 2.2 离散动作空间离散动作空间是最经典、最常规的动作空间,一般是相对连续动作而言的概念,具体由有限数量的动作组成,包含特定任务中所有可用的离散控制指令,可以类比机器学习中的分类任务。这里我们举一些离散动作空间的实际例子: 石头剪刀布游戏,可选择的动作有三种。红白机游戏,可选择的动作为游戏手柄上的按键(上下左右BA)。理论:PPO 如何建模离散动作空间策略定义如果智能体正在玩超级马里奥游戏,那么将当前游戏这一帧的画面(下图所示)记为图片观察状态 s 。而智能体在观测到状态 s 后,可选择的动作集合则记为 a \in \{{left, right, up} \} ,即一个标准的3维离散动作空间,每次决策需要从这三个离散动作中选择一个。 基于上述的状态和动作定义,智能体往往需要从数据中学习到策略 \pi ,即向策略 \pi 输入状态,它将输出所选动作,或是选择每个动作的概率,对于 PPO 来说,具体是学习一种随机性策略,即给定一个某时刻 t 马里奥的游戏画面,即图片观察状态 s_t ,PPO 智能体策略输出选择各个离散动作的概率分布 \pi(a_t|s_t) ,一个具体的实例为: \pi(left|s) =0.2 表示选择向左动作的概率是0.2\pi(right|s)=0.1 表示选择向右动作的概率是0.1\pi(up|s)=0.7 表示选择向上动作的概率是0.7计算图和动作采样PPO 是一种深度强化学习算法,由于策略要建模的“状态-动作”之间的映射在实际问题中可能比较复杂,所以结合神经网络来实现参数策略函数 \pi(a|s) ,对于这个策略神经网络,输入状态 s ,网络就输出每一维离散动作 a_i 对应的 logit 值,比如上文所示的马里奥游戏就是最终输出3个 logit 值,完整的输入输出数据流可以参考下图: logit 的含义是神经网络 \pi(a|s;\theta) 的原始输出(比如最后一层全连接层的输出,不加激活函数,取实数范围),离散动作空间有 k 个动作,则策略网络输出 k 个动作相应的 logit 值。这些 logit 值经过 softmax 函数即可得到当前策略 \pi(a|s;\theta) 选择每个离散动作的概率。 关于 logit 的进一步理解可以参考知乎博客:如何理解深度学习源码里经常出现的logit [2]在获得智能体策略选择各个离散动作的概率之后,一般常有两种采样动作的方式: 确定性决策(determinstic decision):直接贪心选择 [3] 概率最大的那一维动作 (一般实现中直接选择 logit 最大的,因为 softmax 函数并不改变 logit 的相对大小,即 \mathop{\mathrm{argmax}}\limits_{a\in \mathcal{A}}{\pi(a|s;\theta )} )。随机性决策(stochastic decision):根据之前将 \pi(a|s) 的输出经过 softmax 函数后获得的概率值,构造相应概率分布(离散动作空间即对应玻尔兹曼分布 [4]) 进行抽样得到动作。随机性决策一般用于 PPO 智能体收集数据的过程,由于强化学习是一个在线训练的过程,所以训练中需要保持足够的探索程度(即概率低的动作也有被采样到的可能性),同时也更多地利用概率高的动作。此外,为了更精细地控制这一点,部分任务中还会在 softmax 处设置专门的温度系数来控制概率分布的平滑程度。另一方面, PPO 智能体训练过程中也会定期进行评测,分析当前智能体的性能。这时则会根据情况选择使用确定性决策还是随机性决策。一般来说,对于环境简单,干扰噪声因素较少的环境(例如超级马里奥),确定性决策往往能直接给出优秀的解。而另外一些过于复杂,环境中随机性较大,最优策略不唯一的环境(例如星际争霸2,局部视野的迷宫),使用随机性决策则可以获得比较高的期望收益。在确定了智能体策略的计算图和采样动作的方式之后,我们就可以让智能体和环境不断交互,产生一系列轨迹数据用于训练,整个交互流程如下图所示: PPO 在离散动作空间上的算法理论其实很简单,大部分的算法设计很容易实现,具体可以参考课程第二章的相关代码。但其中关于随机性决策采样动作的部分,仍存在一些特殊的地方。关于如何在深度学习中构建和使用概率分布,TensorFlow 的作者们在2017年提出了关于这部分的标准设计 [5]。本课程中我们结合 PyTorch 中具有相似功能与设计的概率分布模块 torch.distribution [6] 来进行讲解。 torch.distribution 实现了各种概率分布,以及相关用于抽样和计算统计数据的方法。如对于离散动作空间,我们使用 torch.distribution.Categorical 来构建策略神经网络输出的离散动作概率分布,决策时直接使用它的函数sample()即可返回抽样结果。 而要深入了解torch.distribution的工作原理,就要理解三种类型的shape,即 Sample shape、Batch shape 和 Event shape,它们对于理解 torch.distribution 至关重要。 Sample shape 为针对单个分布的采样次数,在使用sample(sample_shape)时指定,即从这个分布中独立同分布地采样多个值。Batch shape 为用于采样的(不同)分布的个数,例如对于一批(batch)样本,采样每个样本对应的动作。Event shape 为单个分布本身的维度,具体使用时跟概率分布的语义强相关,例如后续更复杂的动作空间,可能需要考虑多重动作之间的关系。一个更具体的演示图如下所示 [7]: 完整的“算法-代码”一一对比详细讲解,读者可以参考 PPO × Family 课程的注解文档,一个示意图如下: 在明确 PPO + 离散动作空间的算法理论和代码实现细节后,我们尝试来应用相关知识解决相应的实际问题,这里选择简化后的火箭回收任务中的离散控制问题。本章节将会介绍环境的各种细节定义以及使用 PPO 的实践经验。问题背景2021年3月4日,美国得克萨斯州 Boca Chica 测试基地,SpaceX 的星舰飞船原型 SN10 再次表演了一场空中杂技,实现了星舰高空试飞的首次平稳落地,下图是 SN10 发射和着陆的实际情况 [8]: 本课程修改并简化了开源代码环境 Rocket-recycling [9] 中模拟 SN10 的回收落地任务,并将其作为 PPO 做离散控制的示例之一,可以在1-2小时内训练收敛。具体来说,这个任务就是要控制火箭从水平的初始状态,不断调整发动机的推力从而控制姿态,最终成功竖直平稳落地。实际的环境实现是一个简化模型,考虑了基本的气缸动力学模型,并假设空气阻力与速度成正比。火箭底部安装了推动力为矢量的发动机,强化学习的目标也就是控制这些发动机的相关参数。具体原理图如下所示,将原始连续的推力控制离散化为三个角度 × 三种推力的九维离散动作空间: Rocket-recycling 仿真环境的 MDP 基础元素定义如下: 初始条件• 初始速度设置为 -50m/s。• 火箭方向设置为 90°(水平)。• 着陆燃烧高度设置为离地 500m。• 水平方向初始位置随机动作空间• 推力:推力可调值为 0.2g、 1.0g和 2.0g• 喷嘴角速度: 可调节为 0、 20°/s和 -20°/s• 注意也就是只有 9 个组合,动作空间 shape 为 (9,)观察空间• 位置 (x, y) :即火箭在画布中的位置,范围分别为 (-300, 300)和(-30, 570)• 速度 (vx, vy):即火箭在 x和 y方向上的速度• 箭身角度 θ :即火箭箭身与竖直方向的角度,范围为 [0, 360°]•箭身角速度 vθ :即火箭箭身旋转角速度•喷嘴角度 :范围 (-20°, 20°)• 时间t奖励空间由两部分组成reward = dist_reward + pose_reward• dist_reward 距离目标着陆位置的度量• pose_reward 偏离正中线的位置(theta,正负)• shape (1,),类型为 float一般情况下,复杂机械的控制大多都为连续控制,但在精度要求不是特别高的问题中,合理的离散化将会大大提升问题的解决效率 [10]。具体来说,这里将发动机的推力与喷嘴角度进行组合,预设了9个可选的离散动作,即:(0.2g, 0), (0.2g, 20°/s), (0.2g, -20°/s)(1.0g, 0), (1.0g, 20°/s), (1.0g, -20°/s)(2.0g, 0), (2.0g, 20°/s), (2.0g, -20°/s) 实验结果展示下方的图13展示了 PPO 智能体控制火箭回收的完整训练过程,纵轴是每局游戏结束(坠毁或者成功降落)智能体获得的累积回报值,横轴是智能体和环境交互的步数,最终 PPO 智能体可以学习到稳定的火箭回收控制策略。 由于强化学习是一个需要平衡探索和利用的过程,所以需要不断尝试各种决策行为,并根据奖励反馈学习到最优策略。通过对回放视频以及累积回报值的观察,可以发现 PPO 智能体的学习可以主要分为以下几个阶段: 乱喷气直接坠落(0-100k)先学会前半程的hover(200k-500k)然后学习轨迹的落点(大趋势)尽量靠近目标区域(不论中间怎么翻滚)(600k-1M)学会落地减速(但是落地太想靠近目标区域,所以临近落地疯狂翻转)(1M-2M)开始探索较短的轨迹(反复横跳)(2M-3M)学习落地保持竖直(保持后半程的竖直,一定程度上放弃对目标中心的追求)(3M-5M)最终训练收敛时获得的策略和随机初始化策略的行为对比视频如下,完整样例可以参考官方示例 ISSUE: ![]() 在剖析完 PPO 对于离散动作空间的设计之后,本节课第二部分将会聚焦到连续动作空间。离散和连续是决策问题中两种最基本的空间类型。它们之间的关系可以类比于二进制世界中的整型变量与浮点型变量一样,互相独立存在,却又有着密切的联系。换个角度来说,在现实宏观世界中,大部分的事物都是连续地在时空内变化的,只是为了人类定义和使用的方便,或是受限于工具与条件,需要将一些连续变量抽象成不同离散化的选项,构造出一些离散的情形。 引言:连续动作空间的定义通俗点来说,连续空间往往是一个“充实又稠密”的空间,即对于空间中任意一个点,在某种距离函数的定义下,该空间中总存在一些不同于该点的,但距离无穷小的其它点。这一说法的严格的数学定义如下: 连续空间是一个完备测度向量空间,即指一个拓扑空间 X ,假使对该拓扑空间 X 定义一种度量函数 F(x,x') ,对于拓扑空间 X 中的任意点 x ,该点的任意邻域内都存在一个柯西序列:即对于任意小的正实数 r ,序列中都存在一个序数 M ,使得序列中所有序数大于 M 的点 x_N , \forall N>M ,与 x 的距离都小于该正实数, F(x_N,x)此外,对于具体的决策问题,也可以根据情况把问题建模成不同的 MDP,例如强化学习的经典环境 Lunarlander(模拟月球着陆器),就提供了离散和连续2种不同的控制方式: 离散控制模式:对应着4个离散动作,分别为:什么都不做,启动左方向引擎,启动主引擎,启动右方向引擎(启动引擎的推力为一个固定值)。连续控制模式:对应着2个连续的动作变量,即主引擎和助推器的开启力度。前者训练起来更加简洁高效,而后者可以允许更细粒度的操控。部分强化学习环境中的离散动作空间往往都是将原始连续动作中经过某种归类方式获得,是连续动作的某个特殊形式。 连续动作空间的特点 更具体地,本章节以经典的学术环境双足机器人行走(bipedalwalker)为例,具体分析连续动作空间的特性。在这个环境中,智能体的任务目标是控制机器人平稳走到右端的终点。如上图所示,具体的决策输出是一个4维的连续变量,这四个维度分别是其机器人位于臀部关节和膝盖关节的铰链的马达转速。对比这样的连续动作空间和上文提到的离散动作空间,我们可以发现: 离散动作空间是非连续的动作的集合(类似分类问题),而连续动作空间是连续的,稠密的,不可数个动作元素组成的连续区间(类似回归问题)。在连续空间中的个体,总能找到许多与它特别相似甚至相同的另一个体;而在离散空间中,不存在完全相同的个体,每个元素自成一派。一般而言,连续动作空间中的变量可以根据具体取值来衡量数值大小和远近关系。比如放置物体时的位置坐标,抛掷物体时的施加力的大小(例如 1.1N > 1N ,那么 两者之差 0.1N 能够明确表达两个力之间的数量关系差异)。而离散动作空间中的变量,则需要用一组类别来区分彼此,集合中各个不同的状态点或动作点之间存在着显著的性质上的差异,但他们之间并没有具体的数量关系(比如之前的马里奥游戏中0指代向左2指代跳跃,但两者相减并没有实际意义)。具体实例比如十字路口处的直行左转右转,开关阀门的开启与闭合等等。总结来说,连续动作空间的特点可以概括为以下三点: 连续的,稠密的,不可数个动作元素组成的连续区间(类似回归问题)可以根据具体取值来衡量数值大小和远近关系可以直接回归,也可构建概率分布采样动作(参数化分布)基于上述分析,关于 PPO 和连续动作空间相关的算法设计,本章节将会从以下两部分展开: 如何设计 PPO 算法去输出连续动作PPO 和其他连续空间上的决策算法(以 DDPG 为例)的对比计算图设计(前向和反向计算图)对于 bipedalwalker 环境这样的连续动作空间如何使用 PPO 算法。这里将从前向和反向计算图分别展开: 另外,对于连续动作空间,如果某个连续动作的最优解是单峰的(大多数控制任务中很常见),就常常使用高斯分布来建模连续动作。一个高斯分布的形态,只决定于其均值向量 \mu 与协方差矩阵 L 。因此仅需让策略神经网络输出高斯分布的均值与方差的数值,随后从该分布中采样即可。除此之外,实际应用中也可以做进一步简化,如果假设不同维度的连续动作是互相独立的分布,那么协方差矩阵可以退化为对角矩阵 [\sigma_{ii}] 。注:关于强化学习算法和重参数化方法的进一步联系可以参考本节课的补充材料。 PPO 与 DDPG 算法对比PPO 和 DDPG 都可以用于经典连续动作空间的决策问题,那么这两个算法相比有什么不同点呢?设计理念 PPO 算法来自论文《Proximal Policy Optimization Algorithms》,是经典的策略梯度算法的延伸,中文译为近端策略优化算法。顾名思义,PPO 主要是围绕第一节课中提到的策略提升定理展开,也就是 TRPO 算法的相关算法设计和逻辑,核心思想是在一个临近的信赖区域内,让策略朝着优化目标前进(即最大化累计回报),由此推导出的算法是在原始优化目标的基础上,额外增加单次优化前后,对策略变化距离的限制。只是在具体优化实现中,PPO 的前身 TRPO 为了控制优化中策略的变化幅度,在算法中使用了优化前后策略函数的 KL散度作为约束,进而优化方法较为复杂(具体可参考课程第一讲的补充材料),而 PPO 继承了 TRPO 的核心理念,采用了更易于计算的 clip 函数替代 KL 散度来限制策略的更新幅度,侧重于保持策略函数的近端优化和渐近单调提升,同时,其价值函数主要起辅助评价作用,只是用来计算优势函数 Advantage,类似一个权重乘到优化项上,并不传递梯度: $J^{\text{CLIP}}(\theta')=\mathbb{E}_{(s_{t}, a_{t})\sim \pi_{\theta'}}[\min(\frac{p_{\theta}(a_{t}|s_{t})}{p_{\theta'}(a_{t}|s_{t})}A^{\theta'}(s_{t},a_{t}),\text{clip}(\frac{p_{\theta}(a_{t}|s_{t})}{p_{\theta'}(a_{t}|s_{t})}, 1-\epsilon,1+\epsilon)A^{\theta'}(s_{t},a_{t}))] 相应的,DDPG 算法来自论文《Continuous control with deep reinforcement learning》[11]。DDPG 的全称为 Deep Deterministic Policy Gradient,中文译为使用深度学习的确定性策略梯度算法。虽然和 PPO 一样,它们俩都是 Actor-Critic 系列算法,但两者的设计理念区别很大,DDPG 使用了确定性策略,即一个参数化的策略函数 $\mu(s|\theta_\mu) ,而 PPO 是随机性策略,输出一个选择动作的概率分布。DDPG 算法围绕优化动作价值函数(Q Function)展开,侧重于最小化价值函数的建模误差,而其策略函数由对价值函数求极值的方式引导生成。如图20所示,就是策略网络输出一个动作,交给价值网络来判断动作的好坏,并通过价值网络回传梯度来指导策略进行更新(特性上更类似于Deep Q-learning [12]),更详细的关于 DDPG 算法设计的细节可以参考原始论文。数据属性(On-Policy VS Off-Policy) 从数据属性上看: PPO 需要尽可能地选用最新 Policy 采样获得的数据轨迹,是一个 on-policy 算法。而 DDPG 则可以使用来自不同的 Policy 生成的数据,对当前的 Policy 进行训练,是一个 off-policy 算法。PPO 算法需要使用在线数据是由策略提升定理的本质决定的 [13-14],即使用下述公式进行更新: \eta(\pi')=\eta(\pi)+E_{s,a \sim \pi'}(\Sigma_t{\gamma^tA_\pi(s,a)})=\eta(\pi)+\Sigma_s\rho_{\pi'}(\Sigma_a\pi'A_\pi(s,a)) 这个公式从原理上来讲,就是对于迭代更新前后的两个策略函数 \pi 与 \pi' ,如果希望它们的总回报值有稳定的更新提升,即 \eta(\pi')>\eta(\pi) ,那么需要将目标函数设定为此式,并优化 \pi' 使其最大化累计回报 \eta(\pi') 。但在实际操作中无法获得更新后的轨迹 \rho \sim \pi' 的数据,因而只能选取更新前的轨迹 \rho \sim \pi ,来近似最大化下式: J(\pi')=\eta(\pi)+\Sigma_s\rho_{\pi'}(\Sigma_a\pi'A_\pi(s,a))\approx\eta(\pi)+\Sigma_s\rho_{\pi}(\Sigma_a\pi'A_\pi(s,a)) 相应地,为了使策略提升定理有效,需要保证两个策略接近,它们所采集的轨迹也接近,这样才可以使训练稳定。而 DDPG 算法则并不依赖在线数据,这是因为 DDPG 的优化思路来源于 DPG,使用最小化均方贝尔曼误差来拟合值函数,随后使用值函数来引导策略函数的生成,并不会对动作求积分,因此可以使用不同策略的数据进行优化: L(\theta_Q)=E_{data}{(Q(s,a)-(r+\gamma \max Q_{target}(s',a')))^2} J(\theta_\mu)=E_{data}{(Q(s,\mu(s|\theta_\mu)))} 从算法性质上讲,DDPG 的优化思路更接近于 value-based 方法,其算法可靠性和值函数本身的建模质量很相关。注:关于 PPO 和 DDPG 中是否使用重要性采样的详细思考可以参考本节课的相关补充材料。代码:如何实现高斯分布的策略函数关于 PPO 对于连续动作空间神经网络设计的部分,可以参考课程第二章的相关代码。以下部分将进一步详述如何使用 PyTorch distributions 库的相关函数,实现使用高斯分布来将动作参数化的方法: a|s\sim \mathcal{N}(\mu(s),\Sigma(s)) \pi(a|s)=\frac{\exp({-\frac{1}{2}{(a-\mu)}^T\Sigma^{-1}(a-\mu)})}{\sqrt{{(2\pi)}^{k}{|\Sigma|}^{-1}}} 独立分布的动作对于独立分布的动作,我们可以使用多个独立分布的单维高斯分布来实现参数化。因为一个单维高斯分布由均值 \mu 和方差 \sigma^2 构成,对于 PyTorch distributions Normal 类,我们需要提供均值 \mu 和标准差 \sigma 。由于标准差是非负数,我们可以使用对数来构造一个无界的标准差的参数,然后再用指数操作来还原它。如果环境有动作区间的限制,除了通过环境中适配截断动作这个处理办法之外,我们也可以通过函数变换,来让无界的高斯分布,限定至一个有界的区间内。 import torch from torch import nn from torch.distributions import Independent, Normal, TransformedDistribution, TanhTransform # Get mean vector mean = nn.Parameter(torch.zeros(action_dim)) # Get log_sigma to ensure sigma is positive log_sigma = nn.Parameter(torch.zeros(action_dim)) # usually they are model output mean, log_sigma = model(obs) # Define Independent Normal distribution with 1 Batch size sigma=torch.exp(log_sigma) # Get normal distribution and reinterpret 1 batch dim to be event dim distribution = Independent(Normal(output_mean, output_std), reinterpreted_batch_ndims=1) # Transform distribution into a bounded interval by functions such as Tanh into [-1,1] if you need to do so. distribution = TransformedDistribution(base_distribution=distribution, transforms=[TanhTransform()]) # Sample action from Distribution with Autograd to it action=distribution.rsample() # Sample action from Distribution without Autograd to it action=distribution.sample()非独立分布的动作对于存在协方差的非独立的动作分布,我们可以使用一个多维高斯分布来实现参数化。多维高斯分布由均值向量 \mu 和协方差矩阵 \Sigma=LL^T 构成。对于 PyTorch distributions MultivariateNormal 类,我们可以提供均值 \mu 和协方差矩阵 \Sigma 来构造它。因为协方差矩阵是一个对称的(半)正定矩阵,而且需要符合几个特殊要求: 各维度标准差为非负。协方差项的绝对值,小于两个标准差项之积。等价于相关系数位于 [-1,1] 之间。但是我们无法直接使用一个矩阵来编码协方差矩阵 \Sigma ,那样参数自由度太大。而其矩阵分解的下三角矩阵 L 虽然满足自由度的数目,其所需满足的边界要求也不易编码。因此,我们需要借助容易编码边界的相关系数矩阵 C ,和标准差向量 \sigma ,来构造协方差矩阵 \Sigma=[\sigma_{i}c_{ij}\sigma_{j}] 。矩阵 C 自由度为 \frac{(D-1)(D)}{2} ,标准差向量 \sigma 自由度为 D ,共计 \frac{(D+1)(D)}{2} 个参数变量。 import torch from torch import nn from torch.distributions import Independent, MultivariateNormal, TransformedDistribution, TanhTransform, CorrCholeskyTransform # Get mean vector mean = nn.Parameter(torch.zeros(action_dim)) # Get log_sigma to ensure sigma is positive log_sigma = nn.Parameter(torch.zeros(action_dim)) # Get correlation_param to ensure sigma is positive correlation_param = nn.Parameter(torch.zeros(action_dim*(action_dim-1)//2)) # usually they are model output mean, log_sigma,correlation_param = model(obs) # Define Independent Normal distribution with 1 Batch size sigma=torch.exp(log_sigma) # Get low triangle decomposition matrix of correlation matrix low_tri = CorrCholeskyTransform()(correlation_param) # Get covariance matrix corvar_matrix=torch.mul(torch.einsum('bij,bkj->bik', low_tri, low_tri), torch.einsum('bi,bj->bij', sigma, sigma)) # Get multivariate normal distribution and reinterpret 1 batch dim to be event dim distribution = Independent(MultivariateNormal(loc=mean, covariance_matrix=corvar_matrix), reinterpreted_batch_ndims=1) # Transform distribution into a bounded interval by functions such as Tanh into [-1,1] if you need to do so. distribution = TransformedDistribution(base_distribution=distribution, transforms=[TanhTransform()]) # Sample action from Distribution with Autograd to it action=distribution.rsample() # Sample action from Distribution without Autograd to it action=distribution.sample()实践:使用 PPO 来解决无人机姿态控制问题在明确 PPO + 连续动作空间的算法理论和代码实现细节后,我们尝试来应用相关知识解决相应的实际问题,这里选择一个简明的无人机姿态连续控制问题。本章节将会介绍环境的各种细节定义以及使用 PPO 的实践经验。 问题背景近年来,多旋翼无人机技术发展迅速,该技术已经能够赋予很多传统行业一些新的技术方法和商业解决方案,比如物流业、农林业、旅游业等。本节课以一个开源的无人机模拟环境—— gym-pybullet-drones [15-16] 为例介绍 PPO 在连续动作空间上的应用。研究对象是一台性能指标开源的四旋翼小无人机,bitcrazeflie [17]。我们选定了一个简单的任务 Flythrughgate,目标是让四旋翼无人机从原点出发,飞行穿过一座门框。 状态空间:该任务的状态空间为一个12维度的连续空间,按顺序分别是: 变量性质区间备注x, y, z,无人机在世界坐标中的位置[-1,1]经过clip截断函数和scale范围缩放处理,对于z坐标,被限制在[0,1]之内y, p, rr~roll滚转角, p~pitch俯仰角,y~yaw偏航角[-1,1]r~roll滚转角与p~pitch俯仰角,经过clip截断函数和scale范围缩放处理。y~yaw偏航角仅经过scale范围缩放处理。vx, vy, vz无人机在世界坐标中的速度[-1,1]经过clip截断函数和scale范围缩放处理wx, wy, wz无人机在世界坐标中的角速度[-1,1]经过clip截断函数和scale范围缩放处理动作空间:该任务提供了多种控制无人机的模式,包括PID控制模式,转速控制模式等,对应着不同的动作空间。 (\frac{20*\Delta{RPM}_0}{{RMP}_{hover}},\frac{20*\Delta{RPM}_1}{{RMP}_{hover}},\frac{20*\Delta{RPM}_2}{{RMP}_{hover}},\frac{20*\Delta{RPM}_3}{{RMP}_{hover}}) 上式中的分子是各个旋翼转速与悬停转速的差值,分母是悬停转速,整体取值范围为 [-1,1] 2.PID 算法修正 position 模式,三维连续空间: (10*\Delta x,10*\Delta y,10*\Delta z) 分别是各个方向上所期望无人机运动的位置修正量的10倍大小,单位为米,取值范围为 [-1,1] 。即智能体只需要给出下一步期望到达的空间运动量,PID 算法将根据当前位置和期望运动量计算得出实际的操作控制信号。 3.PID 算法修正velocity 模式,4维连续空间: ({V_x}/|V| , {V_y}/|V| , {V_z}/|V|, |V|/|V_{max}|) 分别是各个方向上的速度分量的相对大小,以及速度相比系统最大允许速度的相对大小。 采用第一种方式,直接控制无人机四个旋翼各自的转速,将其作为智能体的动作输出,这在物理概念上十分直观。但这种模式在实际训练中会使得无人机的状态十分不稳定,常常倾斜起飞或翻转,而无法达成目标。这是为什么呢?举例来说,如果想让无人机学习到竖直原地起飞这样的动作,就需要它控制四个旋翼转速保持一致,这件事对于人类来说是很简单的概念,但对于智能体来讲是庞大的连续动作空间中的一个点,因此它很难在没有任何辅助信息的情况下探索到这件事。在实际运行中,还会可以发现四个旋翼之间的配合度往往会比较差。因为转速的变化在带来升力的同时也会带来扭矩,扭矩会传递给整体,带来整体的姿态变化,而姿态的变化会影响力的方向,进而让无人机进入负面的状态而产生损失,强化学习算法因此也难以训练。为了解决第一种动作空间的问题,可以借助课程一开始讲到的 Action Shaping 的思路,具体来说就是将强化学习和经典控制理论中的 PID 结合起来使用,即对应到第二和第三种控制方式。实践中,采用 PID 算法可以很大程度上协调和统一四个旋翼之间的转速和配合。因此智能体在这类模式下,训练较为平稳,无论是 PID-position 还是 PID-velocity 模式下都有较好的效果,课程中为了简便主要使用 PID-position 模式。 奖励空间:四旋翼无人机的每个时刻都会基于其位置而获得奖励,计算方法如下: $r(x,y,z)=-10*([x,y,z]-[0,-2*\frac{t}{T},0.75])^2 通过奖励函数的组成,可以看出,该任务将激励无人机往y值减小,且z值增大至某一定高度的轨迹上飞行。此外,由于还会受到不可见的障碍物的影响(门框与地面),存在损失和错过奖励的风险。因此,在该任务中无人机需要学习成功起飞,飞离地面,通过试错的方式,感知和躲避障碍。 实验结果展示接下来的部分将介绍 PPO 智能体完整的训练过程,具体分析使用 PPO 控制 Flythrughgate 的的各个训练阶段: 在初始阶段(训练迭代0~200K),从视频中可以看到,四旋翼无人机驻留在原地,还未学会起飞。这是因为根据强化学习环境的奖励的设计,此时无人机会在每一帧收到一个比较差的 reward。这个阶段 PPO 算法的 Actor 的策略网络显然还无法输出好的决策,这是因为从 Critic (价值网络)是随机初始化的,无法给出正确引导,它需要拟合现状,学习到停留在原地是坏的决策(这从 Critic 输出的均值逐渐下降可以看出,即下图红色箭头):![]() |
CopyRight 2018-2019 实验室设备网 版权所有 |