机场航站楼里,安检员小陈面前有两样东西:一张旅客的登机牌,和一个贴着“AI 核验”标签的机器。最近情报部门警告,有人发明了一种“隐形墨水”——它打印出的登机牌,人眼看上去毫无异样,却能让 AI 核验机把罪犯当成 VIP 放行。这种攻击,AI 领域叫“对抗样本”:给正常的图片、语音或文字加上人类察觉不到的微尘式扰动,模型就会被牵着鼻子走。 小陈的应对策略不是拆掉核验机重造,而是在入口处加设三道安检闸门:第一道“画像比对”,看旅客的行为轨迹是否偏离正常人群(kNN 距离检测);第二道“深层体检”,检查核验机内部器官的运转数据是否协调(激活异常检测);第三道“压缩复核”,把登机牌按不同精度重新扫描,比对结论是否一致(特征 squeeze)。三道闸门独立工作、联合决策,谁也别想轻松蒙混过关。 这就是检测式防御:不修改模型本身,而是给模型配一个“哨兵”,专门识别那些试图欺骗模型的异常输入。这套思想在 AI 安全、金融风控、内容审核等场景中,是保护模型不被恶意攻击的第一道防线。

岗位关联

掌握检测式防御,等于给 AI 系统装上“安检雷达”——这是 AI 安全工程师、算法平台建设者的核心技能之一,也是应对对抗攻击的第一道实用防线。

目录
  1. 可视化演示
  2. 1. 威胁模型:安检情报与敌情假设
  3. 2. kNN距离检测:行为画像比对
  4. 3. 激活异常检测:深层功能体检
  5. 4. 特征压缩检测:多精度复核
  6. 5. 多检测融合:三闸联动判决
  7. 6. 评估与调参:误报与漏放的权衡
  8. 7. 局限与演进:对抗逃逸与持续升级
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示三种检测式防御方法:kNN特征空间距离检测、中间层激活异常监控、特征squeeze位深压缩,对比干净样本与对抗样本的检测过程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

kNN特征空间距离检测 粉色:干净样本特征分布 红色:对抗样本偏离流形 黄色:k近邻与距离阈值 score=avg(d(x,xi)), i=1..k 对抗样本在特征空间中远离干净样本的自然流形

1. 威胁模型:安检情报与敌情假设

机场安检的第一原则是什么?先搞清楚“敌人长什么样”。小陈开动员会时,屏幕上放着一张制作工艺完美的登机牌:纸张、水印、钢印全都有,唯独 AI 核验机读出的身份代码与真人不符。原来攻击者用了一种“隐形墨水”——对图片来说,就是在每个像素上叠加一层极微弱的变化,人眼根本分辨不出,但模型的内部计算却被彻底带偏。学术上把这种被精心修改过的输入叫“对抗样本”,那层微弱变化叫“对抗扰动”。

检测式防御的定位很明确:它不改动模型的任何参数,而是在模型前方加一个“安检台”。模型该怎么做预测还怎么做,安检台只负责回答一个问题:“这份输入,是正常的,还是被改造过的?”这与对抗训练(把模型本身练得更皮实)是两条互补的路线。在实际威胁建模中,还要区分攻击者的“能力等级”:灰盒攻击者知道模型的输出但不知道安检细节;白盒攻击者甚至连安检台的代码都拿到手了——这意味着检测方案不能依赖“敌人不知道我在查什么”这种侥幸。

对抗样本的数学定义非常简洁,但每一处都是攻防博弈的浓缩:

情报决定了安检的等级。知道了攻击者用的是“隐形墨水”、且扰动被限制在极小范围,小陈就能反推出一个关键事实:对抗样本虽然表面正常,但它在“特征空间”里的位置一定和正常样本不一样——这正是后面三道闸门的理论基石。

x~=x+δ,∥δ∥∞≤ϵ\displaystyle \tilde{x} = x + \delta, \qquad \|\delta\|_{\infty} \le \epsilon
意思是:对抗样本等于干净样本加一个扰动,且扰动在“无穷范数”意义下被限制在极小的口袋里——人类察觉不到,模型却会上当。
  1. 干净样本$x$ 是模型原本能正确识别的原始输入,相当于一张没有涂改的登机牌。
    x:干净输入\displaystyle x: \text{干净输入}
  2. 扰动向量$\delta$ 是要叠加在每个像素位置上的微小改动,相当于隐形墨水的墨点。
    δ:微小的扰动向量\displaystyle \delta: \text{微小的扰动向量}
  3. 无穷范数约束$\|\delta\|_{\infty} \le \epsilon$ 表示所有维度上改动幅度都不超过 $\epsilon$,整张图片被严格限制在“人眼无感”的量级。
    ∥δ∥∞=max⁡i∣δi∣≤ϵ\displaystyle \|\delta\|_{\infty} = \max_i |\delta_i| \le \epsilon
  4. 对抗样本合成$\tilde{x}$ 是叠完“墨水”后的最终输入,它看起来正常,骗得过人眼,却能引着模型走向错误的分类。
    x~=x+δ\displaystyle \tilde{x} = x + \delta

