本章的题目为"on-policy prediction with approximation",之前几章的内容也涉及到了on-policy prediction,这里的不同就在于“估计”。因为前面讲到的内容是根据策略采样轨迹,再基于轨迹得到的奖励,计算价值函数。但这里不再是采用这样的思路,而是估计价值函数,并且估计出来的价值函数不再是以表格的形式存在,而是得到一个参数化的函数形式。形式化表示为 v ^ ( s , w ) ≈ v π ( s ) \hat{v}(s, \mathbf{w}) \approx v_{\pi}(s) v^(s,w)≈vπ(s),其中 v ^ ( s , w ) \hat{v}(s, \mathbf{w}) v^(s,w)表示估计的价值函数, w \mathbf{w} w表示价值函数中的参数。我们要做的就是估计这个参数,使得估计的价值函数接近于目标的价值函数。当然 v ^ \hat{v} v^可以是多种形式,比如:线性函数、神经网络、决策树、最近邻、傅里叶/小波变换等等。通常,参数 w \mathbf{w} w的维度是远小于状态空间大小的。
为什么我们需要估计价值函数呢?
- 状态空间、动作空间离散,但很大的时候,用表格存储价值函数不现实,且查表效率低。
- 状态空间连续时,无法将每个状态的价值都保存在表格中。
基于以上两种情况,我们可以利用函数近似的方式来估计价值。下面给出图示,左边第一张表示一个状态价值估计器,输入是某一个状态,输出是该状态的估计价值,
w
\mathbf{w}
w是函数估计器的参数。第二张图表示动作价值估计器,输入是一个状态-动作对,输出是其对应的动作价值。第三张图是对于一个状态可能发生的所有动作的价值估计,输入是一个状态,输出是该状态所有可能的动作对应的估计价值。
文章目录
1. 价值函数估计
本书中讲到的预测方法都可以描述为估计值函数的更新,也就是对于一个状态,将它的价值向目标价值趋近。形式化表示为: s ↦ u s \mapsto u s↦u。其中 s s s是将要更新价值的状态, u u u是更新的目标。在前面几章介绍的不同方法中,更新的目标也不同,如下:
- 蒙特卡洛(MC): S t ↦ G t S_t \mapsto G_t St↦Gt
- TD(0): S t ↦ R t + 1 + γ v ^ ( S t + 1 , w t ) S_t \mapsto R_{t+1} + \gamma \hat{v}(S_{t+1}, \mathbf{w_t}) St↦Rt+1+γv^(St+1,wt)
- n-step TD: S t ↦ G t : t + n S_t \mapsto G_{t:t+n} St↦Gt:t+n
- 动态规划(DP): s ↦ E π [ R t + 1 + γ v ^ ( S t + 1 , w t ) ∣ S t = s ] s \mapsto \mathbb{E}_{\pi}[R_{t+1} + \gamma \hat{v}(S_{t+1}, \mathbf{w}_t) | S_t = s] s↦Eπ[Rt+1+γv^(St+1,wt)∣St=s]
所以,如果我们拥有充足的训练数据,每条数据包含状态和该状态对应的目标价值,即(s, u)。那么直观的想法,我们就可以使用现有的很多监督学习方法来训练一个价值函数估计器。
当然,我们还需要定义合适的损失函数,通过减小损失,得到更好的参数估计。
2. 预测目标( V E ‾ \overline{VE} VE)
因为要预测的价值是一个实数值,所以很自然的想到可以用均方误差作为损失函数。即:
V
E
‾
(
w
)
≐
∑
s
∈
S
μ
(
s
)
[
v
π
(
s
)
−
v
^
(
s
,
w
)
]
2
\overline{VE} (\mathbf{w}) \doteq \sum_{s \in \mathcal{S}} \mu(s)[v_{\pi}(s) - \hat{v}(s, \mathbf{w})]^2
VE(w)≐s∈S∑μ(s)[vπ(s)−v^(s,w)]2
其中 μ ( s ) \mu(s) μ(s)表示我们对于状态 s s s的价值估计误差有多在意。很多时候 μ ( s ) \mu(s) μ(s)是与访问状态 s s s的次数成正比的。
在eposodic 任务中 μ ( s ) \mu(s) μ(s)的计算方式
对于所有的状态s,
μ ( s ) = η ( s ) ∑ s ′ η ( s ′ ) \mu(s) = \frac{\eta(s)}{\sum_{s'}\eta(s')} μ(s)=∑s′η(s′)η(s)
其中, η ( s ) \eta(s) η(s)表示为:
η ( s ) = h ( s ) + ∑ s ˉ η ( s ˉ ) ∑ a π ( a ∣ s ˉ ) p ( s ∣ s ˉ , a ) \eta(s) = h(s) + \sum_{\bar{s}}\eta(\bar{s})\sum_a \pi(a | \bar{s}) p(s | \bar{s}, a) η(s)=h(s)+sˉ∑η(sˉ)a∑π(a∣sˉ)p(s∣sˉ,a)可以看出, η ( s ) \eta(s) η(s)的计算包括两个部分, h ( s ) h(s) h(s)表示状态 s s s作为起始状态的概率,后面的部分表示的是状态 s s s作为中间状态出现的概率。所以 η ( s ) \eta(s) η(s)表示的是状态 s s s出现的概率。
3. 随机梯度和半梯度方法
随机梯度下降(SGD)是机器学习中常用的优化算法,这里,我们也是用这种思想来优化值函数估计,更新参数。
我们要更新的参数 w \mathbf{w} w是一个固定维度的列向量,表示为: w ≐ ( w 1 , w 2 , ⋯ , w d ) T \mathbf{w} \doteq (w_1, w_2, \cdots, w_d)^\mathrm{T} w≐(w1,w2,⋯,wd)T。并且, v ^ ( s , w ) \hat{v}(s, \mathbf{w}) v^(s,w)对 w \mathbf{w} w是可微的。
利用上一节中的均方误差作为损失函数,我们试图最小化观测到的样本损失。SGD是在每个样本损失计算之后更新参数,参数的更新方向则是梯度下降方向。
w t + 1 ≐ w t − 1 2 α ▽ [ v π ( S t ) − v ^ ( S t , w ) ] 2 = w t + α [ v π ( S t ) − v ^ ( S t , w t ) ] ▽ v ^ ( S t , w t ) \begin{aligned} w_{t+1} &\doteq w_t - \frac{1}{2} \alpha \triangledown [v_{\pi}(S_t) - \hat{v}(S_t, \mathbf{w})]^2 \\ &= w_t + \alpha [v_{\pi}(S_t) - \hat{v}(S_t, \mathbf{w}_t)] \triangledown \hat{v}(S_t, \mathbf{w}_t) \end{aligned} wt+1≐wt−21α▽[vπ(St)−v^(St,w)]2=wt+α[vπ(St)−v^(St,wt)]▽v^(St,wt)
其中, α \alpha α表示更新步长,通常是一个很小的值,并且随着时间的变化, α \alpha α会逐渐减小。这是因为如果步长很大,那么一步更新很有可能就错过了最优解,步长随时间减小是因为在训练过程中, w \mathbf{w} w的值越来越接近最优值,所以越到后面,步长就越小一点,有利于找到最优解。
目标值
v
π
(
S
t
)
v_{\pi}(S_t)
vπ(St)也可能是一个估计出来的值
U
t
U_t
Ut,这种情况下,参数的更新为:
w
t
+
1
≐
w
t
+
α
[
U
t
−
v
^
(
S
t
,
w
t
)
]
▽
v
^
(
S
t
,
w
t
)
]
w_{t+1} \doteq w_t + \alpha [U_t - \hat{v}(S_t, \mathbf{w}_t)] \triangledown \hat{v}(S_t, \mathbf{w}_t)]
wt+1≐wt+α[Ut−v^(St,wt)]▽v^(St,wt)]
如果 U t U_t Ut是 v π ( S t ) v_{\pi}(S_t) vπ(St)的无偏估计,即 E [ U t ∣ S t = s ] = v π ( S t ) \mathbb{E}[U_t|S_t = s] = v_{\pi}(S_t) E[Ut∣St=s]=vπ(St),并且步长参数随时间减小,则 w t \mathbf{w_t} wt一定可以收敛到局部最优。
在蒙特卡洛方法中,我们知道
U
t
≐
G
t
U_t \doteq G_t
Ut≐Gt是一个无偏估计,所以,蒙特卡洛预测用梯度下降来求解就能够保证得到局部最优解,伪代码如下:
上面的伪代码中,
G
t
G_t
Gt是根据轨迹序列的奖励计算出来的
S
t
S_t
St的目标价值,
v
^
(
S
t
,
w
)
\hat{v}(S_t, \mathbf{w})
v^(St,w)根据给定的可微价值估计函数计算出来的状态
S
t
S_t
St的估计价值。
▽
v
^
(
S
t
,
w
)
\triangledown \hat{v}(S_t, \mathbf{w})
▽v^(St,w)是价值估计值对于
w
\mathbf{w}
w的微分结果(即求得的梯度)。所以,很容易就根据更新公式,得到
w
\mathbf{w}
w的更新值。
但是一些包含bootstrapping的方法无法对 v π ( S t ) v_{\pi}(S_t) vπ(St)进行无偏估计。比如:TD(0)方法中, U t ≐ R t + 1 + γ v ^ ( s ′ , w t ) U_t \doteq R_{t+1} + \gamma \hat{v}(s', \mathbf{w}_t) Ut≐Rt+1+γv^(s′,wt);DP方法中, U t ≐ ∑ a , s ′ , r π ( a ∣ S t ) p ( s ′ , r ∣ S t , a ) [ r + γ v ^ ( s ′ , w t ) ] U_t \doteq \sum_{a, s', r} \pi(a|S_t) p(s',r|S_t, a)[r+\gamma \hat{v}(s', \mathbf{w}_t)] Ut≐∑a,s′,rπ(a∣St)p(s′,r∣St,a)[r+γv^(s′,wt)]。可见,以上的目标价值 U t U_t Ut其实依赖于估计值 v ^ ( s ′ , w t ) \hat{v}(s', \mathbf{w}_t) v^(s′,wt),因为估计值不是最优,所以 U t U_t Ut也就是一个有偏的估计。这种情况下,上面的参数更新公式就不是真正的梯度下降,因为没有考虑到 w \mathbf{w} w对于 U t U_t Ut的影响。这种叫做半梯度方法。
尽管半梯度方法不像梯度方法那样能够鲁棒性收敛,但在下一节要讨论的线性估计器来说,是可以保证收敛的。
下面给出TD(0)的半梯度参数更新伪代码:
4. 线性模型
价值函数估计的一个重要的情况是,估计函数 v ^ ( s , w ) \hat{v}(s, \mathbf{w}) v^(s,w)是一个线性函数。其中 s s s表示为 d d d维列向量 x ( s ) ≐ ( x 1 ( s ) , x 2 ( s ) , ⋯ , x d ( s ) ) T \mathbf{x}(s) \doteq (x_1(s), x_2(s), \cdots, x_d(s))^\mathrm{T} x(s)≐(x1(s),x2(s),⋯,xd(s))T, w \mathbf{w} w当然也是一个 d d d维列向量。所以,线性估计的模型表示为:
v ^ ( s , w ) ≐ w T x ( s ) ≐ ∑ i = 1 d w i x i ( s ) \hat{v}(s, \mathbf{w}) \doteq \mathbf{w}^\mathrm{T} \mathbf{x}(s) \doteq \sum_{i=1}^d w_i x_i(s) v^(s,w)≐wTx(s)≐i=1∑dwixi(s)
x ( s ) \mathbf{x}(s) x(s)是状态 s s s的特征表示向量。对于线性方法,特征就是基函数,因为它们构成了一组近似函数的线性基。构造表示状态的 d d d维特征向量,与选择一组基函数是一样的。
线性函数使用SGD来更新参数时非常方便的,价值估计 v ^ ( s , w ) \hat{v}(s, \mathbf{w}) v^(s,w)对于参数向量 w \mathbf{w} w的梯度为:
▽ v ^ ( s , w ) = x ( s ) \triangledown \hat{v}(s, \mathbf{w}) = \mathbf{x}(s) ▽v^(s,w)=x(s)
所以,参数的更新为:
w t + 1 ≐ w t + α [ U t − v ^ ( S t , w t ) ] x ( S t ) \mathbf{w}_{t+1} \doteq w_t + \alpha [U_t - \hat{v}(S_t, \mathbf{w}_t)]\mathbf{x}(S_t) wt+1≐wt+α[Ut−v^(St,wt)]x(St)
我们知道,线性函数仅有一个全局最优解,所以 U t U_t Ut如果是无偏估计,就可以收敛到局部最优,也就是全局最优。也就是,目标价值如果是通过MC方法计算出来的,该线性模型就可以收敛到全局最优。
那么,对于半梯度方法TD(0)而言,使用线性模型估计价值函数的话,也是可以收敛的,但不能保证收敛到全局最优,而是一个全局最优点附近的解。它的参数更新表示为:
w t + 1 ≐ w t + α ( R t + 1 + γ w t T x t + 1 − w t T x t ) = w t + α ( R t + 1 x t − x t ( x t − γ x t + 1 ) T w t ) \begin{aligned} \mathbf{w}_{t+1} &\doteq \mathbf{w}_t + \alpha (R_{t+1} + \gamma \mathbf{w}_t^\mathrm{T} \mathbf{x}_{t+1} - \mathbf{w}_t^\mathrm{T} \mathbf{x}_{t}) \\ &=\mathbf{w}_t + \alpha (R_{t+1} \mathbf{x}_t -\mathbf{x}_t(\mathbf{x}_t - \gamma \mathbf{x}_{t+1})^\mathrm{T} \mathbf{w}_t) \end{aligned} wt+1≐wt+α(Rt+1+γwtTxt+1−wtTxt)=wt+α(Rt+1xt−xt(xt−γxt+1)Twt)
对于一个给定的
w
t
\mathbf{w}_t
wt,它的下一个时刻的参数期望表示为:
E
[
w
t
+
1
∣
w
t
]
=
w
t
+
α
(
b
−
A
w
t
)
\mathbb{E}[\mathbf{w}_{t+1}|\mathbf{w}_t] = \mathbf{w}_t + \alpha(\mathbf{b} - \mathbf{A}\mathbf{w}_t)
E[wt+1∣wt]=wt+α(b−Awt)
其中, b ≐ E [ R t + 1 x t ] ∈ R d \mathbf{b} \doteq \mathbb{E}[R_{t+1}\mathbf{x}_t] \in \mathbb{R}^d b≐E[Rt+1xt]∈Rd, A ≐ E [ x t ( x t − γ x t + 1 ) T ] ∈ R d × R d \mathbf{A} \doteq \mathbb{E}[\mathbf{x}_t(\mathbf{x}_t - \gamma \mathbf{x}_{t+1})^\mathrm{T}] \in \mathbb{R}^d \times \mathbb{R}^d A≐E[xt(xt−γxt+1)T]∈Rd×Rd。因为上面的更新式是针对一个样本的,但分析收敛性的时候,要考虑所有训练样本,所以这里使用了期望的形式。
那么,如果模型收敛,前一次参数和后一次参数应该是一样的,所以:
E
[
w
t
+
1
∣
w
t
]
=
w
t
\mathbb{E}[\mathbf{w}_{t+1}|\mathbf{w}_t] = \mathbf{w}_t
E[wt+1∣wt]=wt,也即:
b
−
A
w
T
D
=
0
\mathbf{b} - \mathbf{A}\mathbf{w}_{TD} = 0
b−AwTD=0,所以我们得到TD(0)使用线性模型收敛时,参数的计算方式为:
w
T
D
≐
A
−
1
b
\mathbf{w}_{TD} \doteq \mathbf{A}^{-1} \mathbf{b}
wTD≐A−1b
这个值称为TD不动点,也就是线性半梯度TD(0)能够收敛到这一点。书上有关于TD(0)收敛的证明。
也证明表示在TD不动点,其 V E ‾ \overline{VE} VE误差存在一个上界:
V E ‾ ( w T D ) ≤ 1 1 − γ min w V E ‾ ( w ) \overline{VE}(\mathbf{w}_{TD}) \leq \frac{1}{1-\gamma} \min_{\mathbf{w}} \overline{VE}(\mathbf{w}) VE(wTD)≤1−γ1wminVE(w)
其中, min w V E ‾ ( w ) \min_{\mathbf{w}} \overline{VE}(\mathbf{w}) minwVE(w)是通过蒙特卡洛方法作为目标价值计算出来的。可以看出,TD的 V E ‾ \overline{VE} VE误差上限是最小误差的 1 1 − γ \frac{1}{1-\gamma} 1−γ1倍。由于 γ \gamma γ通常是一个接近于1的值,所以这个误差可能是很大的。但在第六章和第七章中也讲到,TD方法比MC方法有更小的方差,并且学习的更快。所以,也各有各的优劣,具体使用哪种方法计算的价值作为目标价值,还需要考虑问题和近似的性质,以及学习的持续时间。
对于n-步TD方法,也可以利用类似的方式更新参数,下面给出伪代码:
5. 线性模型的特征构造
对于一个状态,选择合适的特征来表示它,其实相当于将一些先验领域知识加入到强化学习系统中。比如,我们要评估移动机器人的状态,那么我们可能会选择其位置、剩余电池电量、声纳传感器数据等作为其状态。
但是这样的特征表示形式存在一个局限,即仅考虑每个单独的特征,而没有考虑特征之间的交互关系。所以如果想要考虑高阶的特征,我们需要将这些单个的特征做一些组合。下面将讲解四种特征构造的方法。
5.1 多项式特征
很多问题中的状态都可以用数值来表示,例如:位置、速度等。在这类问题中,用于强化学习的函数逼近与我们熟悉的插值和回归任务有很多相似之处。多项式特征常用在插值和回归任务中。所以,我们这里也可以使用多项式特征来表示状态。
举个例子,如果一个状态 s s s可以用2维向量表示出来,即 x ( s ) = ( s 1 , s 2 ) T \mathbf{x}(s) = (s_1, s_2)^\mathrm{T} x(s)=(s1,s2)T,但是这样就没有考虑到这两维特征的交互。如果构造多项式特征,我们常常加入常数项和耦合项,将特征表示为: x ( s ) = ( 1 , s 1 , s 2 , s 1 s 2 ) T \mathbf{x}(s) = (1, s_1, s_2, s_1s_2)^\mathrm{T} x(s)=(1,s1,s2,s1s2)T。或者可以选择更高阶特征向量,如: x ( s ) = ( 1 , s 1 , s 2 , s 1 s 2 , s 1 2 , s 2 2 , s 1 s 2 2 , s 1 2 s 2 , s 1 2 s 2 2 ) T \mathbf{x}(s) = (1, s_1, s_2, s_1s_2, s_1^2, s_2^2, s_1s_2^2, s_1^2s_2, s_1^2s_2^2)^\mathrm{T} x(s)=(1,s1,s2,s1s2,s12,s22,s1s22,s12s2,s12s22)T。
将以上的例子推广,就可以得到多项式特诊构造的一般形式。设状态
s
s
s的特征包含
k
k
k个,构造它的
n
n
n阶多项式特征时,构造后的第
i
i
i维特征可以表示为:
x
i
(
s
)
=
∏
j
=
1
k
s
j
c
i
,
j
x_i(s) = \prod_{j=1}^{k} s_j^{c_{i, j}}
xi(s)=j=1∏ksjci,j
其中, c i , j ∈ { 0 , 1 , ⋯ , n } c_{i,j} \in \{0, 1, \cdots, n\} ci,j∈{0,1,⋯,n}。 x i ( s ) x_i(s) xi(s)只是构造出来的特征向量的一个维度,理论上有 ( n + 1 ) k (n+1)^k (n+1)k维。
5.2 傅里叶基
傅里叶级数能将任何周期函数分解为无穷个不同频率正弦函数和余弦函数的叠加。那么,如果我们要估计的价值函数是一个周期函数,就可以直接利用这种方式构造特征。
但我们要估计的值函数并不是一个周期函数。所以,如果想要使用傅里叶基,就需要将价值函转换为一个周期函数。做法也很简单,就是通过复制的方式,当前价值函数的区间长度就是周期。
这里的具体思想,我其实没有想得很懂。等我完全懂了,再分享出来,见谅。
5.3 粗糙编码
假设一个任务的状态集是二维且连续的。那么,每一个状态其实就是二维空间中的一个点。如果我们把状态空间用一些相互重叠的区域覆盖,如下图:
图中的各个圆表示一种特征,如果一个状态点落在了某个院内,则相应的特征值为1,否则为0。假设我们有10个圆,每个圆都有一个编号,对于一个状态来说,它可以表示为一个10维的特征向量,向量中的每个值为1或者0,1表示这个状态在对应的特征的圆内。这种方式成为粗糙编码。
在我们进行随机梯度下降更新参数的时候,对于一个状态点
s
s
s,所有与它有交集的参数都会受到影响。所以粗糙编码的泛化性能还受到我们设定的圆的大小和形状的影响。如下图所示,第一张图中的圆较小,那么更新一个点时,泛化会在较小的距离上进行。第二张图表示每个圆很大,那更新将会影响到一个大的范围。第三张图中的圆呈现椭圆的形状,更新的范围也受到影响。
5.4 Tile Coding
Tile Coding是粗糙编码的一种。对于一个状态来说,它会被多个tile覆盖。考虑二维连续的状态空间,tile coding的叠加方式如下图:
5.5 径向基函数
径向基函数是对于粗糙编码的一个扩展。在粗糙编码中,每个特征是由该状态是否落在圆内决定,特征值是0或1。但径向基函数是将特征转换为0到1之间的实数值。一个典型的径向基特征
i
i
i具有一个高斯响应
ϕ
s
(
i
)
\phi_s(i)
ϕs(i)。
ϕ
s
(
i
)
=
e
x
p
(
−
∣
∣
s
−
c
i
∣
∣
2
2
σ
i
2
)
\phi_s(i) = exp(-\frac{||s-c_i||^2}{2\sigma_i^2})
ϕs(i)=exp(−2σi2∣∣s−ci∣∣2)
其中, c i c_i ci表示状态中心, σ i \sigma_i σi表示特征宽度。
6. 非线性函数估计:人工神经网络ANN
前面说到,我们有了目标价值,还有价值估计函数,希望让估计的价值接近目标价值。这就相当于一个监督学习的问题,所以,ANN也是可以直接利用到这个问题上的。输入是状态的特征表示,输出是这个状态的估计价值。参数 w \mathbf{w} w是通过ANN训练得到的。
7. 最小二乘TD算法(LSTD)
在前面的内容中,提到了线性估计函数的TD(0)算法,在收敛的时候,能得到:
E
[
w
t
+
1
∣
w
t
]
=
w
t
+
α
(
b
−
A
w
t
)
\mathbb{E}[\mathbf{w}_{t+1}|\mathbf{w}_t] = \mathbf{w}_t + \alpha(\mathbf{b} - \mathbf{A}\mathbf{w}_t)
E[wt+1∣wt]=wt+α(b−Awt)
这样就会收敛到TD不动点:
w
T
D
≐
A
−
1
b
\mathbf{w}_{TD} \doteq \mathbf{A}^{-1} \mathbf{b}
wTD≐A−1b,其中:
b
≐
E
[
R
t
+
1
x
]
∈
R
b \doteq \mathbb{E}[R_{t+1}\mathbf{x}] \in \mathbb{R}
b≐E[Rt+1x]∈R
A ≐ E [ x t ( x t − γ x t + 1 ) T ] ∈ R d × R d \mathbf{A} \doteq \mathbb{E}[\mathbf{x}_t(\mathbf{x}_t - \gamma \mathbf{x}_{t+1})^{\mathrm{T}}] \in \mathbb{R}^d \times \mathbb{R}^d A≐E[xt(xt−γxt+1)T]∈Rd×Rd
这里是迭代计算出TD不动点的,我们其实也可以直接计算TD不动点,这种方式就叫做LSTD,计算方式如下:
b
^
t
≐
∑
k
=
0
t
−
1
R
k
+
1
x
k
\hat{b}_t \doteq \sum_{k=0}^{t-1} R_{k+1} \mathbf{x}_{k}
b^t≐k=0∑t−1Rk+1xk
A ^ t ≐ ∑ k = 0 t − 1 x k ( x k − γ x k + 1 ) T + ε I \hat{A}_t \doteq \sum_{k=0}^{t-1} \mathbf{x}_{k}(\mathbf{x}_{k} - \gamma \mathbf{x}_{k+1})^{\mathrm{T}} + \varepsilon \mathbf{I} A^t≐k=0∑t−1xk(xk−γxk+1)T+εI
那么,利用LSTD来估计价值的伪代码为: