Personal Knowledge Base

A long-term research and learning notebook for posts, notes, papers, projects, and research directions.

Skip to content
Back to RiskAffordance overview

阶段②:先验激活(FiLM + Direction Routing)

阶段①的先验是通用的:它学会的是"近+快逼近=危险"这种几何规律,但它不知道什么叫"追尾"、什么叫"切出"。阶段②要做的事:冻结先验不动,用语言描述和事故类型去"激活/改写"它输出的危险场 H,得到一张"特定事故形态下"的危险场 H′。

76 min read

目的:给"通用危险直觉"注入"事故语义"

阶段①的先验是通用的:它学会的是"近+快逼近=危险"这种几何规律,但它不知道什么叫"追尾"、什么叫"切出"。阶段②要做的事:冻结先验不动,用语言描述和事故类型去"激活/改写"它输出的危险场 H,得到一张"特定事故形态下"的危险场 H′。

类比:先验是一个经验丰富的司机的"危险直觉",阶段②是有人在他耳边说"注意,现在是前车急刹场景"——他的危险直觉立刻聚焦到正前方。这个"说一句话就能改写危险场"的能力,是整个项目区别于传统 bbox 预测的立身之本。

为什么机制上必须是"改写场"而不是"重新生成"?因为先验已经冻结,且事故数据稀缺——能训练的参数必须极少,训练数据必须能程序化无限合成。这两条约束直接决定了后面的全部技术选型。

输入输出

输入:  H = {o, ρ, v}        ← 冻结先验的输出(训练时用 H_gt,原因上一轮讲过)
        type_id              ← 事故类型(rear_end / cut_in_left / head_on / ... 10 类含 unknown)
        text                 ← 英文语言描述("the car ahead brakes suddenly...")
 
输出:  H′ = {o′, ρ′, v′}    ← 改写后的场(同网格同形状)
        中间量 {w, λ, γ, β, α_ρ, α_v}  ← 全部可解释、可监控(后面会看到这些救了无数次诊断)
 
可训练参数:仅 ~1-2M(FiLM 层 + Type Embedding + Routing 参数)
冻结:      Grid U-Net 先验 + CLIP 文本编码器(~150M)全部冻结

训练数据:程序化改写

这是本阶段第一个"设计硬核"。要学映射 H → H′,需要成对数据,但没有真实事故占用。解法:规则化合成。以伪标签构造的 H_gt 为起点,按事故类型执行规则化改写生成监督目标 H′_gt

  • 例:rear_end(ego 追尾前车)→ 在 ego 正前方按校准距离放一个高斯风险核注入 ρ(max 语义,与伪标签栅格化同款),核内 v 全部指向"从前方来"的方向;
  • cut_in_left → 核放左前方侧向位置;
  • 核的方位/距离/σ/幅度不是拍脑袋——从 DoTA 真实事故数据集的统计分布里采样校准(onset 窗口,事故发生初期 ~1s 内的 bbox 投影统计);
  • 文本侧:每类 ≥15 条英文模板(含方位词),CLIP 一次性编码成嵌入缓存。

于是配对 (H, H′_gt, type, text) 可以无限量、类别均衡、种子确定性地合成——train 4419 对 / val 1047 对,9 类各 491。真实事故数据(DoTA)只用来做分布校准,不做逐样本监督——这是数据稀缺设定下的标准生存策略。

答辩口径备好了:为什么可行?因为事故的几何前兆(逼近、TTC 骤降、近距切入)在正常数据里完备存在,阶段②只是"把通用几何重新定向到特定事故形态",这是规则可以描述的局部改写。

机制一:FiLM —— 管"多少、多危险"(强度域)

问题:怎么把"这是追尾场景"这个信息注入一个冻结的 3D 特征场?

选型对比(答辩高危问题):

  • concat(拼接条件到输入):需要后续网络层可训练来消化拼接信息——主干冻结了,没有后续层,出局;
  • cross-attention:token 级交互,需要大量配对数据训练,参数大——我们只有合成配对、参数预算百万级,出局;
  • FiLM(Feature-wise Linear Modulation):逐通道仿射变换,参数百万级、即插即用、天然兼容冻结主干。入选

FiLM 的做法:

γ, β = MLP(type_emb ⊕ clip_text_emb)        ← 类型嵌入拼接文本嵌入,过一个小 MLP
FiLM(F) = γ ⊙ F + β                          ← 对 3D 特征逐通道缩放+平移
  • γ(缩放):决定"放大/抑制哪些特征通道"——比如追尾场景下放大"前方快速逼近"相关的特征通道,抑制侧向通道。这是强度域的改写;
  • β(平移):整体偏移;
  • 零初始化技巧:γ 初始化为 1、β 初始化为 0,使训练起点是恒等映射(H′=H,实测误差 0.00e+00)——模型从"什么都不改"出发,按需学改写,而不是从随机改写出发。这个技巧后面会被反复验证其价值(也有一段"被污染权重不能做初始化"的血泪史呼应它)。