2. kNN距离检测:行为画像比对

机场公安给每位合法旅客建了一份“行为画像”:他们的排队位置、候机区域、行进路线总在某一团区域里打转,很少有人独自杵在航站楼角落一动不动。小陈的第一道闸门,就是把这个直觉算法化:如果一个可疑样本在“特征空间”中离所有正常样本都太远,那它就别想上飞机。

这里的关键假设叫“流形假设”:正常数据虽然看上去千变万化,但在高维特征空间里,它们其实聚集在一片低维的、连续的“流形”上,像面粉撒在案板上形成的那条面带。而对抗样本为了让模型出错,必须偏离这条面带,跑进案板边缘的犄角旮旯。kNN 检测就是量一量这个“偏离度”——计算可疑样本到它最近的 $k$ 个正常样本的平均距离,距离越大越可疑。

实现时有两个细节决定成败。一个是 $k$ 的选取:$k$ 太小,单个噪声点就能造成误判;$k$ 太大,邻域被拉宽,局部偏离被平均掉。另一个是距离度量:最常用欧氏距离,但特征尺度差异大时需先做标准化。kNN 分类器大家都熟,但把它反过来用——不看“多数票”,只看“有多远”——就成了一件检测对抗样本的利器。

画像比对这道闸门思路直观,但它有个天生短板:如果航站楼里旅客本来就三五成群、人群分散,或者特征维度太高、空间过于稀疏,那么“离群”这件事本身就很难定义——这也为后面的体检和复核闸门留出了舞台。

dk(x)=1k∑i=1k∥x−x(i)∥2\displaystyle d_k(x) = \frac{1}{k} \sum_{i=1}^{k} \| x - x_{(i)} \|_2
这是“离群分数”:把可疑样本 $x$ 到最近的 $k$ 个正常样本的欧氏距离取平均,分数越高,说明它离正常人群越远。
  1. 距离度量$\| x - x_{(i)} \|_2$ 计算 $x$ 与第 $i$ 个最近邻的欧氏距离,相当于用尺子量两个人座位的直线距离。
    ∥x−x(i)∥2=∑j(xj−x(i),j)2\displaystyle \| x - x_{(i)} \|_2 = \sqrt{\sum_j (x_j - x_{(i),j})^2}
  2. 排序取近邻把所有正常样本按距离从小到大排序,选出前 $k$ 个,记作 $x_{(1)}, x_{(2)}, \dots, x_{(k)}$。
    x(1),x(2),…,x(k):距离最近的 k 个样本\displaystyle x_{(1)}, x_{(2)}, \ldots, x_{(k)}: \text{距离最近的 } k \text{ 个样本}
  3. 平均距离$\frac{1}{k}\sum_{i=1}^{k}$ 把 $k$ 个距离加起来除以 $k$,得到“平均离群度”,避免个别近邻干扰。
    1k∑i=1k∥x−x(i)∥2\displaystyle \frac{1}{k} \sum_{i=1}^{k} \| x - x_{(i)} \|_2
  4. 阈值比对若 $d_k(x) > \tau$,就判定 $x$ 偏离了正常流形,安检闸门拉响警报。
    dk(x)>τ⇒对抗样本\displaystyle d_k(x) > \tau \Rightarrow \text{对抗样本}

3. 激活异常检测:深层功能体检

笑容满面的人不一定健康。小陈的第二道闸门,灵感来自体检科医生:表面症状(比如体温)可以伪装,但内脏器官的功能数据骗不了人。换到神经网络里,“表面症状”就是模型最后输出的 softmax 置信度——很多对抗样本的置信度高得惊人,模型不仅分错,还分得“信心满满”。所以只查输出层完全不够。

真正藏得住秘密的是中间层。当输入流经神经网络的隐藏层时,每一层都会产出一个激活向量,它像一份“体检报告”,记录着模型从输入中提取到的各种特征线索。正常的“猫”图片和对抗的“猫”图片,虽然在输出层都给出类似的高置信度,但中间层激活的分布模式却会出现系统性偏差。激活异常检测正是抓这个偏差。

怎么量化偏差?最经典的做法是“分布距离”:预先收集一批正常样本的中间层激活,估出它们的均值 $\mu$ 和协方差 $\Sigma$,然后用马氏距离度量新样本的激活与这个正常分布有多远。马氏距离和欧氏距离最大的区别是它考虑了特征之间的相关性——就像体检判断“血压高但心率低”这种组合异常时,不能只看单项指标。

除了马氏距离,研究者还提出过 LID(局部内在维度)等方法:对抗样本往往落在正常流形的高维“空洞”里,LID 会算出该局部区域的有效维度,维度越高越诡异。体检式检测的代价是每次都要做一遍前向传播并取出中间层,计算开销比画像比对更大,但它能发现“表面一切正常、内里全是问题”的隐蔽攻击。

M(z)=(z−μ)⊤Σ−1(z−μ)\displaystyle M(z) = \sqrt{(z - \mu)^\top \Sigma^{-1} (z - \mu)}
马氏距离把“多维指标的组合偏离”压缩成一个分数:$z$ 是可疑输入的中间层激活,$\mu$ 和 $\Sigma$ 是正常激活的均值与协方差,分数越大,内部器官越“不协调”。
  1. 中间层激活$z$ 是输入经过某隐藏层后得到的激活向量,相当于一份多维体检指标。
    z∈Rd:中间层激活向量\displaystyle z \in \mathbb{R}^d: \text{中间层激活向量}
  2. 正常分布参数$\mu$ 是正常样本激活的均值向量,$\Sigma$ 是协方差矩阵,刻画了各指标间的联动关系。
    μ=1n∑izi,Σ=1n∑i(zi−μ)(zi−μ)⊤\displaystyle \mu = \frac{1}{n}\sum_i z_i, \quad \Sigma = \frac{1}{n}\sum_i (z_i-\mu)(z_i-\mu)^\top
  3. 偏差向量$z - \mu$ 算出每项指标偏离正常水平的幅度与方向。
    z−μ=[z1−μ1⋮zd−μd]\displaystyle z - \mu = \begin{bmatrix} z_1-\mu_1 \\ \vdots \\ z_d-\mu_d \end{bmatrix}
  4. 协方差逆加权$\Sigma^{-1}$ 对偏差做“白化”,把相关性强的指标去冗余,使距离计算落在标准化后的空间里。
    (z−μ)⊤Σ−1(z−μ)\displaystyle (z-\mu)^\top \Sigma^{-1}(z-\mu)
  5. 开方得距离整体开根号后得到马氏距离,$M(z)$ 超过阈值即判为激活异常。
    M(z)=⋯>τ⇒异常激活\displaystyle M(z) = \sqrt{\cdots} > \tau \Rightarrow \text{异常激活}

4. 特征压缩检测:多精度复核

小陈从老安检员那里学来一招土办法:遇到拿不准的登机牌,就用复印机压一档灰度重新打一份,再让 AI 核验机读一遍。如果两份结论对不上,那这份登机牌八成有鬼。这招在学术界的名字叫“特征 squeeze”(特征压缩),它的思路朴素却有效:对抗扰动是“隐形墨水”,而任何压缩操作都会或多或少地破坏这些墨水痕迹。

什么是“压缩”?就是把输入变“糙”一点。常用的压缩算子有三种:一是降低颜色深度,把原本 256 级灰度压到 8 级甚至 4 级,相当于把彩色照片打成黑白复印件;二是中值滤波,把每个像素替换成邻域像素的中位数,像拿刷子把图像表面“抹平”;三是均值滤波,做局部平均。无论哪种,目标都是“擦掉”那些微小到人类无感的扰动。

检测流程分三步走。第一步,把原始输入 $x$ 分别送入压缩算子,得到压缩版本 $\mathcal{S}(x)$。第二步,让模型分别对原始输入和压缩输入做推理,得到两组预测向量(logits)。第三步,比较两组向量的差异——如果差异超过阈值,说明原始输入里藏着一层“压缩即消失”的扰动,而这正是对抗样本的典型特征。它的最大优点是无需训练额外模型,直接复用现有模型的推理结果即可。

压缩复核的代价不是零:压得太狠,正常样本也会因为信息丢失而改变预测,造成误报;压得太轻,又擦不掉攻击者的扰动。所以实际部署时,通常会把压缩强度当作一个超参数,在“擦除能力”和“误伤率”之间小心权衡。小陈把这个权衡记在小本子上:安检的本质,就是不停地在“抓得细”与“误伤多”之间走钢丝。

Δ(x)=∥f(x)−f(S(x))∥1>τ\displaystyle \Delta(x) = \| f(x) - f(\mathcal{S}(x)) \|_1 > \tau
含义:将原始输入与压缩后输入分别送入模型,若输出向量的一范数差异超过阈值,就认定原始输入被注入了对抗扰动。
  1. 压缩算子$\mathcal{S}(\cdot)$ 表示对输入做某种“降精度”处理,如色深量化或中值滤波。
    S(x):压缩后的输入\displaystyle \mathcal{S}(x): \text{压缩后的输入}
  2. 双路推理$f(x)$ 是模型对原始输入的预测,$f(\mathcal{S}(x))$ 是模型对压缩版本的预测,两者像两份独立扫描报告。
    f(x),f(S(x))\displaystyle f(x), \quad f(\mathcal{S}(x))
  3. 一范数差异$\| \cdot \|_1$ 把两份报告逐元素相减再取绝对值求和,度量两份报告的总体分歧程度。
    ∥f(x)−f(S(x))∥1=∑j∣fj(x)−fj(S(x))∣\displaystyle \| f(x) - f(\mathcal{S}(x)) \|_1 = \sum_j | f_j(x) - f_j(\mathcal{S}(x)) |
  4. 阈值判定$\Delta(x) > \tau$ 时报警——正常输入被压缩后结论基本不变,只有“隐形墨水”才会让两份报告突然分道扬镳。
    Δ(x)>τ⇒原始输入可疑\displaystyle \Delta(x) > \tau \Rightarrow \text{原始输入可疑}

