🧠 第十章 交通与智驾:构建安全高效出行解决方案
📄 一句话概括

400 张合成标志图,干净数据 100%。 一场雾(乘 0.45 加 0.40)打到 25%,过曝 2 倍打到 50%,3×3 模糊打到 31.2%。 训练时补上噪声和雾之后, 雾回到 100%,但过曝一个点没动(50.0%→50.0%)、模糊只挪了 4.5 个点。

📝 本节和前面几节的关系

上一节讲数据能不能用。 这一节讲模型: 同一个模型,晴天 100 分,起雾 25 分——这种落差在实验室里看不出来,在路上会要命。

一、鲁棒性不是一个数,是一组数

「这个模型很鲁棒」这句话没有信息量,因为它没说「对什么鲁棒」。正确的说法是: 在某一组扰动下,准确率从 A 掉到 B。 所以第一步是列扰动清单。 对交通视觉模型来说,常见的六类是: 噪声(传感器)、雾/雨(散射)、过曝/逆光(饱和)、运动模糊(曝光时间)、遮挡、对抗纹理。 这六类对特征的影响机制完全不同,所以它们不会一起好、一起坏。 用一个总体数字概括,等于把六件事混成一件。

二、五类扰动,掉法各不相同

Demo 用四种几何基元合成 400 张 32×32 的「标志图」,提五个特征(横/竖/斜梯度能量、均值、 标准差),训练 softmax 回归,然后在七种输入上测:

扰动 原始训练 增强后
干净 100.0% 99.8%
噪声 0.10 87.5% 99.0%
噪声 0.25 75.2% 83.8%
雾(压对比度) 25.0% 100.0%
过曝 2 倍 50.0% 50.0%
3×3 模糊 31.2% 35.8%
棋盘纹理 0.06 95.5% 100.0%
雾最狠:100% 掉到 25%。因为「乘 0.45 加 0.40」把对比度压掉一半多,
梯度能量整体塌下来,四类之间那点差别也被压平了。
过曝掉一半(50%)。 亮的被削成纯白,
条纹对比一起消失——这类损失是「信息被裁掉」,不是「被噪声淹没」。
3×3 模糊掉到 31.2%。 高频条纹被均值抹平,横竖两类直接糊成一片。
只有棋盘纹理几乎不掉(95.5%)——它是加性的高频,没有改变原有的梯度结构,只是叠了一层。

三、增强只能覆盖你加进去的那几类

右边那一列是在「干净 + 噪声 0.10 + 雾」上重训的结果: 雾从 25.0% 回到 100%,噪声两行也涨了(87.5→99.0、75.2→83.8)。 这就是「增强对路」的样子:补了哪一类,那一类就回来。 但过曝只挪了 +0.0 个点,模糊只挪了 +4.5 个点——跟雾那 +75.0 个点比,等于没动。 因为训练集里根本没出现过这两类。这一条应该记牢: 数据增强不是「让模型更鲁棒」,是「让模型在你补的那几类上更鲁棒」。 所以工程上的顺序是:先列扰动清单,再按清单补增强,最后按清单报每一类的指标。 跳过第一步直接加增强,是最常见的白干。

四、为什么对抗类最难防

表里棋盘纹理那一行很特殊:原始训练 95.5%,增强后反而 100%。这次没出问题, 但这类扰动才是真正难防的。 因为它不是「自然界的坏天气」,是「有人特意构造的」。自然扰动(雾、雨、模糊)有物理规律, 你可以建模、可以补数据。 而对抗扰动是针对你的模型算出来的——补了 A 它就换 B。 对交通场景来说这不只是学术问题:贴在标志上的小贴纸、路面的特殊反光条,都可能让模型认错。 这类风险靠「多采数据」防不住,只能靠冗余——多传感器、多模型投票、加规则兜底。 这也是为什么车规级系统很少「只靠一个神经网络出结论」。冗余不是浪费,是对抗未知扰动的唯一手段。

五、落地:一张扰动表和一条红线

第一步,列清单。 按「你的传感器会遇到什么」列,不按「论文里有什么」列。 摄像头怕逆光,激光雷达怕雨雾,超声波怕高速——清单因传感器而异。 第二步,每类都测,单独报。 不要只报一个「综合准确率」。 报告里应该是一张 6 行 2 列的表(扰动、准确率),外加一列「相对干净的下降幅度」。 第三步,定红线。 比如「雾天准确率不得低于 85%」。 低于红线的场景要在功能上降级(限速、提示接管),而不是硬跑。 这一步是很多人跳过的地方:他们测出了掉点,但没定义「掉到多少就不能用」。 没有红线的测试报告,只会变成一份没人看的附件。

六、动手 Demo:鲁棒性:干净时 100.0%,一场雾打到 25.0%,增强后回到 100.0%

用四种几何基元(竖条纹、横条纹、圆环、斜线)各生成 100 张 32×32 图,加 σ=0.35 的底噪, 提取横/竖/斜梯度能量和均值、标准差五个特征,训练 softmax 回归。 然后在噪声、雾、过曝、模糊、棋盘纹理上各测一遍; 再用「干净 + 噪声 0.10 + 雾」重训一次,同样的七种输入再测一遍。

