想象你是一家公司的项目经理,手下有位“报喜军师”。这位军师从来不说坏话,你问“这个项目能赚多少?”他永远回答“稳赚不赔,大胆投!”你信了他的话,连续追投了好几个激进项目,结果几次大额亏损——公司差点倒闭。这就是 DDPG 算法在连续控制任务中面临的核心困境:价值评估网络(Critic)会对未来的回报过于乐观,这种“乐观偏差”在训练中会像滚雪球一样越滚越大,最终让策略(Actor)做出疯狂的错误决策。TD3 算法(Twin Delayed DDPG)的解决方案,就像给这家公司引入了一套严谨的决策制度:请两位独立军师分别报价、只采纳更保守的那个(双Q网络取最小值);军师汇报要连续稳定多次后,你才调整公司大方向(延迟策略更新);评估目标方案时,故意模拟一点“手抖”误差来检验方案是否真的稳妥(目标策略平滑)。这一套组合拳,把 DDPG 的“乐观病”彻底治好了。
掌握 TD3 是进入深度强化学习工业实战的必经之路,它解决了 DDPG 在机器人控制、自动驾驶等连续控制任务中训练不稳定、难以收敛的痛点,是衡量你从“调参侠”迈向“算法工程师”的分水岭。
目录
可视化演示
本节配有交互动效(进入视口后自动加载,约 3KB)。
改进1: 双Q网络取最小值 Critic Q1Critic Q2Critic Q1Critic Q1Critic Q2Critic Q1 Critic Q1Critic Q2Critic Q1Critic Q1Critic Q2Critic Q1
问题诊断:从DDPG到TD3
故事要从那位“报喜军师”说起。DDPG 算法本质上是让一个 Actor(决策者)和一个 Critic(评估者)协作:Actor 负责出招,Critic 负责给每个招式打分。问题就出在这个 Critic 身上——它既是裁判员,又是运动员。它给自己定“标准答案”时,依赖的是自己过去的评分习惯。就像那位军师,每次评估都带一点乐观滤镜,夸大了收益。一次夸大看不出问题,但训练中这个估值会被反复当作“标准答案”去学习,乐观偏差像利滚利一样,在时间维度上不断传导和放大。
学术上把这种现象称为“过估计”(overestimation)。DDPG 的目标值计算公式如下:
问题是,$Q'$ 本身也来自同一个乐观的军师。每一次训练,它都在用自己的虚高旧账去教新的自己,偏差自然越滚越大。TD3 的改进思路非常直接:既然单一评估者会盲目乐观,那就请两位独立军师,互相制约;既然军师一激动就乱报价,那就规定等他们口径稳定后再动大方向;既然真实世界里动作总有小误差,那就在评估目标时故意加点抖动,检验方案在“手抖”情况下还稳不稳。这三条,构成了 TD3 的三大核心改进。
- 即时奖励 $r$执行动作后环境立刻返回的回报,训练中从经验回放里采样得到。
- 折扣因子 $\gamma$衡量未来收益相对于当前收益的权重,通常取 $0.99$,表示“今天的$1$元约等于明天的$0.99$元”。
- 目标策略 $\mu'\left(s'\right)$目标网络根据下一状态 $s'$ 给出的建议动作,相当于“军师在下一时刻的预测”。
- 目标Q值 $Q'\left(s', a'\right)$目标 Critic 对“下一状态+建议动作”的价值评分。把这个评分打折加进当前奖励,就构成了当前价值的“标准答案”。
双Q网络:两位军师取保守报价
既然单一位军师容易报喜不报忧,项目组定下新规矩:设立两个完全独立的评估小组,每组各自独立调研、独立报价,最终的投资决策只听两者中更保守的那个数字。为什么要听保守的?因为乐观偏差是单向的——没人会哭着说“这项目稳赔”,但会说“这项目暴赚”。取最小值,正好把这类虚高的报价卡在门外。
对应到算法里,TD3 维护两个独立的 Critic 网络 $Q_{\theta_1}$ 和 $Q_{\theta_2}$,对应两个目标网络 $Q_{\theta_1'}$ 和 $Q_{\theta_2'}$。计算目标值时,不再只用一个网络的输出,而是取两个目标网络输出的最小值:
为什么这能治住过估计?两个网络由于初始化不同、训练样本顺序有差异,它们的乐观偏差几乎不可能完全同步。取最小值后,即使某一个网络偶尔虚高,另一个网络也能把它拉回来。TD3 付出的代价是略微低估了真实价值——不过这属于“宁可保守也不冒进”的取舍,在连续控制任务中,低估比虚高安全得多,策略反而更稳定。
- 两个目标网络 $Q_{\theta_1'}$ 与 $Q_{\theta_2'}$分别对“下一状态+目标动作”独立打分。
- 取最小值 $\min_{i=1,2}$对两个分数逐元素比较,只保留更小的那个,作为保守估计。
- 组装目标 $y$用保守分数替代单一分数,代入贝尔曼公式。
延迟策略更新:让军师先达成共识
新制度实施后,又暴露出一个新问题:军师上午刚报完价,项目经理下午就急不可耐地调整了公司战略方向。但策略一动,评估体系也得跟着变,两边互相拉扯,整个系统震荡不停。于是明文规定:军师评估是每天做的事,但调整公司大方向必须每 $d$ 天才允许一次,让评估结果先沉淀下来。
TD3 中的“延迟”正是这个意思:Critic(价值网络)每一步训练都更新,因为它是裁判,需要紧跟最新数据;但 Actor(策略网络)每 $d$ 步才更新一次,默认 $d=2$。这样 Critic 有充足时间逼近真实价值函数,Actor 再去学习时,面对的就不再是晃来晃去的靶子。策略更新的数学形式可以写为:
有了这条“慢半拍”的规矩,每次策略更新都基于相对稳定的价值评估,不再被 Critic 的短期波动带偏。这就像公司战略调整前,一定要看军师们连续一周的稳定报告,而不是某一天的热血汇报。
- 策略梯度方向 $\nabla_\theta Q_1$用第一个 Critic 对当前策略动作的打分来指引策略参数 $\theta$ 的更新方向。
- 学习率 $\alpha$控制每次沿梯度方向迈多大步。
- 延迟条件 $t \bmod d = 0$只有时间步数能被 $d$ 整除时,才执行上述参数更新。
目标策略平滑:给目标方案加一点手抖
两位军师上任后,有人提出钻空子的办法:如果知道评审只看最完美的那个动作,就故意把报告写得天花乱坠,专挑理想状态来说。军师们商量后决定:评审目标方案时,故意模拟一点手抖——在目标动作上加入小幅随机噪声,看看方案在真实执行时(动作总会有点误差)是否依然可靠。这样一来,不管你怎么粉饰,评审都会考察你周围一小片区域的表现。
对应算法,TD3 在计算目标动作时,会给目标策略的输出加上一个被裁剪过的高斯噪声,再把结果限制在合法动作范围内:
这项技巧的作用等同给价值函数施加了正则化:它让 Critic 不能只对一个点给出虚高分,而必须对一个区域都给出稳定高分。目标动作因此从一个“完美尖峰”变成了一个小范围区域,有效防止了价值函数在个别动作上出现“华而不实”的尖峰。
- 高斯噪声 $\mathcal{N}(0, \sigma^2)$以零为中心、标准差 $\sigma$ 的随机扰动,模拟真实环境中的执行误差。
- 噪声裁剪把噪声限制在 $[-c, c]$ 区间内,防止极端扰动影响评估。
- 目标动作加噪目标策略的输出加上平滑噪声,得到实际用于评估的动作。
- 动作边界裁剪把最终动作限制在环境允许的范围 $[a_{\text{low}}, a_{\text{high}}]$ 内。
目标网络软更新:军师的记忆慢慢刷新
军师们还有一个习惯性问题:每次开完会,就完全抛弃旧观点,用今天的最新数据重新建立世界观。结果昨天的判断和今天的判断经常断崖式跳变,评估结果忽高忽低。后来改成:军师每天把旧认知往新证据方向挪一小步,既吸收新信息,又不失忆。
TD3 维护的目标网络就是“军师的长期记忆”。它不像在线网络那样每步都剧烈变化,而是通过软更新缓慢逼近在线网络的参数。每一步更新都只移动一点点:
软更新的价值在于给整个训练过程加了一层“惯性”。对比 DDPG 常用的硬拷贝(过一段时间直接把在线参数复制给目标网络),软更新让目标值的变化轨迹更平滑,Critic 在学习时面对的目标不会突然大幅横跳,训练因此更加稳定。这也是 TD3 中多个目标网络(Actor 目标、两个 Critic 目标)统一使用的更新方式。
- 插值系数 $\tau$控制目标网络向在线网络靠近的速度,默认 $\tau = 0.005$。
- 在线参数 $\theta_{\text{online}}$当前价值网络或者策略网络的最新参数。
- 目标参数 $\theta'_{\text{target}}$更新前的目标网络参数,代表“旧记忆”。
- 加权求和新记忆 = 一小部分最新参数 + 一大部分旧参数。
训练流程:项目评审的完整闭环
让我们把整套决策制度完整地捋一遍。一个训练周期就像公司开一次项目复盘会:先从一线收集近期数据(环境交互采样),把数据存进案例库(经验回放池);复盘会开始时,随机抽取一批历史案例;评审组(双 Critic)用保守口径评估这批案例的“合理回报”;然后按延迟制度,每隔几天才调整一次公司战略(策略更新);最后,军师们把各自的新认知慢慢融进长期记忆(软更新)。
整个流程循环往复,直到策略表现收敛。其中 Critic 的训练目标是最小化预测值与目标值之间的差距:
两个 Critic 各自独立地做这个回归,但共享同一个保守目标 $y$。这样它们既保持独立,又被引导着逼近同一个“地面真相”。训练中观察回报曲线是否平稳上升、Q 值是否不再异常冲高,就可以判断制度是否在良性运转。
- 批次大小 $N$从经验回放池中随机采样的样本数量,论文常用 $N=256$。
- TD目标 $y_j$样本 $j$ 对应的保守目标值(含双Q取小与平滑噪声)。
- 预测Q值 $Q_{\theta_i}\left(s_j, a_j\right)$当前第 $i$ 个 Critic 对“状态-动作对”的打分。
- 均方误差所有样本误差平方的平均值,越小说明预测越准。
实战调参:顾问团队的制度手册
制度定好了,具体执行细则还需要精心打磨。TD3 之所以在工业界受欢迎,一个重要原因是它的默认超参经过大量验证,能直接迁移到各种连续控制任务。当然,“能用”和“好用”之间还需要一些调参经验。
论文给出的核心默认配置可以总结如下:
工程实践中还有几条经验法则:一是探索噪声(加到行为动作上的)通常比平滑噪声大,且随训练衰减;二是如果回报曲线长时间不涨,先检查经验回放池是否过小或奖励是否未归一化,再考虑调大 $\sigma$;三是评估模型时不要只看最后一帧,要跑多个随机种子取平均。调参的本质,就是在“军师团队”的乐观程度、反应速度和记忆长度之间寻找平衡——这套制度能不能发挥作用,往往就藏在那些小数点后的数字里。
- 策略噪声标准差 $\sigma = 0.2$目标平滑中高斯噪声的强度,控制“手抖”幅度。
- 噪声裁剪 $c = 0.5$噪声的最大绝对值,防止抖动过大干扰评估。
- 延迟步数 $d = 2$策略网络每隔一次价值更新才更新一次。
- 软更新系数 $\tau = 0.005$目标网络每次向在线网络移动的比例。
- 折扣因子 $\gamma = 0.99$未来回报的衰减速度,越大表示越重视长远收益。
AI 应用场景
机械臂关节控制
阶段:策略训练与部署
解决的问题:传统 PID 控制器需要人工整定大量参数,面对复杂轨迹跟踪任务时适应性差。DDPG 虽然能端到端学习控制策略,但训练中 Q 值过估计会导致机械臂动作剧烈抖动甚至伤及电机。TD3 的双Q取最小与目标平滑机制,让学到的动作既平滑又稳定。
具体案例:某工厂用 6 自由度机械臂做零件装配,要求关节角度连续变化且不能超调。工程师用 TD3 在仿真环境预训练,再通过域随机化迁移到真实机械臂,训练 50 万步后轨迹跟踪误差降低了 40%,且全程无剧烈振荡。
自动驾驶横向控制
阶段:决策模型训练与评测
解决的问题:自动驾驶的转向和油门都是连续量,传统方法依赖规则查表,难以覆盖复杂路况。TD3 适合处理这种高维连续控制问题,且稳定训练出的策略不会出现“方向盘疯狂摆动”的危险行为。
具体案例:某自动驾驶团队在模拟器中训练 TD3 策略,控制车辆在雨雪天气下保持车道。由于平滑噪声机制,策略对传感器噪声和路面湿滑带来的执行误差具有天然鲁棒性,仿真到实车的迁移成功率比 DDPG 提升了约 30%。
工业过程温度控制
阶段:控制器优化与在线监控
解决的问题:化工反应釜的温度控制具有大滞后、非线性特点。传统 PID 容易超调,严重时影响产品质量。TD3 通过双Q保守估计,学习出更温和的调节策略,阀门开度变化平缓,温度波动明显减小。
具体案例:某化工厂将 TD3 部署在反应釜温度控制回路上,以设定温度与实际温度的偏差作为奖励信号。上线运行 72 小时后,温度超调量从原来的 ±8°C 缩小到 ±2°C,能耗也随之下降 12%。
Python 演示
import torchimport torch.nn as nnimport torch.nn.functional as Fimport numpy as np class CNet(nn.Module): def __init__(self, state_dim, action_dim, hidden=256): super().__init__() self.net = nn.Sequential( nn.Linear(state_dim + action_dim, hidden), nn.ReLU(), nn.Linear(hidden, hidden), nn.ReLU(), nn.Linear(hidden, 1)) def forward(self, s, a): return self.net(torch.cat([s, a], dim=-1)) class ANet(nn.Module): def __init__(self, state_dim, action_dim, max_action, hidden=256): super().__init__() self.net = nn.Sequential( nn.Linear(state_dim, hidden), nn.ReLU(), nn.Linear(hidden, hidden), nn.ReLU(), nn.Linear(hidden, action_dim), nn.Tanh()) self.max_action = max_action def forward(self, s): return self.max_action * self.net(s) class TD3Agent: def __init__(self, state_dim, action_dim, max_action, tau=0.005, policy_noise=0.2, noise_clip=0.5, delay=2): self.max_action = max_action self.tau = tau self.policy_noise = policy_noise self.noise_clip = noise_clip self.delay = delay self.actor = ANet(state_dim, action_dim, max_action) self.actor_target = ANet(state_dim, action_dim, max_action) self.actor_target.load_state_dict(self.actor.state_dict()) self.q1 = CNet(state_dim, action_dim) self.q1_target = CNet(state_dim, action_dim) self.q2 = CNet(state_dim, action_dim) self.q2_target = CNet(state_dim, action_dim) self.q1_target.load_state_dict(self.q1.state_dict()) self.q2_target.load_state_dict(self.q2.state_dict()) self.actor_opt = torch.optim.Adam(self.actor.parameters(), lr=3e-4) self.q_opt = torch.optim.Adam( list(self.q1.parameters()) + list(self.q2.parameters()), lr=3e-4) self.update_count = 0 def select_action(self, state, explore_noise=0.1): s = torch.FloatTensor(state).unsqueeze(0) a = self.actor(s).cpu().data.numpy().flatten() a = a + np.random.normal(0, explore_noise * self.max_action, size=a.shape) return np.clip(a, -self.max_action, self.max_action) def update(self, states, actions, rewards, next_states, dones): s = torch.FloatTensor(states) a = torch.FloatTensor(actions) r = torch.FloatTensor(rewards).unsqueeze(1) ns = torch.FloatTensor(next_states) d = torch.FloatTensor(dones).unsqueeze(1) noise = torch.clamp( torch.randn_like(a) * self.policy_noise, -self.noise_clip, self.noise_clip) na = torch.clamp(self.actor_target(ns) + noise, -self.max_action, self.max_action) y = r + (1 - d) * 0.99 * torch.min( self.q1_target(ns, na), self.q2_target(ns, na)) loss_q = F.mse_loss(self.q1(s, a), y.detach()) + \ F.mse_loss(self.q2(s, a), y.detach()) self.q_opt.zero_grad() loss_q.backward() self.q_opt.step() self.update_count += 1 if self.update_count % self.delay == 0: loss_p = -self.q1(s, self.actor(s)).mean() self.actor_opt.zero_grad() loss_p.backward() self.actor_opt.step() for tp, p in zip(self.actor_target.parameters(), self.actor.parameters()): tp.data.copy_(self.tau * p.data + (1 - self.tau) * tp.data) for tq, q in zip(self.q1_target.parameters(), self.q1.parameters()): tq.data.copy_(self.tau * q.data + (1 - self.tau) * tq.data) for tq, q in zip(self.q2_target.parameters(), self.q2.parameters()): tq.data.copy_(self.tau * q.data + (1 - self.tau) * tq.data) return loss_q.item() if __name__ == "__main__": agent = TD3Agent(state_dim=3, action_dim=1, max_action=2.0) batch = (np.random.randn(64, 3).astype(np.float32), np.random.randn(64, 1).astype(np.float32), np.random.randn(64, 1).astype(np.float32), np.random.randn(64, 3).astype(np.float32), np.random.randint(0, 2, (64, 1)).astype(np.float32)) loss = agent.update(*batch) print("TD3 update OK, critic loss =", round(loss, 4))
self.q1_target.load_state_dict(self.q1.state_dict())初始化时把在线网络的参数复制给目标网络,保证起点一致。noise = torch.clamp(torch.randn_like(a) * self.policy_noise, -self.noise_clip, self.noise_clip)生成裁剪后的平滑噪声,模拟“手抖”。na = torch.clamp(self.actor_target(ns) + noise, -self.max_action, self.max_action)目标动作加噪后裁剪到合法范围,构成平滑目标动作。y = r + (1 - d) * 0.99 * torch.min(self.q1_target(ns, na), self.q2_target(ns, na))双Q取最小值组装TD目标,完整体现“保守报价格”制度。F.mse_loss(self.q1(s, a), y.detach())让在线Q网络向固定的保守目标回归,目标值不反传梯度。self.update_count % self.delay == 0延迟策略更新的开关,每 $d$ 步才触发一次策略改进。loss_p = -self.q1(s, self.actor(s)).mean()策略梯度通过最大化第一个Q网络的打分来实现。tp.data.copy_(self.tau * p.data + (1 - self.tau) * tp.data)对Actor目标网络执行软更新,目标参数只朝在线参数移动 $\tau$ 比例。
常见误区
误区两个Q网络取最小值会严重低估真实收益,反正 DDPG 是过估计、TD3 是欠估计,那取平均值不就“中和”了吗?为什么非得那么保守?
正解TD3 选择 min 是有明确理论依据的。过估计源于 max 操作与自举的叠加,是系统性的单向偏差;而双Q网络各自的乐观偏差大概率不完全相关,取最小值能有效切断“虚高传导”。如果用均值,虽然偏差看起来被“摊薄”了,但只要两者同时偏高,均值依然偏高,过估计问题又会悄悄溜回来。宁可保守,不可冒进,这句决策智慧在TD3中体现得淋漓尽致。
为何常见:人们习惯性地认为“平均更接近真相”,但忽略了强化学习中误差是方向性的——自举会把乐观偏差持续放大,平均值并不能改变这个方向。
误区既然叫“延迟”DDPG,应该所有网络都慢慢更新吧?是不是目标网络和在线网络都要隔几步才更新一次?
正解TD3 的“延迟”只针对策略网络(Actor)。价值网络(Critic)是每一步都更新的,因为它的任务就是尽快逼近真实价值函数;策略网络则要等价值函数稳定后才更新,默认每 2 步一次。目标网络则走软更新。三者节奏完全不同:Critic 快跑、Actor 慢跑、目标网络小步走。
为何常见:从名字望文生义,把“延迟”理解成了全局减速,而没有理解延迟的本质是让价值评估先于策略调整,从而给 Actor 提供一个更稳定的学习目标。
误区策略评估时在目标动作上加噪声,这不是把学好的动作搞乱了吗?训练完是不是还得把噪声去掉才行?
正解目标平滑噪声只加在目标网络计算TD目标时使用的动作上,目的是让 Critic 学会对一个邻域都给出稳定打分,而不是对某个点“死记硬背”。它等效于一种正则化,让价值函数更平滑,反而能提升真实策略的鲁棒性。真正用于环境交互的动作(行为动作)使用探索噪声,在评估阶段通常置零。
为何常见:初学者容易把“目标动作”与“实际执行动作”混为一谈,其实两者分属不同网络、服务于不同目的。
误区TD3 这么稳,收敛速度肯定也碾压 DDPG,直接换 TD3 就能又快又稳地训练!
正解TD3 的三大改进解决的是稳定性问题,不是速度问题。由于多了双Q网络、延迟更新、噪声平滑,计算量更大;在训练早期,保守策略甚至可能显得“畏手畏脚”,回报上升趋势比 DDPG 更慢。TD3 的价值在于同等训练步数下最终收敛效果更好、方差更小,而不是每步回报都领先。
为何常见:把“稳定”和“快速”混为一谈。稳定指的是训练曲线的方差小、最终性能可靠,而速度是另一个维度的指标。
误区既然要“两个独立军师”,那他们必须有完全不同的知识背景,得把两个 Critic 网络设计成不同架构才行吧?
正解TD3 的两个 Critic 网络结构完全相同,差异只来自随机初始化和训练过程中的样本顺序。正是这种“同构但独立演化”的关系,让两者的乐观偏差不完全相关,取最小值才有意义。如果故意用不同架构,反而难以平衡两者收敛速度,可能导致其中一个网络总拖后腿。
为何常见:把“独立”误解为“不同结构”。实际上独立指的是参数演化路径相互独立,而非网络骨架不同。
面试题
Q1. TD3中“双Q网络取最小值”主要解决的问题是什么?
- A.降低模型计算复杂度
- B.抑制价值过估计← 正确答案
- C.提升环境采样效率
- D.加速策略网络收敛
答案:B。TD3 的核心动机就是解决 DDPG 中 Q 值虚高的问题。取两个 Critic 输出中的较小值,相当于在“乐观偏差”这条路上设了一道闸门,防止虚高估价被自举机制放大。降低复杂度、提升采样效率都不是双Q取min的设计目标。
Q2. 下列哪个是 TD3 计算目标值的正确公式?
- A.$y = r + \gamma\, Q'\left(s', a'\right)$
- B.$y = r + \gamma\, \max_{a'} Q'\left(s', a'\right)$
- C.$y = r + \gamma\, \min\left(Q_1',\, Q_2'\right)$← 正确答案
- D.$y = r + \gamma\, \frac{Q_1' + Q_2'}{2}$
答案:C。选项 C 完整体现了双Q取最小机制,是 TD3 区别于 DDPG 的标志性公式。选项 A 是单网络目标,选项 B 是 Q-learning 中的最大化操作(正是过估计来源),选项 D 用平均值替代最小值无法有效抑制过估计。
Q3. TD3 相比 DDPG 引入了哪些关键改进?
- A.双Q网络取最小值← 正确答案
- B.延迟策略更新← 正确答案
- C.目标策略平滑← 正确答案
- D.优先经验回放
答案:ABC。TD3 的三大改进是双Q取min、延迟更新、目标平滑,分别对应选项 A、B、C。优先经验回放是其他算法(如 PER-DQN)的技术,不属于 TD3 的核心贡献。这三项改进共同解决了“乐观军师”带来的过估计问题。
Q4. TD3 中策略网络默认每隔多少步更新一次?
- A.每一步都更新
- B.每两步更新一次← 正确答案
- C.每十步更新一次
- D.完全不更新
答案:B。论文默认延迟步数 $d=2$,即价值网络每步更新,策略网络每隔一次价值更新才更新。如果每一步都更新(选项A),就回到了 DDPG 的不稳定状态;延迟太多(选项C)又会浪费训练效率。选项D显然不符合训练逻辑。
Q5. 目标策略平滑中,噪声被裁剪到什么范围?
- A.$[-c, c]$,$c$ 为噪声裁剪阈值← 正确答案
- B.$[-\sigma, \sigma]$,$\sigma$ 为标准差
- C.$[0, 1]$,固定归一化区间
- D.不裁剪,完全自由
答案:A。平滑噪声从高斯分布采样后,被裁剪到 $[-c, c]$ 区间,论文默认 $c=0.5$。裁剪的目的是防止个别极端噪声污染目标值。选项 B 中 $\sigma$ 是分布参数不是裁剪边界;选项 C、D 都与论文实现不符。
Q6. 为什么延迟策略更新能让训练更稳定?
- A.让价值网络先充分逼近真实价值← 正确答案
- B.减少策略网络的参数量
- C.降低动作空间维度
- D.提高环境互动频率
答案:A。延迟更新的核心逻辑:价值网络每步训练后变得更准确,策略网络再基于“稳定可靠”的价值函数更新,避免了“靶子乱动”的问题。选项 B、C、D 都不涉及训练稳定性的本质,因为参数量、动作空间、互动频率并未改变。
Q7. 关于目标网络软更新,下列说法正确的是?
- A.目标参数向在线参数缓慢靠近← 正确答案
- B.默认插值系数 $\tau=0.005$← 正确答案
- C.目标网络一直保持初始值不变
- D.相比硬拷贝,软更新更平滑← 正确答案
答案:ABD。软更新公式 $\theta' \leftarrow \tau \theta + (1-\tau)\theta'$ 让目标网络逐步追踪在线网络,$\tau=0.005$ 表示每次只移动 0.5%。选项 C 错误,因为软更新正是为了让目标网络缓慢变化而非静止;选项 D 正确,软更新避免了硬拷贝导致的目标值突变。
Q8. DDPG 中 Q 值过估计的根本来源是什么?
- A.最大化操作与自举误差叠加← 正确答案
- B.网络隐藏层设置太深
- C.学习率设置过高
- D.探索噪声设置过小
答案:A。过估计的本质是 Bootstrapping(用自己估计的值去更新自己)与 Q 值更新中隐含的“最大化”操作叠加,导致积极误差被反复放大。网络深度、学习率、噪声大小都是工程因素,不是过估计的理论根源。
Q9. 关于目标策略平滑噪声,下列说法正确的是?
- A.加在目标网络的输出动作上← 正确答案
- B.噪声经过裁剪限幅← 正确答案
- C.起到正则化作用← 正确答案
- D.加在环境执行的行为动作上
答案:ABC。平滑噪声加在目标动作上(选项A正确),并非行为动作(选项D错误);噪声被裁剪到 $[-c,c]$(选项B正确);它让价值函数对邻域动作都稳定,属于正则化手段(选项C正确)。注意区分“目标平滑噪声”与“探索噪声”两个概念。
Q10. 如果将 TD3 目标值中的 $\min$ 改为 $\text{mean}$,最可能发生什么?
- A.训练结果完全不变
- B.过估计风险重新回升← 正确答案
- C.价值函数立刻发散崩溃
- D.策略收敛速度显著加快
答案:B。取平均值后,如果两个 Q 网络同时存在正向偏差(现实中经常发生),均值依然偏高,过估计会重新出现,所以 B 正确。选项 A 忽略了均值与最小值的本质差异;选项 C 过于绝对,训练未必立刻崩溃但会逐渐恶化;选项 D 没有理论依据,均值并不能加快收敛。