You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Soft Actor Critic Actor网络前向传播骤现NaN问题求助

SAC Actor网络迭代后出现NaN的排查与解决方案

问题定位

你的Actor网络在几次参数更新后前向传播输出NaN,问题出在sample_normal()的前向计算环节,结合代码细节,核心问题大概率是数值稳定性不足或分布参数的不合理输出导致的。

排查思路与修复方案

1. 修复Sigma的计算方式(关键)

当前代码直接输出sigma并钳制,网络可能输出负数,虽被钳制到1e-6,但这种方式不如通过log_std转换稳定:

  • 恢复你注释掉的log_std逻辑,确保sigma始终为正,避免数值异常:
# 替换原forward中的sigma计算部分
log_std = self.sigma(prob)
log_std = T.clamp(log_std, min=-20, max=2)  # 更宽松的范围,避免过度钳制
sigma = log_std.exp()

sigma通过指数输出天然为正,不会出现负数被强制拉正带来的数值跳变,同时钳制log_std可避免sigma过大或过小导致的采样异常。

2. 优化log_prob的计算稳定性

当action接近±max_action时,1 - action.pow(2)趋近于0,直接计算易引发数值下溢,改用tanh对数恒等式优化:

# 替换原log_probs的计算
log_probs = probabilities.log_prob(actions)
# 用恒等式替换1 - tanh(x)^2的计算,消除数值下溢风险
log_probs -= 2 * (T.log(T.tensor(2.0)) - actions - F.softplus(-2 * actions))
log_probs = log_probs.sum(1, keepdim=True)

3. 初始化Sigma层的权重与偏置

默认Linear层初始化可能让sigma初始输出波动过大,手动将sigma层参数初始化为小值:

# 在__init__中添加
nn.init.normal_(self.sigma.weight, 0, 0.01)
nn.init.constant_(self.sigma.bias, -1.0)  # 初始log_std为-1,对应sigma≈0.37,避免初始方差过大

4. 添加梯度裁剪

即使状态和奖励归一化,反向传播时梯度仍可能累积爆炸,对Actor参数进行梯度裁剪:

# 在Actor参数更新步骤中(optimizer.step()之前)添加
torch.nn.utils.clip_grad_norm_(actor.parameters(), max_norm=1.0)

限制梯度最大范数,避免参数更新幅度过大导致数值异常。

5. 实时监控关键数值

在训练过程中打印关键变量,确认异常来源:

# 在sample_normal中添加调试代码
mu, sigma = self.forward(state)
print("mu range:", mu.min().item(), mu.max().item())
print("sigma range:", sigma.min().item(), sigma.max().item())

若mu出现极大值(如超过10),说明前馈网络输出失控,需检查网络结构或初始化;若sigma趋近于0或过大,说明log_std钳制范围不合理。

6. 调整Adam优化器参数

尝试增大Adam的eps参数,默认eps=1e-8可能在梯度极小时引发数值问题:

self.optimizer = optim.Adam(self.parameters(), lr=alpha, eps=1e-5)

内容的提问来源于stack exchange,提问作者Zubin Oommen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 04:04:58