FiLM 的短板(刻意留白):γ、β 是全局共享的一组数——它能把"危险"整体调强调弱,但没有空间分辨能力,说不出"把危险从左边挪到右边"。这个短板由第二个机制补。

机制二:Direction Routing —— 管"在哪、朝哪来"(几何域,自研)

这是项目的原创机制,补 FiLM 的空间短板。分三步:

第 1 步:方位原型库

D = {d_rear, d_side-left, d_side-right, d_front, ...}  ← 8 向原型
每个原型 = 一个单位向量(方向)+ 一个空间锚点(位置)

原型初始化是几何先验(类似检测里的 anchor)——答辩被问"这是不是手工特征"时的口径:原型只是初始化,路由权重由数据学习,这是数据稀缺设定下的结构化归纳偏置,是优点不是缺点。

第 2 步:双通路软路由

两条通路分别对原型库做软选择:

类型通路:type embedding → 与各原型算亲和度 → w = softmax(e·D)
文本通路:CLIP 文本嵌入(含方位词"left lane"/"ahead"...)→ 同样路由
两路印证,冲突时按 λ 混合(λ(type)/λ(text) 可学习门控)

"一辆车从左侧切入"这句话里的 "left",和 type_id=cut_in_left,应该在原型库里路由到同一个方向——双通路互相印证。unknown 兜底类型强制退化为纯文本通路。

第 3 步:场改写

按路由权重 w 在对应方位生成/移动风险核   → 重定位 ρ′(危险挪到该在的位置)
把方向场向量向原型方向重定向             → 重定向 v′(威胁方向指向正确来向)
改写强度由可学习标量 α_ρ、α_v 门控       ← 这两个小标量后来成为最重要的"仪表盘"

两个机制的分工一句话:FiLM 管强度(多少、多危险),Routing 管几何(在哪、朝哪来)

训练攻关史:四场硬仗

第 1 仗:过拟合试金石首轮 FAIL —— 损失量级失衡 + 梯度阻断

200 步试金石,结果:总损失只降 39.21%(要求 ≥80%)、v'cos 0.4338(要求 ≥0.9)。按铁律先诊断不动参,定位出两个根因:

  • velocity/rho 损失量级失衡 19.6 倍(阶段①的 775 倍教训的小型重演)→ λ_rho 1→20;
  • routing 硬 mask 阻断梯度:v 只在 ρ′ > τ 的区域被改写和监督,而改写幅度由 α_ρ 控制——v 的损失梯度传不到 α_ρ,α_ρ 被 ρ-L1 钉在 0.75,覆盖率封顶 85%,v'cos ≈ 覆盖率,结构性锁死。

解法:覆盖 hinge 损失(给覆盖率一个显式的梯度来源,把被门控阻断的量"捞出来")+ autograd 解平衡点一次定权。复跑 PASS:损失 −93.5%、routing acc 1.000、v'cos 0.982。

方法论沉淀:硬 mask 会阻断梯度通路——被门控的量收不到下游梯度时,要给它加显式的覆盖约束;λ 用 autograd 平衡点一次解出,胜过逐档试 lr。

第 2 仗:λ_coverage 校准 —— 悬崖与闸门

λ_coverage 这个权重怎么定?设计了 --mode calibrate:观测 α_ρ 动态 → 网格扫描 → 用 autograd 解平衡点 λ = -λ_rho · g_rho / g_cov

连踩三次悬崖:target_coverage 定 0.88/0.85/0.84,解出来都是 113.6——因为 α_ρ-coverage 曲线在 0.75→1.0 之间存在悬崖(λ 从 ~4.4 跳到 113.6),目标落进空白区就向上取整到悬崖上方。sane 闸门 [4,30] 三次全部拦下,拒绝写回——这就是闸门存在的意义。第四次 target 降到 0.83,解出 λ_coverage=4.353 落带内写回。这个 4.353 后来被列为阶段②定版红线,不可回退。