5. 多检测融合:三闸联动判决

三道闸门单独看,各有各的软肋:画像比对怕“人群本来就散”的数据集,深层体检怕计算开销大的场景,压缩复核怕压缩参数调不好。小陈的经验是:别让任何一道闸门单独拍板,把它们的结果汇总起来,搞一个“联合判定委员会”。这正是检测式防御在工程落地时的重要一步——多检测器融合。

融合的第一步是“归一化”。三个检测器输出的分数量纲完全不同:kNN 给的是距离,马氏距离给的是开根号后的散布程度,squeeze 给的是范数差异。直接相加毫无意义,必须先把每个分数映射到统一的尺度上。常用做法是用正常样本的分数分布做标准变换:把“正常样本的 95 分位”作为该检测器的报警阈值,然后将实际分数除以阈值,得到一个大于 1 就报警的“异常比”。

第二步是“加权求和”。不同检测器在不同攻击类型上的灵敏度不一样,需要给它们分配权重。比如在图像任务上,squeeze 对 FGSM 这类强扰动特别敏感,kNN 对 CW 这类精心优化过的攻击更有效。权重可以由验证集上的表现来标定:哪个检测器在该场景下 AUC 高,就给哪个更大的话语权。

除了加权求和,实践中还可以用“逻辑或”规则:任何一个检测器强烈报警就拦截,适合安全要求极高的场景;或者用“逻辑与”:所有检测器都报警才拦截,适合误报成本极高的场景。融合的价值不在于“每个检测器都完美”,而在于它们各自的盲区在统计上不重叠——一个人眼看不出的破绽,总有一道闸门能嗅到气味。

s(x)=∑j=1mwj s^j(x),∑j=1mwj=1\displaystyle s(x) = \sum_{j=1}^{m} w_j \, \hat{s}_j(x), \qquad \sum_{j=1}^{m} w_j = 1
公式表达“N 个检测器联合打分”:每个检测器给出归一化后的分数 $\hat{s}_j$,乘上权重 $w_j$ 再加总,最终分数超过阈值即拒绝该输入。
  1. 单检测器分数$\hat{s}_j(x)$ 是第 $j$ 个检测器对输入 $x$ 给出的归一化异常分数,取值通常在 0 到 1 之间。
    s^j(x)∈[0,1]\displaystyle \hat{s}_j(x) \in [0,1]
  2. 权重系数$w_j$ 表示第 $j$ 个检测器在最终决策中的话语权,所有权重之和为 1。
    wj≥0,∑j=1mwj=1\displaystyle w_j \ge 0, \quad \sum_{j=1}^{m} w_j = 1
  3. 加权求和$\sum_{j=1}^{m} w_j \hat{s}_j(x)$ 把所有检测意见按重要性加权汇总,得到一个综合嫌疑分。
    s(x)=∑j=1mwjs^j(x)\displaystyle s(x) = \sum_{j=1}^{m} w_j \hat{s}_j(x)
  4. 最终判定综合分 $s(x)$ 超过阈值时触发拦截,否则放行——三门闸门互相补位,盲区被显著压缩。
    s(x)>τ⇒拒绝输入\displaystyle s(x) > \tau \Rightarrow \text{拒绝输入}

6. 评估与调参:误报与漏放的权衡

安检系统的体检报告怎么写?小陈手里有一张四格表:被拦下的旅客里,有多少是真正的危险分子(真阳性 TP),有多少是被冤枉的好人(假阳性 FP);被放行的旅客里,有多少安全通过(真阴性 TN),有多少漏网之鱼(假阴性 FN)。这张表就叫做“混淆矩阵”,是一切检测系统评估的地基。

从混淆矩阵可以导出两个最核心的指标。真正例率 TPR,也叫召回率,衡量的是“所有危险分子中有多少被拦住”——这个指标太低,漏网之鱼就会登机。假正例率 FPR,衡量的是“所有正常旅客中有多少被冤枉”——这个指标太高,航站楼就会排起长队、投诉不断。这两者在阈值移动时此消彼长:阈值调严,TPR 上升但 FPR 也跟着涨;阈值调松,误报少了,漏放又多了。