def feat(A):                       # 五个手工特征
    gx = np.abs(np.diff(A, axis=2)).sum(axis=(1, 2))
    gy = np.abs(np.diff(A, axis=1)).sum(axis=(1, 2))
    return np.stack([gx, gy, dg, A.mean(axis=(1, 2)),
                     A.std(axis=(1, 2))], axis=1)

def fog(A):
    return np.clip(0.45 * A + 0.40, 0, 1)      # 压对比度 + 抬底

def over(A):
    return np.clip(2.0 * A, 0, 1)              # 削顶

XA = np.concatenate([X, pert_noise, pert_fog])  # 只补两类
clf2 = fit(feat(XA), yA)

实跑输出:

--------------------------------------------------------------------
鲁棒性:干净时 100.0%,一场雾打到 25.0%,增强后回到 100.0%
--------------------------------------------------------------------
  样本                     400 张 32×32,4 类
  特征                     横/竖/斜梯度能量、均值、标准差
  分类器                   softmax 回归,900 轮

  扰动             原始训练   增强后
  ---------------------------------
  干净               100.0%    99.8%
  噪声 0.10           87.5%    99.0%
  噪声 0.25           75.2%    83.8%
  雾(压对比度)      25.0%   100.0%
  过曝 2 倍           50.0%    50.0%
  3×3 模糊            31.2%    35.8%
  棋盘纹理 0.06       95.5%   100.0%

  **干净数据 100.0%,最高的那一档。**下面三种扰动,掉法各不相同。
  **雾最狠,掉到 25.0%。**因为「乘 0.45 加 0.40」把对比度压掉一半多,
  **梯度能量整个塌下来,四类之间那点差别也被压平了。**
  **过曝 50.0%**:亮的被削成纯白,条纹对比一起消失。
  **模糊 31.2%**:3×3 均值把高频条纹抹平,横竖两类直接糊成一片。
  只有**棋盘纹理几乎不掉(95.5%)**——它是加性的高频,没有改变原有的梯度结构。
  增强之后(训练集里只加了噪声 0.10 和雾):
  **雾从 25.0% 回到 100.0%**,噪声两行也涨了(87.5%→99.0%、75.2%→83.8%)——
  **这是「增强对路」的样子:补了哪一类,那一类就回来。**
  但**过曝只挪了 +0.0 个点**(50.0%→50.0%),
  **模糊只挪了 +4.5 个点**(31.2%→35.8%)——
  **跟雾那 +75.0 个点比,等于没动。**
  **因为训练集里根本没出现过这两类。**
  结论很硬:**数据增强只能覆盖「你加进去的那几类」扰动。**
  **没加的那几类不会因为增强而明显变好**——原地不动算正常,小幅波动也算正常。
  所以「模型很鲁棒」必须带条件:**在哪几类扰动上鲁棒。**
  不做分类说明的鲁棒性测试,基本等于没测。

干净数据 100%, 雾 25%——同一套权重,只换了输入。这就是「实验室指标」和「路上表现」的差距来源。 过曝掉 50 个点、模糊掉 68.8 个点,都不是「慢慢变差」,是断崖式的——因为特征被整类抹掉, 而不是被轻微污染。 增强后雾从 25% 回到 100%,这是补对了类的证据。过曝 50%→50%,模糊 31.2%→35.8%,等于没补。 注意增强后干净数据反而从 100% 掉到 99.8%—— 补了噪声就会牺牲一点干净数据上的精度,这是必然的交换。 要说明:这些图是我用几何基元合成的,不是真实交通标志,特征也是手选的,不是 CNN 学出来的。 但「扰动分类、逐类测量、增强只覆盖补过的类」这条逻辑是真的,换成真实数据集,流程一模一样。

30 秒实验

  1. 把雾的参数从「乘 0.45 加 0.40」改成「乘 0.7 加 0.15」(轻雾),看准确率。 会掉到 70% 左右——轻雾不一定触发降级,这是最危险的情况。
  2. 把增强集里加上过曝,重训,看过曝那一行。 应该能回到 90% 以上;同时注意干净数据会不会再掉一点。
  3. 把 3×3 模糊换成 5×5,看掉点幅度。会掉得更狠——核越大,高频信息损失越多。

常见误区

  1. 「模型准确率 99%,很鲁棒」。准确率是在某种输入分布上测的,换个天气就可能是 25%。
  2. 「加了数据增强就鲁棒了」。增强只对补过的那几类有效,过曝一个点没动就是证据。
  3. 「对抗扰动是学术问题,路上遇不到」。 贴纸、反光条、特殊喷涂都能造成同样效果,冗余设计是唯一解。
自测三问(点开对答案) 1. 为什么「鲁棒性」必须拆成一组数来说? —— 不同扰动对特征的影响机制不同,不会一起好一起坏。 一个综合数字会把六件事混成一件,掩盖最弱的那一环。 2. 数据增强为什么救不了没补过的扰动? —— 增强改变的是训练分布。没出现在训练分布里的扰动,模型没学过对应的不变性,指标原地不动。 3. 为什么车规系统不靠单一模型出结论? —— 对抗类扰动是针对模型算出来的,补数据防不住。只能靠多传感器、多模型投票和规则兜底做冗余。

模型准不准是一件事,来不来得及是另一件。下一节把延迟拆到每一环,再换算成「米」。

相关笔记