强化学习中的关键概念
强化学习中的关键概念
强化学习的主要角色是智能体和环境,环境是智能体存在和互动的世界。智能体在每一步的交互中,都会获得对于所处环境状态的观察(有可能只是一部分),然后决定下一步要执行的动作。环境会因为智能体对它的动作而改变,也可能自己改变。
智能体也会从环境中感知到奖励信号,奖励是一个表明当前状态好坏的数字。智能体的目标是最大化累计奖励,也就是回报。强化学习就是智能体通过学习来完成目标的方法。
为了便于后面的学习,我们介绍一些术语:
- 状态和观察(states and observations)
- 动作空间(action spaces)
- 策略(policies)
- 动作轨迹(trajectories)
- 不同的回报公式(formulations of return)
- 强化学习优化问题(the RL optimization problem)
- 值函数(value functions)
状态和观察
一个状态\(s\)是一个关于这个世界状态的完整描述。这个世界除了状态以外没有别的信息。观察\(o\)是对于一个状态的部分描述,可能会漏掉一些信息。
在深度强化学习中,我们一般用实数向量、矩阵或者更高阶的张量(tensor)表示状态和观察。比如说,视觉上的观察可以用RGB矩阵的方式表示其像素值;机器人的状态可以通过关节角度和速度来表示。
如果智能体观察到环境的全部状态,我们通常说环境是被全面观察的。如果智能体只能观察到一部分,我们称之为部分观察。
动作空间
不同的环境有不同的动作。所有有效动作的集合称之为动作空间。有些环境,比如说 Atari 游戏和围棋,属于离散动作空间,这种情况下智能体只能采取有限的动作。其他的一些环境,比如智能体在物理世界中控制机器人,属于连续动作空间。在连续动作空间中,动作是实数向量。
这种区别对于深度强化学习来说,影响深远。有些种类的算法只能直接用在某些案例上,如果需要用在别的地方,可能就需要大量重写代码。
策略
策略是智能体用于决定下一步执行什么动作的规则。可以是确定性的,一般表示为:\(\mu\):
\[a_t = \mu(s_t),\]
也可以是随机的,一般表示为\(\pi\):
\[a_t \sim \pi(\cdot | s_t).\]
因为策略本质上就是智能体的大脑,所以很多时候“策略”和“智能体”这两个名词经常互换,例如我们会说:“策略的目的是最大化奖励”。
在深度强化学习中,我们处理的是参数化的策略,这些策略的输出,依赖于一系列计算函数,而这些函数又依赖于参数(例如神经网络的权重和误差),所以我们可以通过一些优化算法改变智能体的的动作。
我们经常把这些策略的参数写作\(\theta\)或者\(\phi\),然后把它写在策略的下标上来强调两者的联系。
\[a_t = \mu_{\theta}(s_t) \\\] \[a_t \sim \pi_{\theta}(\cdot | s_t).\]
确定性策略
例子1:确定性策略:这是一个基于 TensorFlow 在连续动作空间上确定性策略的简单例子:
1 | obs = tf.placeholder(shape=(None, obs_dim), dtype=tf.float32) |
其中,mlp 是把多个给定大小和激活函数的 密集层(dense layer)相互堆积在一起的函数。
例子2:确定性策略:下面是为 Pytorch 中的连续动作空间构建一个简单的确定性策略代码片段,使用torch.nn
包构建:
1 | pi_net = nn.Sequential( |
这里建立了一个多层感知机(MLP)网络,具有两个大小为64和tanh
激活函数的隐藏层。如果obs
是一个Numpy
数组,包含了一组观察,则pi_net
可以用来获得一组动作,如下所示:
1 | obs_tensor = torch.as_tensor(obs, dtype=torch.float32) |
随机性策略
深度强化学习中最常见的两种随机策略是绝对策略(Categorical Policies) 和对角高斯策略(Diagonal Gaussian Policies)。
绝对策略适用于离散动作空间,而高斯策略一般用在连续动作空间
使用和训练随机策略的时候有两个重要的计算:
- 从策略中采样动作
- 计算特定动作的对数似然(likelihoods), \(\log \pi_{\theta}(a|s)\)。 下面我们介绍一下这两种策略
绝对策略 绝对策略就像是一个离散动作空间的分类器(classifier)。对于分类器和确定策略来说,建立神经网络的方式一模一样:输入是观察,接着是一些卷积、全连接层之类的,至于具体是哪些取决于输入的类型,最后一个线性层给出每个动作的 log 数值(logits),后面跟一个 softmax 层把 log 数值转换为概率。 采样:考虑每个动作的概率,PyTorch和TensorFlow之类的框架有内置采样工。具体可查阅 PyTorch中的绝对分布,torch.multinomial, tf.distributions.Categorical,或 tf.multinomial 的文档。 对数似然:\(P_{\theta}(s)\)表示最后一层的概率。它是一个有很多值的向量,我们可以把动作当做向量的索引。所以向量的对数似然值 \(a\) 可以通过这样得到: \[\log \pi_{\theta}(a|s) = \log \left[P_{\theta}(s)\right]_a.\]
对角高斯策略 多元高斯分布(或者多元正态分布),可以用一个均值向量 \(\mu\) 和协方差矩阵 \(\Sigma\) 来描述。对角高斯分布就是协方差矩阵只有对角线上有值的特殊情况,所以我们可以用一个向量来表示它。 对角高斯策略总会有一个神经网络,表示观察到动作的映射 \(\mu_\theta(s)\)。其中有两种协方差矩阵的经典表示方式: 第一种:有一个单独的关于对数标准差的向量:\(\log \sigma\),它不是关于状态的函数,\(\log \sigma\) 而是单独的参数(我们这个项目里,VPG, TRPO 和 PPO 都是用这种方式实现的)。 第二种:有一个神经网络,从状态映射到对数标准差\(\log \sigma_{\theta}(s)\)。这种方式会选择性地与均值网络共享某些层的参数。 要注意这两种情况下我们都没有直接计算标准差而是对数标准差。这是因为对数标准差能够接受 \((-\infty, \infty)\) 的任何值,而标准差必须要求参数非负。要知道,限制条件越少,训练就越简单。而标准差可以通过取幂快速从对数标准差中计算得到,所以这种表示方法也不会丢失信息。 采样:给定平均动作\(\mu_{\theta}(s)\)和 标准差\(\sigma_{\theta}(s)\),以及一个服从球形高斯分布的噪声向量 \(z\),动作的样本可以这样计算: \[a = \mu_{\theta}(s) + \sigma_{\theta}(s) \odot z,\] 这里 \(\odot\) 表示两个向量按元素乘。标准框架都有内置噪声向量实现,例如 torch.normal 和 tf.random_normal 。也可以直接用 torch.distributions.Normal 或 tf.distributions.Normal 构建分布对象,并以均值和标准差的方式采样(后一种方式的好处是可以使用通过这些对象计算对数似然)。 对数似然 一个 \(k\) 维动作 \(a\) 基于均值为 \(\mu = \mu_{\theta}(s)\),标准差为 \(\sigma = \sigma_{\theta}(s)\) 的对角高斯的对数似然为: \[\log \pi_{\theta}(a|s) = -\frac{1}{2}\left(\sum_{i=1}^k \left(\frac{(a_i - \mu_i)^2}{\sigma_i^2} + 2 \log \sigma_i \right) + k \log 2\pi \right).\]
运动轨迹
运动轨迹 \(\tau\) 指的是世界中状态和动作的序列。
\[\tau = (s_0, a_0, s_1, a_1, ...).\]
第一个状态 \(s_0\),是从 初始状态分布 中随机采样的,有时候表示为 \(\rho_0\) :
\[s_0 \sim \rho_0(\cdot).\]
转态转换(从某一状态时间 \(t\) 对应的状态 \(s_t\) 到下一状态时间 \(t+1\) 对应的状态 \(s_{t+1}\)时世界发生了什么),是由环境的自然法则确定的,并且只依赖于最近的动作 \(a_t\)。它们可以是确定性的:
\[s_{t+1} = f(s_t, a_t)\]
也可以是随机的:
\[s_{t+1} \sim P(\cdot|s_t, a_t).\]
智能体的动作由策略确定。
Note:动作轨迹常常也被称作 回合(episodes) 或者 实验轨迹(rollouts)。
奖励和回报
强化学习中,奖励函数 \(R\) 非常重要。它由当前状态、已经执行的动作和下一步的状态共同决定。
\[r_t = R(s_t, a_t, s_{t+1})\]
有时候这个公式会被改成只依赖当前的状态 \(r_t = R(s_t)\),或者状态动作对 \(r_t = R(s_t,a_t)\)。
智能体的目标是最大化动作轨迹的累计奖励,这意味着很多事情。我们会把所有的情况表示为 \(R(\tau)\),至于具体表示什么,要么可以很清楚的从上下文看出来,要么并不重要。(因为相同的方程式适用于所有情况。)
\(T\) 步累计奖赏,指的是在一个固定窗口步数 \(T\) 内获得的累计奖励:
\[R(\tau) = \sum_{t=0}^T r_t.\]
另一种叫做 \(\gamma\) 折扣奖励,指的是智能体获得的全部奖励之和,但是奖励会因为获得的时间不同而衰减。这个公式包含衰减率 \(\gamma \in (0,1)\):
\[R(\tau) = \sum_{t=0}^{\infty} \gamma^t r_t.\]
这里为什么要加上一个衰减率呢?为什么不直接把所有的奖励加在一起?可以从两个角度来解释: 直观上讲,现在的奖励比外来的奖励要好,所以未来的奖励会衰减;数学角度上,无限多个奖励的和很可能 不收敛 ,有了衰减率和适当的约束条件,数值才会收敛。
Note:这两个公式看起来差距很大,事实上我们经常会混用。比如说,我们经常使用 \(\gamma\) 折扣奖励,但是用衰减率估算 值函数。
强化学习问题
无论选择哪种方式衡量收益(\(T\) 步累计奖赏或者 \(\gamma\) 折扣奖励),无论选择哪种策略,强化学习的目标都是选择一种策略从而最大化 预期收益。
讨论预期收益之前,我们先讨论下动作轨迹的概率分布。
我们假设环境转换和策略都是随机的。这种情况下, \(T\) 步 动作轨迹的概率是:
\[P(\tau|\pi) = \rho_0 (s_0) \prod_{t=0}^{T-1} P(s_{t+1} | s_t, a_t) \pi(a_t | s_t).\]
预期收益是 \(J(\pi)\)(无论采用何种衡量方式):
\[J(\pi) = \int_{\tau} P(\tau|\pi) R(\tau) = \mathop{E}\limits_{\tau\sim \pi}[{R(\tau)}].\]
强化学习中的核心优化问题可以表示为:
\[\pi^* = \arg \max_{\pi} J(\pi),\]
\(\pi^*\) 是 最优策略。
值函数
知道一个状态的 值 或者状态动作对(state-action pair)很有用。这里的值指的是,如果你从某一个状态或者状态动作对开始,一直按照某个策略运行下去最终获得的期望回报。几乎是所有的强化学习方法,都在用不同的形式使用着值函数。
这里介绍四种主要函数:
同策略值函数: \(V^{\pi}(s)\),从某一个状态 \(s\) 开始,之后每一步动作都按照策略 \(\pi\) 执行 \[V^{\pi}(s) = \mathop{E}\limits_{\tau \sim \pi}[{R(\tau)\left| s_0 = s\right.}]\]
同策略动作-值函数: \(Q^{\pi}(s,a)\),从某一个状态 \(s\) 开始,先随便执行一个动作 \(a\) (有可能不是按照策略走的),之后每一步都按照固定的策略执行 \(\pi\)
\[Q^{\pi}(s,a) = \mathop{E}\limits_{\tau \sim \pi}[{R(\tau)\left| s_0 = s, a_0 = a\right.}]\]
- 最优值函数: \(V^*(s)\),从某一个状态 \(s\) 开始,之后每一步都按照 最优策略 \(\pi\) 执行
\[V^*(s) = \max_{\pi} \mathop{E}\limits_{\tau \sim \pi}[{R(\tau)\left| s_0 = s\right.}]\]
- 最优动作-值函数 : \(Q^*(s,a)\) ,从某一个状态 \(s\) 开始,先随便执行一个动作 \(a\) (有可能不是按照策略走的),之后每一步都按照 最优策略 执行 \(\pi\)
\[Q^*(s,a) = \max_{\pi} \mathop{E}\limits_{\tau \sim \pi}[{R(\tau)\left| s_0 = s, a_0 = a\right.}]\]
Note:当我们讨论值函数的时候,如果我们没有提到时间依赖问题,那就意味着 折扣累计奖励。 累计奖励需要传入时间作为参数。
Note:值函数和动作-值函数两者之间经常出现的联系: \[V^{\pi}(s) = \mathop{E}\limits_{a\sim \pi}[{Q^{\pi}(s,a)}],\] 以及: \[V^*(s) = \max_a Q^* (s,a).\]
最优 \(Q\) 函数和最优动作
最优动作-值函数 \(Q^*(s,a)\) 和被最优策略选中的动作有重要的联系。从定义上讲, \(Q^*(s,a)\) 指的是从一个状态 \(s\) 开始,任意执行一个动作 \(a\) ,然后一直按照最优策略执行下去所获得的回报。
最优策略 \(s\) 会选择从状态 \(s\) 开始选择能够最大化期望回报的动作。所以如果我们有了 \(Q^*\) ,就可以通过下面的公式直接获得最优动作: \(a^*(s)\) :
\[a^*(s) = \arg \max_a Q^* (s,a).\]
注意:可能会有多个动作能够最大化 \(Q^*(s,a)\),这种情况下它们都是最优动作,最优策略可能会从中随机选择一个。但是总是存在一个最优策略,其每一步选择的动作是确定的。
贝尔曼方程
全部四个值函数都遵守自一致性的方程叫做 贝尔曼方程,贝尔曼方程的基本思想是:
- 起始点价值等于当前点预期值和下一个点价值之和。
同策略值函数的贝尔曼方程:
\[\begin{align*} V^{\pi}(s) &= \mathop{E}\limits_{a \sim \pi \atop s'\sim P}[{r(s,a) + \gamma V^{\pi}(s')}], \\ Q^{\pi}(s,a) &= \mathop{E}\limits_{s'\sim P}{r(s,a) + \gamma \mathop{E}\limits_{a'\sim \pi}[{Q^{\pi}(s',a')}}], \end{align*}\]
\(s' \sim P\) 是 \(s' \sim P(\cdot |s,a)\) 的简写, 表明下一个状态 \(s'\) 是按照转换规则从环境中抽样得到的; \(a \sim \pi\) 是 \(a \sim \pi(\cdot|s)\) 的简写; \(a' \sim \pi\) 是 \(a' \sim \pi(\cdot|s')\) 的简写.
最优值函数的贝尔曼方程是:
\[ \begin{align*} V^*(s) &= \max_a \mathop{E}\limits_{s'\sim P}[{r(s,a) + \gamma V^*(s')}], \\ Q^*(s,a) &= \mathop{E}\limits_{s'\sim P}[{r(s,a) + \gamma \max_{a'} Q^*(s',a')}]. \end{align*}\]
同策略值函数和最优值函数的贝尔曼方程最大的区别是是否在动作中去最大化(\(\max\))。这表明智能体在选择下一步动作时,为了做出最优动作,他必须选择能获得最大值的动作。
Note:贝尔曼算子(Bellman backup)会在强化学习中经常出现。对于一个状态或一个状态动作对,贝尔曼算子是贝尔曼方程的右边: 奖励+下一阶段的价值。
优势函数(Advantage Functions)
强化学习中,有些时候我们不需要描述一个动作的绝对好坏,而只需要知道它相对于平均水平的优势。也就是说,我们只想知道一个动作的相对 优势 。这就是优势函数的概念。
一个服从策略 \(\pi\) 的优势函数 \(A^\pi (s,a)\),描述的是它在状态 \(s\) 下采取动作 \(a\) 比随机选择一个动作好多少(假设之后一直服从策略 \(\pi\) )。数学角度上,优势函数的定义为:
\[A^{\pi}(s,a) = Q^{\pi}(s,a) - V^{\pi}(s).\]
Note:我们之后会继续谈论优势函数,它对于策略梯度方法非常重要。
数学模型(可选)
我们已经非正式地讨论了智能体的环境,但是如果你深入研究,可能会发现这样的标准数学形式:马尔科夫决策过程 (Markov Decision Processes, MDPs)。MDP是一个5元组 \(\langle S, A, R, P, \rho_0 \rangle\),其中
- \(S\) 是所有有效状态的集合,
- \(A\) 是所有有效动作的集合,
- \(R\) : \(S \times A \times S \to \mathbb{R}\) 是奖励函数,其中 \(r_t = R(s_t, a_t, s_{t+1})\),
- \(P\) : \(S \times A \to \mathcal{P}(S)\) 是转移概率函数,其中 \(P(s'|s,a)\) 是在状态 \(s\) 下 采取动作 \(a\) 转移到状态 s' 的概率。
- \(\rho_0\) 是初始状态的分布。
马尔科夫决策过程指的是服从 马尔科夫性 的系统: 状态转移只依赖与最近的状态和动作,而不依赖之前的历史数据。