构建估算动作价值函数 $Q(s, a; \theta)$ 的神经网络是深度Q网络 (DQN) 的主要考量之一。DQN 运用经验回放和目标网络等核心机制。这个网络的设计很大程度上取决于环境提供的状态表示形式。网络输入:状态表示第一步是确定输入层的结构。智能体“看到”什么?向量形式状态: 如果状态表示为数值特征向量(例如:位置、速度、传感器读数),标准多层感知机(MLP)(也称全连接网络)通常足够使用。输入层的神经元数量将与状态向量中的特征数量相等。图像形式状态: 对于状态由图像(例如屏幕像素)表示的环境,**卷积神经网络(CNN)**是标准选择。CNN擅长识别网格状数据中的空间层次和模式。输入层通常会接受图像的维度(高度、宽度、颜色通道)。通常会将多个连续帧堆叠作为输入,为网络提供时间信息,例如速度或移动方向。网络结构:隐藏层在输入层之后,一个或多个隐藏层会处理信息。MLP: MLP中的隐藏层通常是全连接层。一层中的每个神经元都从前一层的所有神经元接收输入。层的数量以及每层神经元的数量是您需要设定的超参数。先从简单的设置开始(例如,一或两个隐藏层,中等数量的神经元),如果需要可以增加复杂度。修正线性单元 (ReLU) 激活函数($f(x) = max(0, x)$)是DQN中隐藏层的普遍且有效的选择。CNN: 对于图像输入,最初的隐藏层通常是卷积层,后接池化层。卷积层应用滤波器以识别局部模式(边缘、纹理),而池化层则降低空间维度,使表示更易处理,并且对细微平移具有不变性。在经过几个卷积和池化层之后,得到的特征图通常被展平为一个向量,并输入到一个或多个全连接层,类似于MLP。同样,ReLU是这些层的标准激活函数。那个让DQN在Atari游戏中取得成功的著名论文,就采用了由多个卷积层和全连接层构成的CNN架构。网络输出:动作价值网络的最后一层非常重要:它必须输出估算的Q值。结构: 输出层通常是全连接层,环境中智能体可以采取的每个可能的离散动作对应一个神经元。激活: 由于Q值表示预期累积奖励,并且不限于特定范围(如概率),因此输出层通常使用线性激活函数(即无激活函数或恒等函数)。解读: 第$i$个输出神经元产生的值代表网络对在输入状态$s$下执行第$i$个动作的Q值的估算。也就是说,输出向量同时估算所有可能的动作$a$对应的$Q(s, a; \theta)$。示例架构以下是展示常见结构的图示:1. 适用于向量形式状态的MLP:digraph G { rankdir=LR; node [shape=box, style=filled, fillcolor="#a5d8ff"]; edge [color="#495057"]; subgraph cluster_0 { style=filled; fillcolor="#e9ecef"; label = "输入层"; node [shape=circle, fillcolor="#74c0fc"]; i1 [label="s₁"]; i2 [label="s₂"]; i3 [label="..."]; i4 [label="sₙ"]; } subgraph cluster_1 { style=filled; fillcolor="#e9ecef"; label = "隐藏层 1 (全连接 + ReLU)"; node [shape=circle, fillcolor="#748ffc"]; h1_1; h1_2; h1_3 [label="..."]; h1_4; } subgraph cluster_2 { style=filled; fillcolor="#e9ecef"; label = "隐藏层 2 (全连接 + ReLU)"; node [shape=circle, fillcolor="#91a7ff"]; h2_1; h2_2; h2_3 [label="..."]; h2_4; } subgraph cluster_3 { style=filled; fillcolor="#e9ecef"; label = "输出层 (全连接 + 线性)"; node [shape=doublecircle, fillcolor="#ffc078"]; o1 [label="Q(s, a₁)"]; o2 [label="Q(s, a₂)"]; o3 [label="..."]; o4 [label="Q(s, aₘ)"]; } {i1, i2, i3, i4} -> {h1_1, h1_2, h1_3, h1_4} [style=dotted]; {h1_1, h1_2, h1_3, h1_4} -> {h2_1, h2_2, h2_3, h2_4} [style=dotted]; {h2_1, h2_2, h2_3, h2_4} -> {o1, o2, o3, o4} [style=dotted]; label="DQN 的MLP架构(向量输入)"; fontsize=12; labelloc=b; }MLP接收状态向量 $s = (s_1, ..., s_n)$,并通过全连接(FC)隐藏层(通常带有ReLU激活)为每个动作 $a_1, ..., a_m$ 生成Q值估算。2. 适用于图像形式状态的CNN(简化版):digraph G { rankdir=LR; node [shape=box, style=filled, fillcolor="#a5d8ff"]; edge [color="#495057"]; Input [label="输入图像", shape=rectangle, fillcolor="#74c0fc"]; subgraph cluster_cnn { label = "卷积层"; style=filled; fillcolor="#e9ecef"; node [fillcolor="#748ffc", shape=Mrecord]; Conv1 [label="{卷积 | + ReLU}"]; Pool1 [label="池化", fillcolor="#91a7ff"]; Conv2 [label="{卷积 | + ReLU}"]; Pool2 [label="池化", fillcolor="#91a7ff"]; Conv1 -> Pool1 -> Conv2 -> Pool2; } Flatten [label="展平", shape=invtrapezium, fillcolor="#bac8ff"]; subgraph cluster_fc { label = "全连接层"; style=filled; fillcolor="#e9ecef"; node [fillcolor="#d0bfff", shape=ellipse]; FC1 [label="全连接 + ReLU"]; Output [label="输出\n(全连接 + 线性)", shape=doublecircle, fillcolor="#ffc078"]; FC1 -> Output; } subgraph cluster_out { label = "动作价值"; style=filled; fillcolor="#e9ecef"; node [shape=plaintext, fillcolor="#ced4da"]; QVals [label="[Q(s,a₁), ..., Q(s,aₘ)]"]; } Input -> Conv1; Pool2 -> Flatten; Flatten -> FC1; Output -> QVals [arrowhead=none]; label="DQN 的简化CNN架构(图像输入)"; fontsize=12; labelloc=b; }CNN通过卷积层和池化层处理输入图像,以提取空间特征。这些特征随后被展平并通过全连接层,为每个动作输出Q值。一般建议从简入手: 从相对较浅的网络(层数较少)以及较少的神经元/滤波器开始。如果性能不足,可以稍后增加复杂度。过于复杂的网络训练起来会更困难、更慢。匹配问题复杂度: 简单的环境(如CartPole)可能只需要一个小型MLP,而带有视觉输入的复杂环境(如Atari游戏)则需要更深层的CNN。采用标准方法: 隐藏层使用ReLU等常用激活函数,输出层使用线性激活函数。可以考虑将研究论文中已有的架构(例如最初的DQN Atari架构)作为起点。迭代调整: 网络设计常包含实验过程。训练您的智能体,评估其性能,并根据结果调整架构(层数、神经元数量、滤波器大小等)。选择合适的架构是让DQN取得良好效果的一个环节。通过考虑状态空间的特性并借助常见的网络设计模式,您可以为您的强化学习智能体构建有效的函数估算器。