IQL:Implicit Q-Learning
用上 expectile 价值、只含数据动作的 Q 更新和优势加权行为克隆,避免训练时评价策略生成的未见动作。
学习目标
- 仅用数据动作做价值与策略更新,理解 expectile 与优势加权的支持边界。
- 独立复核“两个数据动作的上 expectile 不等于分位数”的输入、计算和解释。
- expectile 来自非对称平方损失,不是分位数。
为什么重要
仅用数据动作做价值与策略更新,理解 expectile 与优势加权的支持边界。
学习前需要掌握
背景与问题
离线数据中的 max Q 会主动查询未见动作,造成外推误差。IQL 试图在更新时不显式评价新的动作:先从数据动作的价值分布提取偏高状态价值,再偏向较好的数据动作拟合策略。
概念定义
IQL 先用非对称平方损失拟合状态条件 expectile V,再用 r+γV(s′) 回归数据动作 Q,最后以 exp(β(Q−V)) 加权数据动作对数似然。训练中的策略提取不需要在新动作上查询 critic,但部署策略仍会泛化。
直观理解
从同一地点的历史选择中,较重视表现好的记录,形成一个偏积极但仍基于记录的参考值;然后更多模仿超过该参考的动作。它不是在所有未见动作中寻找最高分。
核心原理
expectile 对正负残差使用不同平方权重,τ>0.5 更强调 Q 高于 V 的样本。它不是分位数:分位数对应非对称绝对误差,两个目标的数值和统计意义不同。
Q 回归、V 回归和 actor 回归各有固定目标与停止梯度边界。actor 的优势权重常裁剪,避免指数把少量高估或异常样本放大到支配整个批次;β 越大并不保证改进越好。
“不查询数据外动作”描述训练目标,不是整个策略的严格支持保证。数据缺乏关键状态、函数近似把多峰行为平均到无支持动作,或部署进入新区域时,IQL 仍可能失败。
数学表达
IQL 的三个目标
V 做 expectile regression,Q 只对数据 transition 做 TD,策略只对数据动作做优势加权最大似然。
变量含义
τexpectile 参数;τ>0.5 偏向数据动作中的较高 Q。L₂^τ(u)|τ−1(u<0)|u² 的非对称平方损失。β优势权重的逆温度,越大越偏向高优势样本。Q̄停止梯度或 target Q,用于稳定 V 与策略目标。
计算步骤
- 1较低动作残差用 0.25,较高动作残差用 0.75。
- 2令平方损失导数为零,得到 V=(0.25×1+0.75×3)/(0.25+0.75)=2.5。
- 3这两个原子分布的 0.75 分位数为 3,和 2.5 不同。
代码对应位置
示例 1IQL 的 expectile、TD 与优势加权 BC:用固定 transition 批次对应 IQL 的 V、Q、policy 三个目标,全程不查询策略生成的新动作。
变量解释
| 变量 | 含义 |
|---|---|
τ | expectile 参数;τ>0.5 偏向数据动作中的较高 Q。 |
L₂^τ(u) | |τ−1(u<0)|u² 的非对称平方损失。 |
β | 优势权重的逆温度,越大越偏向高优势样本。 |
Q̄ | 停止梯度或 target Q,用于稳定 V 与策略目标。 |
完整数值示例
两个数据动作的上 expectile 不等于分位数
已知条件
- 同状态等频数据动作的 Q 为 1 与 3,τ=0.75。
- 假设拟合值位于 1 和 3 之间。
计算步骤
- 较低动作残差用 0.25,较高动作残差用 0.75。
- 令平方损失导数为零,得到 V=(0.25×1+0.75×3)/(0.25+0.75)=2.5。
- 这两个原子分布的 0.75 分位数为 3,和 2.5 不同。
计算结果
上 expectile 为 2.5;下方 PyTorch 代码进一步核对 V、Q 和 actor 三项损失。
处理前后对比
- expectile 来自非对称平方损失,不是分位数。
- IQL 避免显式 OOD 动作查询,但不能突破状态覆盖限制。
计算与实现步骤
- 从固定数据采样 batch
- 冻结 Q 目标计算 Q(s,a)−V(s)
- 用非对称平方损失更新 V
- 用 r+γV(s′) 更新 Q
- 计算数据动作 advantage
- 用裁剪后的 exp(βA) 做行为克隆
- 评测并可选在线微调
代码实现
示例 1
IQL 的 expectile、TD 与优势加权 BC
example_01.py用途:用固定 transition 批次对应 IQL 的 V、Q、policy 三个目标,全程不查询策略生成的新动作。
import torch
tau, beta, gamma = 0.7, 3.0, 0.99
q_data = torch.tensor([1.4, 0.4, 2.0], requires_grad=True)
v = torch.tensor([0.9, 0.7, 1.3], requires_grad=True)
v_next = torch.tensor([0.6, 0.2, 0.0])
rewards = torch.tensor([0.5, 0.1, 2.0])
done = torch.tensor([0.0, 0.0, 1.0])
log_prob = torch.tensor([-0.8, -1.1, -0.5], requires_grad=True)
diff = q_data.detach() - v
expectile_weight = torch.where(diff > 0, tau, 1 - tau)
v_loss = (expectile_weight * diff.square()).mean()
td_target = rewards + gamma * (1 - done) * v_next
q_loss = (q_data - td_target).square().mean()
adv = q_data.detach() - v.detach()
policy_weight = torch.exp(beta * adv).clamp(max=100.0)
policy_loss = -(policy_weight * log_prob).mean()
(v_loss + q_loss + policy_loss).backward()
print('expectile weights:', expectile_weight)
print('policy weights:', policy_weight)
print('losses:', [round(x.item(), 3) for x in (v_loss,q_loss,policy_loss)])代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
用固定 transition 批次对应 IQL 的 V、Q、policy 三个目标,全程不查询策略生成的新动作。
mean- 训练特征逐列均值。
Step 1 · 1–1 行
导入当前步骤需要的数值计算、预处理、模型或评价工具。依赖集中写在代码开头,便于复现。
import torchStep 2 · 3–21 行
只从训练数据逐列计算均值与标准差,对应标准化公式中的 μ 和 σ。
tau, beta, gamma = 0.7, 3.0, 0.99
q_data = torch.tensor([1.4, 0.4, 2.0], requires_grad=True)
v = torch.tensor([0.9, 0.7, 1.3], requires_grad=True)
v_next = torch.tensor([0.6, 0.2, 0.0])
rewards = torch.tensor([0.5, 0.1, 2.0])
done = torch.tensor([0.0, 0.0, 1.0])
log_prob = torch.tensor([-0.8, -1.1, -0.5], requires_grad=True)
diff = q_data.detach() - v
expectile_weight = torch.where(diff > 0, tau, 1 - tau)
v_loss = (expectile_weight * diff.square()).mean()
td_target = rewards + gamma * (1 - done) * v_next
q_loss = (q_data - td_target).square().mean()
adv = q_data.detach() - v.detach()
policy_weight = torch.exp(beta * adv).clamp(max=100.0)
policy_loss = -(policy_weight * log_prob).mean()
(v_loss + q_loss + policy_loss).backward()
print('expectile weights:', expectile_weight)
print('policy weights:', policy_weight)
print('losses:', [round(x.item(), 3) for x in (v_loss,q_loss,policy_loss)])代码与数学原理
减去训练均值并除以训练标准差,对应代码中的 mean/std 或 StandardScaler。
平方误差代码对应均方损失。
预期输出或运行结果
expectile weights: tensor([0.7000, 0.3000, 0.7000]) policy weights: tensor([4.4817, 0.4066, 8.1662]) losses: [0.182, 0.035, 2.705]
常见错误 · 4 条
- 不要在测试集上调用 fit 或 fit_transform;测试集只能复用训练参数。
- 把 expectile 称为 τ 分位数。
- 让指数权重无限增长,使异常样本主导策略。
- 把只拟合数据动作夸大成部署永远不会产生数据外动作。
实际应用
- 序贯决策
- 控制与资源分配
常见错误
- 把 expectile 称为 τ 分位数。
- 让指数权重无限增长,使异常样本主导策略。
- 把只拟合数据动作夸大成部署永远不会产生数据外动作。
扩展内容说明
本页数值均为解释机制的构造案例,不能解读为真实训练或基准性能。定义和适用条件参见 Kostrikov 等:Offline Reinforcement Learning with Implicit Q-Learning。
算法属性与数据边界
目标函数
expectile V regression + TD Q regression + advantage-weighted behavioral cloning
Advantage
A(s,a)=Q(s,a)−V(s),仅在数据动作上计算
数据边界
- 训练需要固定 transition 和数据动作;策略目标不对新动作求 Q,但最终策略仍可能因泛化产生数据外动作。
- τ 与 β 决定保守—改进权衡,应随数据质量验证。
- 在线微调是单独阶段;一旦新增环境数据,必须与纯离线结果分开报告。
与 DQN、SAC 及相邻方法对照
- DQN:使用 max_a Q(s′,a);IQL 改用 V(s′),避免下一步 OOD max。
- SAC:actor 采样动作并通过 Q 更新;IQL actor 仅对数据动作做加权最大似然。
- CQL:显式惩罚可能的 OOD 高 Q;IQL 通过不查询这些动作来规避训练时外推。
失败模式、风险与性能
失败模式
- 把 expectile 当成 quantile 实现
- Q/V target 未停止梯度导致耦合不稳
- exp(βA) 溢出或有效样本数过低
- 数据回报尺度变化后沿用原 β
风险
- 高优势历史动作可能来自奖励漏洞或越权行为。
- 部署仍需动作过滤、回退策略和分阶段放量。
性能考虑
- 无需为每个状态采样大量候选动作,通常比采样式 CQL 简洁。
- 报告 τ、β、权重上限、奖励归一化、target 更新与多 seed。
常见问题
IQL 不评价新动作就没有分布外问题了吗?
没有。训练少了一类显式动作外推,但函数近似、状态覆盖、连续策略泛化和长期部署分布仍可能超出数据证据。
网页是否会训练模型?
不会。所有图表使用固定种子或解析公式在浏览器本地计算,不执行页面中的示例代码。
推荐学习资料
Offline Reinforcement Learning with Implicit Q-Learning
通过 expectile value、数据动作 TD 更新和优势加权行为克隆完成隐式策略改进。
Kostrikov / Nair / Levine · arXiv