实现和试用BCQ和CQL等主要离线强化学习算法,这些算法旨在应对分布偏移带来的困难。通过这些算法的实践应用,有助于加深理解。直接处理代码和数据有助于呈现从固定数据集训练智能体所涉及的实际细节。我们将着重实现批约束Q学习(BCQ)和保守Q学习(CQL),这两种通过不同机制处理分布偏移的知名方法:分别是策略约束和价值正则化。实践环境的搭建在实现算法之前,我们需要合适的数据集和正确的工具。离线强化学习的数据集离线强化学习社群因标准化数据集而受益匪浅,这些数据集有助于可重复的科研和算法间的公平比较。D4RL(用于深度数据驱动强化学习的数据集)基准测试集是一个被广泛使用的资源。它提供了在不同环境(如MuJoCo物理模拟、Atari游戏和机器人任务)中,使用各种行为策略(从随机到接近最优)收集的数据集。一个典型的离线数据集 $ \mathcal{D} $ 由一系列转换组成,通常以单独的数组或字典形式存储: $ \mathcal{D} = { (s_i, a_i, r_i, s'{i}, d_i) }{i=1}^N $ 这些符号表示:$ s_i $ 是步骤 $ i $ 时的状态。$ a_i $ 是行为策略 $ \pi_b $ 在状态 $ s_i $ 中采取的动作。$ r_i $ 是采取动作 $ a_i $ 后获得的奖励。$ s'_{i} $ 是观察到的下一个状态。$ d_i $ 是一个布尔标志,表示情节是否在状态 $ s'_{i} $ 终止。$ N $ 是数据集中转换的总数。你需要安装必要的库来加载和处理这些数据集。对于D4RL,这通常涉及安装其特定的软件包。所需工具Python: 机器学习科学的标准语言。深度学习框架: TensorFlow或PyTorch,用于构建和训练神经网络(Q函数、VAE等)。NumPy: 用于数值运算。D4RL 或类似库: 便于加载离线数据集。环境模拟器(可选但推荐): 虽然训练是离线进行的,但评估最终学得的策略需要在环境模拟器(例如Gym、MuJoCo)中进行交互。批约束Q学习(BCQ)的实现BCQ的目标是减少外推误差,通过确保所学策略选择的动作“接近”行为数据集 $ \mathcal{D} 中存在的动作。它通过使用Q网络、生成模型和扰动网络来达成此目的。主要组成部分Q网络 ($ Q_\theta(s, a) $): 估算动作值函数的标准神经网络。通常使用两个Q网络(如TD3/Double DQN中)来减少过高估计偏差。我们将它们称为 $ Q_{\theta_1} $ 和 $ Q_{\theta_2} $。生成模型 ($ G_\omega(s) $): 模拟给定状态 $ s $ 下数据集中存在的动作分布。条件变分自编码器(cVAE)是一种常用模型。它包括一个将状态-动作对映射到潜在空间的编码器 $ E(s, a) $ 和一个从状态 $ s $ 及潜在代码 $ z $ 生成动作的解码器 $ D(s, z) $。它被训练来从数据集中重建动作:$ a \approx D(s, E(s, a)) $。扰动网络 ($ \xi_\phi(s, a, \Phi) $): 一个小型网络,对 $ G_\omega $ 生成的动作进行微小调整。它接收状态 $ s $ 和动作 $ a $,并输出一个在范围 $ [-\Phi, \Phi] $ 内的小扰动 $ \Delta a $。扰动后的动作为 $ a + \xi_\phi(s, a, \Phi) $。这允许对数据集动作进行轻微偏离,可能找到附近的更好动作。BCQ的动作选择与更新在训练期间,为了计算状态 $ s' $ 下Q函数更新的目标值,BCQ执行以下步骤:生成候选动作: 使用生成模型为下一个状态 $ s' $ 采样 $ k $ 个动作:$ { a'j = D(s', z_j) }{j=1}^k $,这里 $ z_j $ 从先验分布(例如,标准高斯分布)中采样。扰动动作: 使用扰动网络扰动每个采样的动作:$ { \tilde{a}'_j = a'j + \xi\phi(s', a'j, \Phi) }{j=1}^k $。将扰动后的动作裁剪到有效动作范围。选择最佳动作: 从扰动集合 $ { \tilde{a}'j } $ 中选择动作 $ a^* $,使其根据目标Q网络最大化Q值(为了稳定性,使用两个目标网络中的最小值): $$ a^* = \arg\max{\tilde{a}'j} \min{i=1,2} Q_{\theta'_i}(s', \tilde{a}'_j) $$计算目标值: 使用选择的动作 $ a^* $ 计算目标Q值: $$ y = r + \gamma (1 - d) \min_{i=1,2} Q_{\theta'_i}(s', a^*) $$ 这里 $ \gamma $ 是折扣因子,$ \theta' $ 表示目标网络参数。更新Q网络: 通过使用从 $ \mathcal{D} $ 中采样的转换 $ (s, a, r, s', d) $ 来最小化贝尔曼误差,更新Q网络参数 $ \theta_1, \theta_2 $ : $$ L_Q(\theta_1, \theta_2) = \mathbb{E}{(s,a,r,s',d) \sim \mathcal{D}} \left[ \sum{i=1,2} (Q_{\theta_i}(s, a) - y)^2 \right] $$更新VAE和扰动网络: cVAE ($ G_\omega $) 和扰动网络 ($ \xi_\phi $) 也需要训练。cVAE最小化数据集中动作的重建损失。扰动网络 $ \xi_\phi $ 训练以最大化 $ Q_{\theta_1}(s, a + \xi_\phi(s, a, \Phi)) $。实现上的考虑VAE训练: 在开始Q学习更新之前,对VAE在数据集上进行预训练有时可以稳定训练。超参数: 采样的动作数量 $ k $ 和扰动限制 $ \Phi $ 是影响保持数据接近性和尝试细微变化的权衡的重要超参数。动作空间: 最初的BCQ主要关注连续动作。对于离散动作空间存在改编版本,通常会简化生成/扰动模型。保守Q学习(CQL)的实现CQL采用了一种不同的方法。它不限制策略,而是修改Q学习目标本身,以防止对OOD动作的Q值过高估计。它学习一个保守的Q函数。CQL的目标函数CQL在标准贝尔曼误差目标中添加了一个正则化项。目标是最小化假定为OOD动作的Q值,同时最大化(提高)实际存在于数据集 $ \mathcal{D} $ 中的动作的Q值。组合目标函数如下: $$ \min_\theta \alpha \mathbb{E}{s \sim \mathcal{D}} \left[ \log \sum_a \exp(Q\theta(s,a)) - \mathbb{E}{a \sim \pi_b(\cdot|s)}[Q\theta(s,a)] \right] + \frac{1}{2} \mathbb{E}{(s,a,r,s',d) \sim \mathcal{D}} \left[ (Q\theta(s, a) - y)^2 \right] $$我们来分解CQL正则项(第一项):$ \log \sum_a \exp(Q_\theta(s,a)) $: 这一项的作用类似于状态 $ s $ 下所有可能动作 $ a $ 的Q值的“软最大值”。最小化这一项会普遍降低Q值。对于连续动作,这涉及从某种分布(例如,均匀分布或学习到的策略)中采样动作来近似期望。$ \mathbb{E}{a \sim \pi_b(\cdot|s)}[Q\theta(s,a)] $: 这一项表示在状态 $ s $ 下数据集中实际观察到的动作的预期Q值。由于它是被减去的(或在原始公式中是最大化的),它会提高分布内动作的Q值。$ \alpha $: 一个超参数,控制正则化的强度。较高的 $ \alpha $ 值会施加更强的保守性。第二项是标准均方贝尔曼误差(MSBE),其中 $ y $ 是使用目标网络 $ Q_{\theta'} $ 计算的目标值,可能包含双Q学习等方式: $$ y = r + \gamma (1 - d) Q_{\theta'}(s', \pi(s')) $$ 这里,$ \pi(s') = \arg\max_{a'} Q_\theta(s', a') $ 是当前策略(来源于学习到的Q函数)选择的动作。请注意,CQL在目标值计算中也常使用当前策略和数据集上动作的期望,从而产生略微不同的目标公式。实现上的考虑估计Log-Sum-Exp项: 对于连续动作空间,评估 $ \log \sum_a \exp(Q_\theta(s,a)) $ 需要采样动作(例如,从当前策略、均匀分布或重要性采样)并近似期望。对于离散空间,它直接计算。自动 $ \alpha $ 调整: 手动设定 $ \alpha $ 可能很困难。CQL通常包含一个基于目标值差距约束自动调整 $ \alpha $ 的方法,从而简化了调整。目标值计算: 目标值 $ y $ 的确切公式在不同的CQL实现中可能略有不同(例如,使用多个动作的期望)。请查阅特定论文或库的实现以获取详细信息。计算成本: CQL正则项与标准Q学习相比增加了计算开销,因为它需要对每个状态的多个动作进行Q值评估或采样。离线环境下的评估离线强化学习中一个重要点是评估。由于智能体仅在静态数据集 $ \mathcal{D} $ 上训练,你不能在训练期间通过与环境交互来评估其表现。标准规程如下:完全使用离线数据集 $ \mathcal{D} $ 训练智能体(例如,BCQ或CQL)。训练完成后,获取学得的策略 $ \pi $(来源于最终的Q函数或Actor网络)。通过在实际环境模拟器中运行此固定策略 $ \pi $ 多个情节(例如10或100次),并对获得的累计奖励进行平均来评估。在此评估阶段不会发生进一步的学习或更新。许多基准测试结果(如D4RL)都报告归一化分数,其中性能相对于随机策略(分数为0)和专家策略(分数为100)进行缩放。这有助于比较不同任务和数据集间的性能。实验与比较现在,来测试这些算法吧!选择数据集: 从D4RL等基准测试中选择一个数据集。从更简单的环境(例如,*-medium-*数据集,通常包含好坏数据的混合)开始,然后转向更具挑战性的环境(*-random-*或*-expert-*)。实现BCQ和CQL: 使用PyTorch或TensorFlow等框架。你可能会在网上找到现有实现作为参考,但自己构建它们会提供更深刻的理解。训练智能体: 在选定的数据集上训练BCQ和CQL。通过跟踪以下内容来监控训练进度:Q值(检查稳定性和幅度)。贝尔曼损失。CQL特有的损失项(正则项值)。VAE重建损失(针对BCQ)。定期评估: 尽管最终评估使用模拟器,但你有时可以在训练期间使用离线OPE方法作为粗略的指标,但请谨慎对待这些估计值,因为它们本身存在偏差。最终的评估是在训练后在模拟器中进行的。比较表现: 绘制BCQ和CQL获得的最终评估分数(例如,在模拟器中10个情节的平均回报)。为了进行对比,你还可以实现一个简单的离线Q学习智能体(本质上是离线训练且无约束的DQN)或行为克隆(模仿数据集中动作的监督学习),以观察BCQ和CQL如何超越更简单的基线。{ "data": [ { "type": "scatter", "mode": "lines+markers", "name": "简单离线DQN", "x": [0, 100000, 200000, 300000, 400000, 500000], "y": [5, 10, 12, 8, 6, 5], "line": {"color": "#ff6b6b"} }, { "type": "scatter", "mode": "lines+markers", "name": "行为克隆", "x": [0, 100000, 200000, 300000, 400000, 500000], "y": [15, 18, 20, 21, 20, 19], "line": {"color": "#74c0fc"} }, { "type": "scatter", "mode": "lines+markers", "name": "BCQ", "x": [0, 100000, 200000, 300000, 400000, 500000], "y": [5, 25, 45, 60, 68, 72], "line": {"color": "#51cf66"} }, { "type": "scatter", "mode": "lines+markers", "name": "CQL", "x": [0, 100000, 200000, 300000, 400000, 500000], "y": [5, 30, 55, 70, 78, 80], "line": {"color": "#fcc419"} } ], "layout": { "title": "离线强化学习性能比较", "xaxis": {"title": "训练步数"}, "yaxis": {"title": "归一化评估分数"}, "legend": { "orientation": "h", "yanchor": "bottom", "y": -0.3, "xanchor": "center", "x": 0.5 } } }不同离线方法在一项任务上的评估表现(归一化分数)与训练步数的比较。BCQ和CQL通常通过减少分布偏移,胜过简单方法。故障排除与后续步骤离线强化学习对超参数和实现细节可能很敏感。发散: Q值可能会爆炸或崩溃。检查学习率、目标网络更新频率以及CQL $ \alpha $ 参数的大小。表现不佳: 如果表现不佳,请确保数据集合适且预处理正确。尝试不同的网络架构和超参数(BCQ的 $ k $、$ \Phi $;CQL的 $ \alpha $、目标更新策略)。思考数据集本身的质量;从纯随机数据中学习是极其困难的。进一步学习: 尝试实现其他离线算法,如隐式Q学习(IQL)或决策变换器。研究不同数据集质量(随机、中等、专家、回放)对算法表现的影响。"这种亲自动手的实践是培养对离线强化学习中困难和解决方案的直觉认知的根本。通过实现、调试和比较BCQ和CQL等算法,你将获得将这些技术应用于在线交互受限或成本高昂的问题所需的实践能力。"