把不同阈值下的 (FPR, TPR) 点连成一条曲线,就是大名鼎鼎的 ROC 曲线。曲线越靠近左上角,说明检测器在“尽量多抓”和“尽量少冤”之间兼顾得越好;曲线下的面积 AUC 则是一个与阈值无关的综合性指标。小陈的实战经验是:选阈值不能只看 AUC,还要结合业务场景——反欺诈场景宁可误报高一点(选高 TPR 的点),内容审核场景则要控制误伤(选低 FPR 的点)。

评估不只是上线前做一次就完事。对抗攻击的手段在进化,正常数据的分布也在漂移,所以小陈的团队每两周就会重跑一次 ROC 评估,用最新收集的对抗样本更新阈值。检测系统不是一锤子买卖,而是持续校准的“动态安检预案”。

TPR=TPTP+FN,FPR=FPFP+TN\displaystyle TPR = \frac{TP}{TP + FN}, \qquad FPR = \frac{FP}{FP + TN}
TPR 是“真正的坏样本中被抓住的比例”,FPR 是“正常样本中被冤枉的比例”。调阈值就是在这两个指标之间寻找平衡点。
  1. 混淆矩阵元素$TP$ 是正确拦截的对抗样本,$FN$ 是漏网的对抗样本,$FP$ 是被误伤的正常样本,$TN$ 是正常放行的样本。
    TP,FN,FP,TN:四类判定结果\displaystyle TP, FN, FP, TN: \text{四类判定结果}
  2. 真正例率$TPR = \frac{TP}{TP+FN}$,分母是所有“真实攻击”,分子是“被抓到的攻击”,体现抓坏人的能力。
    TPR=TPTP+FN∈[0,1]\displaystyle TPR = \frac{TP}{TP+FN} \in [0,1]
  3. 假正例率$FPR = \frac{FP}{FP+TN}$,分母是所有“正常样本”,分子是“被冤枉的正常样本”,体现误伤程度。
    FPR=FPFP+TN∈[0,1]\displaystyle FPR = \frac{FP}{FP+TN} \in [0,1]
  4. 阈值调节增大阈值使两者同时下降,减小阈值使两者同时上升;ROC 曲线正是遍历所有阈值画出的轨迹。
    τ↑⇒TPR↓,FPR↓\displaystyle \tau \uparrow \Rightarrow TPR \downarrow, FPR \downarrow

7. 局限与演进:对抗逃逸与持续升级

小陈很快发现,最让他头疼的不是普通的伪造者,而是“懂安检手册的伪造者”。白盒攻击者知道检测器的全部细节,他们会在生成对抗样本的优化过程中,额外加入一项“逃逸损失”:不仅要让模型分错,还要让样本在 kNN 距离、马氏距离、squeeze 差异这三项指标上都表现得像正常样本。这是检测式防御最严峻的挑战——自适应攻击。

为什么难防?因为检测器和攻击者玩的是“猫鼠游戏”:一旦检测规则被写死,攻击者就可以把规则当作优化目标的一部分,让扰动沿着“检测分数最低”的方向迭代。更麻烦的是,检测器本身也是神经网络或距离计算,攻击者可以把梯度一路传回输入,精确地算出“怎么做才能骗过安检”。静态的检测阈值在这种攻击面前,会从“铜墙铁壁”退化成“纸糊的窗户”。

对策有三条主线。第一,让检测器“动起来”:定期在最新攻击样本上重训检测器,或引入随机化组件,让攻击者无法稳定估计梯度。第二,与对抗训练协同:既然检测器防不住所有攻击,就让模型本身也参与防御,双管齐下。第三,引入红队演练:让专门的攻击团队持续尝试绕过安检,失败案例反哺检测器迭代。这三条线对应着一个共同思想——检测式防御不是一次性部署,而是持续的攻防演练。

回到航站楼。小陈把三道闸门的故事讲给新来的同事听,最后总不忘补一句:“安检永远没有终点。”攻击者在研究手册,检测者就要研究攻击者的研究。今天有效的检测规则,明天可能就被写进攻击者的损失函数;但只要检测器持续进化、与对抗训练协同作战,防线就能始终领先半步——这正是 AI 安全攻防最真实的常态。

