PFRL 源码解析:Q 函数与策略网络底层实现
PFRL 是一个基于 PyTorch 的深度强化学习库,提供了从 Q 函数到策略网络的完整实现。对于想要深入理解算法底层机制的开发者来说,直接阅读源码往往比看文档更直观。本文将拆解 PFRL 的核心模块,看看它是如何组织价值估计和决策逻辑的。
Q 函数架构:价值估计的核心实现
Q 函数作为值函数近似的核心组件,在 PFRL 中有着丰富的实现形式。从基础的 DQN 到复杂的决斗网络(Dueling DQN),不同的架构对应着不同的问题场景。
基础 Q 函数实现
在 pfrl/q_functions/state_q_functions.py 中实现了基础的状态 Q 函数。其中 SingleModelStateQFunctionWithDiscreteAction 类是离散动作空间 Q 函数的基类。通过前向传播方法计算状态价值,结构上通常是通过多层感知机将状态映射为动作价值。
class SingleModelStateQFunctionWithDiscreteAction(nn.Module, StateQFunction):
def forward(self, x):
h = self.hidden_layers(x)
q = self.output_layer(h)
return q
这里要注意,虽然代码看起来简单,但实际应用中 hidden_layers 的配置会根据环境维度动态调整,这是 DQN 算法的核心组件。
决斗网络(Dueling DQN)架构
决斗网络通过分离状态价值和优势函数来改进 Q 值估计。在 pfrl/q_functions/dueling_dqn.py 中的实现逻辑如下:
class DuelingDQN(nn.Module, StateQFunction):
def forward(self, x):
h = self.hidden_layers(x)
v = self.value_layer(h)
a = self.advantage_layer(h)
# 优势函数中心化处理
a_mean = a.mean(1, keepdim=True)
q = v + (a - a_mean)
return q
这种架构让智能体能够同时学习状态价值和动作优势。注意这里的 a_mean 中心化操作,这是为了防止训练不稳定,实际跑起来你会发现这对收敛很有帮助。
分布型 Q 函数
PFRL 还实现了分布型 Q 函数(Categorical DQN),它不输出单一值,而是输出价值分布,从而更精确地表示不确定性。
class DistributionalFCStateQFunctionWithDiscreteAction(
DistributionalSingleModelStateQFunctionWithDiscreteAction
):
():
h = .hidden_layers(x)
z = .z_values
logits = .logits_layer(h)
DistributionalDiscreteActionValue(z, logits=logits)