第 3 仗:全量训练三轮 —— 目标冲突与阈值瓶颈

  • R1(λ_identity=10):peak v'cos 0.627 卡住。诊断:identity loss(要求 H′≈H 不要过度改写)与 velocity 优化梯度方向冲突——不是权重没调好,是两个目标在打架。处置:λ_identity=0 关闭,"identity 保持"降级为已知限制。两个目标冲突时,关闭比硬共存更诚实,但要把为什么关写成口径;
  • R2(th=0.05):peak 0.640,覆盖率封顶 0.64 锁死;
  • R3(mask_threshold 0.05→0.03):peak 0.699,验收通过(routing_acc 1.000、v'cos 0.689、oversat 0.737 ∈ [0.5,1.5]、coverage 0.883)。

这里留下了两阶段 τ 不一致的登记项:阶段①伪标签 τ=0.05,阶段②内部 0.03——进阶段③对接时要小心。

第 4 仗(最大的一仗):GT 方向约定翻转 → v2 全面重训

R3 验收过后,一次方向约定核查(检查 GT 的 v 是否真的指向"风险源→ego")掀了桌子:

原始版 rear_end:v 方向 100% 翻转(mean 点积 −0.956)
且 vel 恒为 (−1,0) 类型级常向量——不随样本位置变化
= 双重错误:方向反了 + 根本不是逐样本的几何量

在此之前一切 v'cos 结论都建立在噪声 GT 上——包括刚通过的 0.689。这触发了一整条修复链,是项目"先诊断再修"纪律的最大规模实战:

  1. pair_gen 统一修复v = normalize(p_ego − p_source) 全分支统一,mask 外严格为零;
  2. DoTA 校准配套rear_end 的语义以真实数据为准后整个翻转——从"被追尾"(锚点后方 −π)变成"ego 追尾前车"(锚点正前 0.046 rad)。于是文本模板 16 条改写、文本嵌入缓存重编码 161 条……但漏改了一处:activation.yamlrear_end 的原型亲和先验还绑着旧语义 [rear]。这个漏网之鱼后面单独引爆(见下);
  3. 微调路线证伪:用旧 GT 训出的 best.pt 做初始化微调 → 失败(v'cos −0.784)。探针证明:旧权重对 v2 数据系统性反向(mean −0.801)——被污染约定训出的权重不能做新约定的初始化。零初始化才是中性起跑(zero-init 探针:median +0.000,中性起点坐实);
  4. 零初始化重训 + 方案 A/B 攻关:首训 oversat 0.177 塌缩(FiLM 捷径满足 coverage → hinge 失活 → α_ρ 失去梯度来源)→ 方案 A 路径感知 hinge 修结构(α_ρ 0.038→0.27)→ 方案 B 矩匹配修力度(α_ρ 企稳 0.72)→ 定版:v'cos 0.8689、oversat 0.7516、routing 1.0;
  5. rear_end 亲和修复:三弱类探针坐实 rear_end 的路由权重 w 绑死 rear 原型 0.903(就是第 2 步漏改的那行配置)→ 一行配置修复 [rear]→[front] + 重训 → v'cos 0.9613、rear_end 方位 12.40°——教训入库:"语义翻转的同步清单要闭环到叶子配置:模板 + 缓存 + affinity 绑定 + 映射表注释,缺一项就是埋雷"。

验收与关闭:全绿,但带着登记在案的已知限制

最终定版(best_v2.pt,冻结):

闸门结果
routing_acc1.000
v'cos0.9613(v2 原生口径)
oversat1.048 ∈ [0.5, 1.5]
8 张可视化人工验收通过(含病理如实呈现)

登记为已知限制、排队专项处理的三件事(关闭不粉饰):

  • "文本聋":λ(type)=0.88 主导下,文本通路被压制——同场景只改文本方位词,H′ 只移动 0.002~0.005 rad(几乎不动)。这直接威胁"语言激活先验"的核心叙事,排队阶段③窗口期专项;
  • side_swipe 单侧塌缩:w 恒塌到 side-right 0.715,与文本"left lane"冲突——疑与文本聋耦合(左右信息在文本里,但文本通路被压制,单侧塌缩是"信息不可得下的理性策略");
  • intersection_turn 方向不确定:w 分布左右对半(0.343/0.541),低 v'cos 0.544。

阶段②小结

阶段② = 冻结先验之上,用 ~1-2M 参数的 FiLM(强度域改写)+ Direction Routing(几何域改写),把"通用危险直觉"按事故类型和语言描述定向激活成 H′;训练数据全部程序化合成(规则改写 + DoTA 分布校准);它贡献了项目最多的方法论遗产——梯度阻断与覆盖 hinge、平衡点求解与 sane 闸门、目标冲突的诚实关闭、GT 约定核查先于模型归因、零初始化起跑、语义翻转的同步清单——也以"文本聋"的登记留下了核心叙事上最大的一笔待还债务。