min⁡δ  Ladv(x+δ,yt)+λ⋅gdet(x+δ)\displaystyle \min_{\delta} \; \mathcal{L}_{\mathrm{adv}}(x+\delta, y_t) + \lambda \cdot g_{\mathrm{det}}(x+\delta)
这是自适应攻击者的目标函数:第一项让模型把样本错分成目标类别,第二项让检测器的异常分数被压低,两者合力,攻击者就能得到“既骗过模型、又骗过安检”的样本。
  1. 主攻击目标$\mathcal{L}_{\mathrm{adv}}(x+\delta, y_t)$ 是让模型把对抗样本错分成目标类别 $y_t$ 的分类损失。
    Ladv(x+δ,yt)→min⁡\displaystyle \mathcal{L}_{\mathrm{adv}}(x+\delta, y_t) \to \min
  2. 逃逸项$g_{\mathrm{det}}(x+\delta)$ 是检测器给出的异常分数,攻击者希望它越小越好。
    gdet(x+δ)→0\displaystyle g_{\mathrm{det}}(x+\delta) \to 0
  3. 平衡系数$\lambda$ 权衡“骗过模型”与“骗过检测器”两个目标,太大则攻击成功率下降,太小则会被安检拦下。
    λ>0:逃逸强度\displaystyle \lambda > 0: \text{逃逸强度}
  4. 联合优化攻击者对 $\delta$ 求梯度并迭代更新,最终得到一枚“隐形墨水更隐形”的对抗样本。
    δ←δ−η∇δ[Ladv+λgdet]\displaystyle \delta \leftarrow \delta - \eta \nabla_\delta \left[ \mathcal{L}_{\mathrm{adv}} + \lambda g_{\mathrm{det}} \right]

AI 应用场景

云端 API 滥用拦截

阶段:模型上线后的运行时防护

解决的问题:企业将图像分类、人脸识别等模型封装成 API 对外提供后,攻击者会故意构造对抗样本来探测模型边界,传统日志审计只能事后发现,无法实时拦截。kNN 检测器基于正常业务请求的特征流形建立画像,一旦请求偏离正常分布,就在到达模型前被拦下,既保护了模型不被逆向,也减少了恶意调用对算力的消耗。

具体案例:某金融科技公司的证件识别 API 曾遭到批量对抗扰动攻击,攻击者通过修改身份证照片的微小纹理骗取识别结果。安全团队在原有网关后加装 kNN 距离检测器,以“证件类型 + 图像统计特征”构建特征空间,异常请求在毫秒级内被标记并返回人工审核,攻击成功率由 37% 降至 4% 以下。

自动驾驶视觉输入的实时骚乱筛查

阶段:端侧推理前的输入预检

解决的问题:自动驾驶车辆依赖摄像头感知路面,攻击者可能在路牌上张贴对抗贴纸,让模型把“停止”识别成“限速”。特征 squeeze 检测不需要额外训练模型,只需对摄像头帧做一次色深量化与中值滤波,再比较两次推理的差异,非常适合车载芯片的算力约束。

具体案例:某自动驾驶方案商在感知模块前串联特征 squeeze 检测:对每帧图像分别用 256 级和 8 级色深做推理,若两者预测结果不一致,系统判定该帧可疑,自动切换至保守驾驶策略并上报云端复核。路测中成功拦截了 90% 以上的贴纸类攻击。

大模型输入提示注入探测

阶段:大模型推理入口的安全网关

解决的问题:大语言模型面临提示注入攻击:攻击者把恶意指令藏在用户输入中,让模型偏离安全对齐。这类攻击的语义与正常输入差异极小,但会引发模型中间层激活的异常偏移。激活异常检测通过抽取正常对话的中间层激活分布,用马氏距离识别“表面通顺、内里异常”的输入。

具体案例:某 To B 大模型服务商为客服机器人加装激活异常检测器:对每个用户 prompt 抽取倒数第二层隐藏状态,用一周正常流量数据标定均值与协方差,马氏距离超过阈值时触发二次审查。上线后,针对其系统的提示注入攻击发现率提升至 82%,误报率控制在 3% 以内。

Python 演示

