登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  人工智能

Captum Saliency 的 abs 参数怎样改变梯度含义

来源:17golang原创

时间:2026-10-30 16:28:21 303浏览 收藏

第一次看 Captum Saliency 的结果时,最容易忽略的是默认参数:abs=True。这会把输入梯度变成绝对值,所以结果适合回答“局部变化幅度有多大”,却不再直接告诉你“把这个特征增大,会让目标输出上升还是下降”。如果要保留方向,就显式传入 abs=False。

官方地址:https://captum.ai/api/saliency.html

要点速览
  • target 选择要对哪个输出位置求梯度,abs 决定是否保留梯度正负号。
  • abs=True 的数值不区分促进和抑制;abs=False 才能直接阅读方向。
  • Saliency 是局部梯度,返回形状跟输入一致,不是概率、准确率或因果证明。

先把 target、梯度和 abs 分开

对一个输出为 [N, C] 的分类模型,target 先选出类别分数,Saliency 再计算这个分数相对于输入的梯度。它们回答的是不同问题:target 决定“看哪个输出”,梯度表示“输入在当前点附近改变一点时,目标输出往哪边变”,abs 则决定是否把这个方向折叠掉。

因此,target=2 和 abs=False 并不等价于“类别 2 的概率”。前者只是选了输出索引,后者只是保留导数正负。若模型输出 logits,梯度也是对 logits 的局部变化;若把 forward 包装成概率,解释对象就换了。

Captum Saliency 的 target、输入梯度与 abs 参数之间的静态关系说明图
图1:原创静态说明图,查看 target 选择输出位置、梯度连接输入特征以及 abs 对方向信息的影响。

用最小例子对比两种 abs 语义

下面用固定权重的线性三分类器演示。线性层没有训练过程,读者可以直接从权重理解结果:正权重表示输入增大时目标分数的局部增量为正,负权重表示局部增量为负。

import torch
from captum.attr import Saliency

# 固定三分类权重,只用于解释 abs 参数,不代表训练结果。
model = torch.nn.Linear(4, 3, bias=False)
with torch.no_grad():
    model.weight.copy_(torch.tensor([
        [1.0, -2.0, 0.0, 0.5],
        [-1.0, 3.0, 0.5, 0.0],
        [0.0, 1.0, -1.5, 2.0],
    ]))
model.eval()

# 第 0 维是样本数;每个样本有 4 个输入特征。
inputs = torch.tensor([[1.0, 2.0, 0.0, 1.0],
                       [0.0, 1.0, 2.0, 1.0]], requires_grad=True)
saliency = Saliency(model)

# target=1 让两条样本都解释第二个输出类别。
unsigned = saliency.attribute(inputs, target=1, abs=True)
signed = saliency.attribute(inputs, target=1, abs=False)

# 只比较方向和幅度;结果形状仍与 inputs 相同。
print("unsigned shape:", unsigned.shape)
print("signed:", signed)
print("unsigned:", unsigned)

在这个例子里,signed 会保留类别 1 的权重符号,而 unsigned 会把负值变成正值。两者的形状都是 [2, 4],因为 Saliency 返回的是输入特征梯度,不是类别向量。

什么时候需要保留正负方向

如果你的任务只想排序“哪些输入位置对当前输出变化更敏感”,abs=True 更容易做幅度排序;但它会把“推动目标分数”和“压低目标分数”放在同一条轴上。做规则解释、特征筛选或调试模型偏差时,我更愿意同时保存 signed 结果,再用绝对值做单独的排序字段。

Captum Saliency 带符号梯度与绝对梯度的方向和幅度关系说明图
图2:原创静态说明图,比较 signed gradient 的方向信息与 absolute gradient 的幅度信息;两者不是两次不同的模型预测。

需要注意,梯度只描述当前输入附近的局部变化。一个特征的绝对梯度很大,不等于它在整个数据集上最重要;一个负梯度也不等于该字段“无用”。输入归一化、激活函数饱和、模型输出是 logits 还是概率,都会改变数值的阅读方式。

接入真实模型时保留这张检查表

检查项要确认的内容常见误读
target类别索引或逐样本索引是否对应目标输出把 target 当成输入特征编号
abs是否需要区分促进与抑制方向把绝对梯度当成概率
输入形状第 0 维是否是 batch,多个输入是否对齐以为返回值会带类别维
forward 输出解释的是 logits、概率还是包装后的标量跨输出空间直接比较梯度

多分类场景不要依赖 target=None 自动选择最大类别;官方接口把 target 作为输出索引。若每个样本目标不同,可以传长度等于 batch 的列表或一维张量。若 forward 返回高维输出,则按输出维度传元组索引,先把输出结构和业务类别映射写清楚。

常见问题

abs=True 是不是更准确?

不是。它只是取绝对值,便于观察局部变化幅度;准确性不能由这个开关单独判断。

abs=False 出现负数怎么办?

负数表示在当前输入附近,输入增加与目标输出下降方向相关。它不是报错,也不能单独推出因果关系。

可以把 signed 结果直接跨样本平均吗?

要谨慎。先确认输入尺度、target 和输出空间一致;跨样本平均前最好同时保留均值、绝对值均值与分布信息,否则正负抵消会掩盖局部变化。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>