当面对具有大量状态或连续状态空间的问题时,使用表格来表示价值函数变得不可行。试想一下,为屏幕上的每种像素配置,或复杂机器人的每种关节角度组合创建表格条目会是怎样?函数逼近提供了一种解决方案,它通过使用更紧凑的表示来估计价值函数。这个过程中的一个基本步骤是定义我们如何将状态 $s$ 本身表示为逼近器的输入。我们通常使用特征向量,记作 $x(s)$,而不是原始状态描述。特征向量 $x(s)$ 通常是一个实数值列向量,它捕获状态 $s$ 的重要属性:$$ x(s) = \begin{pmatrix} x_1(s) \ x_2(s) \ \vdots \ x_d(s) \end{pmatrix} $$这里,$d$ 是特征的数量,每个 $x_i(s)$ 是状态 $s$ 的第 $i$ 个特征值。主要思路是特征的数量 $d$ 通常远小于状态总数 $|S|$。这种压缩表示让我们的学习算法能够泛化。如果两个状态 $s$ 和 $s'$ 具有相似的特征向量,即 $x(s) \approx x(s')$,则函数逼近器可能会为它们产生相似的价值估计,即使某个状态从未被访问过。好的特征有何特点?目标是选择能够有效表达状态价值的特征。好的特征应具备:捕获重要信息: 它们应该代表状态中最相关于预测未来奖励的方面。与任务无关的信息通常可以舍弃。支持泛化: 需要相似动作或具有相似预期回报的状态应有相似的特征表示。形成紧凑表示: 特征向量的维度 ($d$) 应该显著低于状态空间的大小 ($|S|$),尤其对于大型或连续空间。设计这些特征的过程通常称为特征工程。它涵盖从简单技术到相当复杂的技术,有时需要丰富的领域知识。常用特征工程技术让我们看看构建特征向量的一些方法:1. 原始状态信息 (低维问题)对于某些问题,状态表示本身可能已是一个相对低维的数值向量。例如,在经典的“杆平衡”环境中,状态通常由四个数值表示:小车位置、小车速度、杆子角度和杆子角速度。$$ s = (\text{位置}, \text{速度}, \text{角度}, \text{角速度}) $$在这种情况下,我们可能直接将状态表示用作特征向量:$$ x(s) = \begin{pmatrix} \text{位置} \ \text{速度} \ \text{角度} \ \text{角速度} \end{pmatrix} $$即使在这里,对这些原始值进行归一化或缩放也通常有益。2. 手工设计特征 (领域知识)当原始状态很复杂(例如图像或棋盘游戏的配置)时,我们可以利用对问题领域的理解来手动定义相关特征。游戏: 在国际象棋中,特征可以包括物质平衡(棋子价值差异)、王的安全(受攻击棋子数量)、中心方格控制、兵结构评估等。机器人技术: 对于在房间中导航的机器人,特征可能包括到不同方向最近障碍物的距离、到目标的距离、当前电量,或是否正在携带物品。创建好的手工设计特征通常需要迭代和实验。3. 多项式基函数如果潜在价值函数预期为某些基本状态变量的非线性函数,我们可以创建多项式特征。对于具有基本特征 $f_1(s)$ 和 $f_2(s)$ 的状态 $s$,我们可以创建一个包含多项式项的特征向量:$$ x(s) = (1, f_1(s), f_2(s), f_1(s)^2, f_2(s)^2, f_1(s)f_2(s), \dots)^T $$常量特征 '1' 允许逼近器学习一个偏置项。这种方法可以捕获一些非线性关系,但可能很快导致特征数量过多。4. 瓦片编码 (粗粒度编码)瓦片编码是一种常用技术,尤其适用于连续状态空间。它通过叠加多个网格(瓦片组)来离散化空间,每个网格相对于其他网格都有偏移。一个状态在每个瓦片组中激活一个瓦片。特征向量 $x(s)$ 通常是一个大型二进制向量,其中每个分量对应所有瓦片组中的一个瓦片。如果对应瓦片对状态 $s$ 处于活动状态,则分量为 1,否则为 0。digraph G { layout=neato; node [shape=box, style=filled, fillcolor="#dee2e6", margin=0.05, width=0.5, height=0.5, fixedsize=true, fontsize=10, pos="0,0!"]; edge [style=invis]; subgraph cluster_0 { label = "瓦片组 1 (网格)"; bgcolor="#e9ecef"; node [fillcolor="#a5d8ff"]; a1 [pos="-1,1!"]; a2 [pos="0,1!"]; a3 [pos="1,1!"]; b1 [pos="-1,0!"]; b2 [pos="0,0!"]; b3 [pos="1,0!"]; c1 [pos="-1,-1!"]; c2 [pos="0,-1!"]; c3 [pos="1,-1!"]; a1 -- a2 -- a3; b1 -- b2 -- b3; c1 -- c2 -- c3; a1 -- b1 -- c1; a2 -- b2 -- c2; a3 -- b3 -- c3; } subgraph cluster_1 { label = "瓦片组 2 (偏移)"; bgcolor="#e9ecef"; node [fillcolor="#96f2d7"]; x1 [pos="-0.5,1.5!"]; x2 [pos="0.5,1.5!"]; y1 [pos="-1.5,0.5!"]; y2 [pos="-0.5,0.5!"]; y3 [pos="0.5,0.5!"]; y4 [pos="1.5,0.5!"]; z1 [pos="-0.5,-0.5!"]; z2 [pos="0.5,-0.5!"]; w1 [pos="-1.5,-1.5!"]; w2 [pos="-0.5,-1.5!"]; w3 [pos="0.5,-1.5!"]; w4 [pos="1.5,-1.5!"]; x1--x2; y1--y2--y3--y4; z1--z2; w1--w2--w3--w4; x1--y2; x2--y3; y1--w1; y2--z1; y2--w2; y3--z2; y3--w3; y4--w4; z1--w2; z2--w3; } # 状态点表示 node [shape=circle, fillcolor="#fa5252", width=0.15, height=0.15, label=""]; state_point [pos="0.2, 0.3!"]; # 注解 node [shape=plaintext, fillcolor=none, fontcolor="#495057", fontsize=9]; anno1 [pos="0.0, -2.2!", label="状态 s 激活瓦片组 1 中的瓦片 b2"]; anno2 [pos="0.0, -2.6!", label="状态 s 激活瓦片组 2 中的瓦片 y3"]; anno3 [pos="0.0, -3.0!", label="特征向量中 b2 和 y3 对应位为 1,其余为 0"]; }二维瓦片编码示意图。一个状态(红点)落入每个偏移网格(瓦片组 1 和 瓦片组 2)中的一个瓦片。激活的瓦片(例如 b2 和 y3)对应二进制特征向量中的 '1' 条目。瓦片编码的主要优点是它提供良好泛化能力。彼此接近的状态将共享一些激活的瓦片,从而产生相似的特征向量和相似的价值估计。泛化程度由瓦片宽度和瓦片组的数量/偏移量控制。5. 径向基函数 (RBF)对于连续空间的另一种方法涉及使用径向基函数。您在状态空间中定义一组原型点(中心)$c_i$。然后根据当前状态 $s$ 与这些中心的距离计算特征,通常使用高斯核等函数:$$ x_i(s) = \exp\left( - \frac{| s - c_i |^2}{2 \sigma_i^2} \right) $$每个特征 $x_i(s)$ 衡量状态 $s$ 与中心 $c_i$ 的相似度。靠近特定中心的状态,其对应特征值会很高。与瓦片编码类似,RBF 提供平滑泛化。6. 学习到的特征 (深度学习)相对于手动设计特征,我们可以使用强大的函数逼近器,如深度神经网络,直接从原始、高维输入(例如屏幕像素或传感器读数)中学习相关特征。这是深度强化学习的核心思路,我们将在第 7 章(深度 Q 网络)中介绍。网络的隐藏层将原始输入转换为逐渐更抽象和有用的表示(特征),然后由输出层用于估计价值函数。动作价值的特征到目前为止,我们主要讨论了状态价值函数 $V(s)$ 的特征 $x(s)$。当逼近动作价值函数 $Q(s, a)$ 时,特征通常需要依赖于状态和动作。我们将此特征向量记作 $x(s, a)$。一个常见的方法是首先计算状态特征 $x(s)$,然后根据动作 $a$ 组合它们。例如,如果存在 $|A|$ 个离散动作,可以通过将状态特征向量 $x(s)$ 放入一个更大向量中对应于动作 $a$ 的特定块中来构建 $x(s, a)$,其他地方填充零。特征在逼近中的作用一旦我们有了特征向量 $x(s)$(或 $x(s, a)$),它就作为我们选择的函数逼近器的输入。例如,在线性函数逼近中(我们将在下文讨论),价值函数被估计为特征的加权和:$$ \hat{v}(s, \mathbf{w}) \approx \mathbf{w}^T x(s) = \sum_{i=1}^d w_i x_i(s) $$或对于动作价值:$$ \hat{q}(s, a, \mathbf{w}) \approx \mathbf{w}^T x(s, a) = \sum_{i=1}^d w_i x_i(s, a) $$这里,$\mathbf{w} = (w_1, w_2, \dots, w_d)^T$ 是强化学习算法学习的权重(参数)向量。学习过程的目标是找到权重 $\mathbf{w}$,使得逼近值 $\hat{v}$ 或 $\hat{q}$ 接近真实的价值函数 $v_\pi$ 或 $q_\pi$。选择或设计合适的特征对于强化学习中函数逼近方法的成功非常重要。好的特征使学习任务更简单,并能在状态空间中有效泛化。在以下部分,我们将研究如何使用这些特征表示来学习权重 $\mathbf{w}$。