python56 行
import numpy as np  def build_normal_samples(n=120, seed=42):    """生成正常样本的特征点云, 模拟合法请求在特征空间中的分布."""    rng = np.random.default_rng(seed)    return rng.multivariate_normal(        [3.0, 3.0, 0.5],        [[0.8, 0.2, 0.0], [0.2, 0.8, 0.0], [0.0, 0.0, 0.05]],        size=n,    )  def knn_score(x, samples, k=8):    """kNN 离群分数: 与 k 个最近邻的平均欧氏距离."""    dists = np.linalg.norm(samples - x, axis=1)    return float(np.sort(dists)[:k].mean())  def quantize(x, bits=4):    """颜色深度量化: 将连续值压缩到 2**bits 个离散等级."""    levels = 2 ** bits    return np.round(x * levels) / levels  def model_logits(x):    """模拟一个对第三维(颜色通道)极其敏感的线性模型."""    return np.array([0.1 * x[0] + 0.1 * x[1] + 2.0 * x[2]])  def squeeze_score(x, bits=4):    """特征压缩检测: 原始输入与量化输入预测结果的差异."""    qx = quantize(x, bits)    return float(np.abs(model_logits(x) - model_logits(qx)).sum())  def detect_combined(x, samples, k=8, tau_knn=2.5, tau_sq=0.050):    """组合检测: kNN 与 squeeze 任一报警即判为对抗样本."""    sknn = knn_score(x, samples, k)    ssq = squeeze_score(x)    flag = (sknn > tau_knn) or (ssq > tau_sq)    return flag, sknn, ssq  def main():    normal = build_normal_samples()    x_clean = np.array([3.2, 3.1, 0.52])    x_adv = np.array([2.3, 3.8, 0.59])     for name, x in [("clean", x_clean), ("attack", x_adv)]:        flag, sk, sq = detect_combined(x, normal)        print(f"{name}: knn={sk:.4f}, squeeze={sq:.5f}, detected={flag}")  if __name__ == "__main__":    main()
目的:用 numpy 实现一个轻量级组合检测器,演示 kNN 离群检测与特征 squeeze 检测如何协同识别对抗样本。
  1. samples - x广播计算待检样本与所有正常样本的坐标差,一次得到整个距离矩阵。
  2. np.linalg.norm(..., axis=1)对每个正常样本求欧氏距离,得到一维距离数组。
  3. np.sort(dists)[:k].mean()排序后取前 k 个最近邻并求平均,就是 kNN 离群分数。
  4. np.round(x * levels) / levels先把坐标放大到量化等级再取整回来,模拟“降低颜色深度”的复印效果。
  5. model_logits刻意让权重对第三维(模拟颜色通道)更敏感,使 squeeze 对微小扰动更灵敏。
  6. flag = (sknn > tau_knn) or (ssq > tau_sq)任一检测器报警即拦截,体现“逻辑或”的保守融合策略。
  7. tau_knn=2.5, tau_sq=0.050阈值需要预先用正常样本分布标定,不能拍脑袋指定。

常见误区

误区对抗样本就是把模型“搞糊涂”的输入,所以它们的 softmax 置信度一定很低,只要看输出概率就能识别出来。

正解恰恰相反,许多经典对抗攻击(如 CW 攻击)会显式约束“目标类别的置信度要足够高”,生成出的对抗样本不仅分错,而且分得自信满满。真正可靠的异常信号藏在中间层激活分布里,而不是最后一层的概率输出上。就像体检时,病人可以强撑笑容,但血液指标骗不了人。

为何常见:人们习惯用“模型的最终答案”来理解模型行为,忽视了中间层才保留着更丰富的结构信息,因此会误以为“置信度低”是异常的唯一信号。

误区kNN 距离检测听上去很通用,无论什么任务,只要算一下待检样本到正常样本的平均距离,就能抓出对抗样本。

正解kNN 检测的生命线是“流形假设”——正常样本必须真的聚集在低维流形上。如果特征空间本身高维稀疏,或者同类样本天然分散成多个簇,那么“离群”的定义就会失真:正常样本可能彼此距离很远,对抗样本反而落在人群中间。部署前必须先用可视化或密度估计检验数据是否满足流形假设。

为何常见:kNN 分类器在教科书上太经典,容易让人误以为“最近邻距离”是普适的异常度量,忽略了它背后的几何假设同样苛刻。

误区压缩操作只是把图片变模糊一点,正常图片经过压缩后模型预测应该不变,所以 squeeze 检测的误报率应该是零。

正解压缩本质上是有损的。一张正常但对比度极低、纹理细腻的图片,被量化或滤波后可能真的改变模型预测,从而被误判为对抗样本。squeeze 检测需要在“擦除扰动”和“保留正常信息”之间做权衡,压缩强度是必须仔细标定的超参数,误报率通常无法做到零。

为何常见:人们容易把“压缩”想成无损的简单缩放,忽略了它和信息损失之间的联系,从而低估了误报风险。

误区既然单一检测器有盲区,那我堆上十几个检测器,总该固若金汤了吧?

正解检测器融合的效果取决于盲区是否互补,而不是数量多少。如果所有检测器都建立在同一个特征层、使用同一种距离度量,那么它们会被同一种自适应攻击一次性全部绕过。此外,每个检测器都会带来延迟与算力开销,在实时场景中,“三个互补检测器”往往优于“十个同质检测器”。

为何常见:直觉上认为“量变引起质变”,但网络安全领域的木桶效应是“短板决定水位”——同质化的检测器再多,也只是把同一块短板加高了几次。

误区有了检测器拦在模型前面,模型本身再脆弱也没关系——不训练也能防攻击。

正解检测式防御应对的是“已知威胁模式下的异常偏离”,而白盒自适应攻击可以把检测器的评分函数纳入优化目标,生成“既不偏离流形、也不触发压缩差异”的样本。只有让模型自身通过对抗训练变得稳健,再与检测器协同,才能形成“即使扰动逃过安检,也无法让模型犯错”的双保险。

为何常见:人们倾向于寻找“一次安装、永久生效”的方案,低估了对抗攻击是一个不断进化的动态博弈过程。

面试题

Q1. 对抗样本的本质是什么?

单选题 · easy

  • A.随机噪声破坏图像
  • B.微小扰动误导模型← 正确答案
  • C.更换数据集再训练
  • D.大幅修改图片内容

答案:B。对抗样本是在干净输入上叠加人类难以察觉的微小扰动,使模型产生错误预测,对应公式 $\tilde{x} = x + \delta$。随机噪声不具针对性,“更换数据集”和“大幅修改内容”都与对抗样本“扰动受限”的定义不符。

Q2. kNN 检测式防御的核心假设是?

单选题 · mid

  • A.正常样本均匀随机分布
  • B.正常样本呈高维稀疏状
  • C.正常样本聚集在低维流形← 正确答案
  • D.正常样本与标签完全无关

答案:C。kNN 检测依赖流形假设——正常样本在特征空间里聚集在低维流形附近,而对抗样本为了误导模型会偏离该流形,从而被较大的近邻距离暴露。均匀随机分布、高维稀疏都会让“离群”失去意义。

Q3. 下列哪些属于检测式防御的典型方法?

多选题 · mid

  • A.kNN 邻域距离检测← 正确答案
  • B.中间层激活异常检测← 正确答案
  • C.特征压缩一致性复核← 正确答案
  • D.梯度裁剪压缩模型

答案:ABC。kNN 检测、激活异常检测、特征 squeeze 分别对应文章中的三道“安检闸门”。梯度裁剪是训练阶段的稳定性手段,目的是防止梯度爆炸,与“检测输入是否异常”无关。

Q4. 特征 squeeze 检测通常会使用哪种压缩算子?

单选题 · easy

  • A.降低颜色深度← 正确答案
  • B.增加图像尺寸
  • C.提升对比强度
  • D.旋转图像角度

答案:A。特征 squeeze 通过量化色深、中值滤波等有损操作擦除对抗扰动。增加尺寸、提升对比度、旋转角度都不是以“降精度”为目的的压缩操作,无法有效抹掉隐形墨水。

Q5. 为什么激活异常检测要使用中间层特征而非 softmax 输出?

单选题 · hard

  • A.中间层特征维度更低
  • B.中间层保留丰富结构信息← 正确答案
  • C.中间层完全不包含噪声
  • D.中间层计算速度更快

答案:B。对抗攻击可以显式约束输出层的高置信度,因此 softmax 给出的“信心”不可靠;而中间层激活向量保留了模型提取到的更丰富、更底层的结构信息,对抗样本要在所有中间层都伪装得天衣无缝,难度远高于伪装一个输出标量。

Q6. 多检测器加权融合的主要收益是什么?

单选题 · mid

  • A.消除全部误报
  • B.覆盖各检测器盲区← 正确答案
  • C.加快模型推理速度
  • D.降低标注数据成本

答案:B。不同检测器对不同类型的攻击灵敏度不同,融合能让它们的盲区互补,使综合决策更稳健。融合不会消除全部误报,也不会改变推理速度或数据标注成本。

Q7. 在 ROC 曲线中,曲线越靠近左上角说明什么?

单选题 · mid

  • A.误报率很高
  • B.检测器性能越优异← 正确答案
  • C.模型精度偏低
  • D.训练数据明显不足

答案:B。左上角对应 FPR 低、TPR 高的区域,即“漏放少、误伤也少”,是检测器性能优异的标志。ROC 曲线下方的面积 AUC 正是对这种优劣的定量刻画。

Q8. 对抗扰动通常被限制在什么范围?

单选题 · easy

  • A.任意大小的像素修改
  • B.人类难以察觉的微小幅度← 正确答案
  • C.完全随机的高斯噪声
  • D.整体图像的亮度调整

答案:B。对抗样本的威胁恰恰在于“人眼无感、模型有感”,扰动通常用无穷范数约束在 $\epsilon$ 之内。任意修改或整图调亮度要么会被发现,要么不属于精准对抗扰动。

Q9. 白盒自适应攻击为何能绕过检测式防御?

多选题 · hard

  • A.攻击者知晓检测器结构← 正确答案
  • B.优化时加入逃逸损失← 正确答案
  • C.将扰动投放到检测盲区← 正确答案
  • D.直接删除检测模块

答案:ABC。白盒攻击者掌握检测器细节后,可把检测器评分函数当作优化目标的一部分(逃逸损失),将扰动定向推入检测器的盲区。“删除检测模块”是对系统物理层面的破坏,不属于对抗样本生成范畴。

Q10. 构建生产级检测系统时需要重点关注哪些环节?

多选题 · mid

  • A.用验证集标定检测阈值← 正确答案
  • B.权衡误报与漏放的代价← 正确答案
  • C.定期进行红队对抗演练← 正确答案
  • D.只追求单次离线测试精度

答案:ABC。生产级系统讲究阈值校准、误报/漏放代价权衡、以及持续的红队演练来对抗攻击进化。只追求单次离线精度而忽视长期对抗迭代,会使检测器在真实攻击面前迅速失效。