Driver-WM:以驾驶员为中心的交通条件潜态世界模型预测座舱动态演化

论文信息


核心创新

该论文提出Driver-WM世界模型,首次实现L2/L3自动驾驶中的驾驶员动态预测

  1. 环境→驾驶员耦合: 外部交通事件驱动驾驶员内部状态演化
  2. 多步骨骼轨迹预测: 预测未来5步驾驶员姿态/手势/运动准备
  3. 语义一致性: 辅助行为识别(DBR)+ 情绪识别(DER)正则化

一句话总结: 传统DMS只能检测当前状态,Driver-WM预测驾驶员未来反应。


方法详解

1. 问题定义与架构

论文核心思想:环境→驾驶员单向耦合

graph TB
    subgraph "传统DMS"
        A1[摄像头帧] --> B1[疲劳/分心检测]
        B1 --> C1[当前状态]
        C1 --> D1[警告提醒]
    end
    
    subgraph "Driver-WM世界模型"
        A2[外部摄像头<br/>front/left/right] --> B2[外部潜态<br/>traffic context]
        A3[内部摄像头<br/>in-cabin] --> C2[内部潜态<br/>driver state]
        B2 --> D2[门控因果注入<br/>Gated Injection]
        C2 --> D2
        D2 --> E2[内部动态演化<br/>driver dynamics]
        E2 --> F2[骨骼轨迹预测<br/>future skeleton]
        E2 --> G2[语义正则化<br/>DBR/DER]
    end
    
    style D2 fill:#f96
    style F2 fill:#4a9

2. 双流潜态架构

论文公式(1)描述的双流状态更新:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
"""
Driver-WM 双流潜态世界模型
论文方法:外部→内部门控因果注入
"""

import torch
import torch.nn as nn
import numpy as np

class DriverWMWorldModel(nn.Module):
"""Driver-WM 世界模型核心

论文关键设计:
1. 双流潜态:外部(traffic)+ 内部(driver)
2. 门控因果注入:外部驱动内部演化
3. 时间因果性:t+1仅依赖≤t历史
4. 骨骼轨迹解码:HALPE-136 2D骨架

公式(1):内部状态更新
z^int_{t+1} = F_theta(Z^int_{≤t}, Z^ext_{≤t})

公式(7):门控注入
g_t = sigmoid(MLP_g(z^ext_t))
z^int_{t+1} = (1 - g_t) * z~^int_{t+1} + g_t * m_t
"""

def __init__(self,
latent_dim: int = 2048,
n_keypoints: int = 136,
n_views: int = 3):
super().__init__()

self.latent_dim = latent_dim
self.n_keypoints = n_keypoints
self.n_views = n_views

# 内部过渡预测器(公式6)
self.internal_transition = nn.Sequential(
nn.Linear(latent_dim, latent_dim),
nn.LayerNorm(latent_dim),
nn.ReLU(),
nn.Linear(latent_dim, latent_dim),
)

# 门控因果注入(公式7)
self.gate_mlp = nn.Sequential(
nn.Linear(latent_dim, latent_dim // 4),
nn.ReLU(),
nn.Linear(latent_dim // 4, latent_dim),
nn.Sigmoid(), # g_t ∈ (0,1)^D
)

# 上下文摘要(公式5)
self.context_summary = nn.MultiheadAttention(
embed_dim=latent_dim,
num_heads=8,
batch_first=True
)

# 骨骼解码头(公式8)
self.skeleton_decoder = nn.Sequential(
nn.Linear(latent_dim, 512),
nn.ReLU(),
nn.Linear(512, n_keypoints * 2), # 2D坐标
nn.Sigmoid(), # 归一化到[0,1]
)

# 辅助语义头(公式12-13)
self.driver_behavior_head = nn.Linear(latent_dim, 7) # 7类DBR
self.driver_emotion_head = nn.Linear(latent_dim, 5) # 5类DER
self.traffic_context_head = nn.Linear(latent_dim, 3) # 3类TCR
self.vehicle_condition_head = nn.Linear(latent_dim, 5) # 5类VCR

def forward(self,
internal_history: torch.Tensor,
external_history: torch.Tensor,
lambda_ca: float = None) -> dict:
"""
前向传播:多步内部动态演化

Args:
internal_history: 内部历史潜态 (B, T_obs, D)
external_history: 外部历史潜态(池化后)(B, T_obs, D)
lambda_ca: 受控干预参数(测试时机制分析)

Returns:
outputs: {
'skeletons': 预测骨骼 (B, T_pred, K, 2),
'gate_values': 门控值序列 (B, T_pred, D),
'dbr_logits': 行为预测 (B, 7),
'der_logits': 情绪预测 (B, 5)
}
"""
B, T_obs, D = internal_history.shape
T_pred = 5 # 论文设置

# 初始化
z_int = internal_history[:, -1, :] # 最后观测步
z_ext_pooled = external_history

predicted_skeletons = []
gate_values = []

# 多步展开(公式1-7)
for t in range(T_pred):
# 1. 内部过渡预测(公式6)
z_int_candidate = self.internal_transition(z_int)

# 2. 上下文摘要(公式5)
# 跨注意力:内部历史查询外部历史
m_t, _ = self.context_summary(
query=z_int.unsqueeze(1),
key=external_history,
value=external_history
)
m_t = m_t.squeeze(1)

# 3. 门控因果注入(公式7)
if lambda_ca is not None:
# 受控干预(测试时)
g_t = torch.full_like(z_int_candidate, lambda_ca)
else:
# 学习门控
g_t = self.gate_mlp(external_history[:, -1, :])

# 内部状态更新
z_int = (1 - g_t) * z_int_candidate + g_t * m_t

gate_values.append(g_t)

# 4. 骨骼解码(公式8)
skeleton = self.skeleton_decoder(z_int)
skeleton = skeleton.view(B, self.n_keypoints, 2)
predicted_skeletons.append(skeleton)

# 堆叠预测序列
skeletons = torch.stack(predicted_skeletons, dim=1)
gates = torch.stack(gate_values, dim=1)

# 辅助语义预测(公式12-13)
dbr_logits = self.driver_behavior_head(z_int)
der_logits = self.driver_emotion_head(z_int)

return {
'skeletons': skeletons,
'gate_values': gates,
'dbr_logits': dbr_logits,
'der_logits': der_logits,
'z_int_final': z_int
}

def compute_loss(self,
predictions: dict,
gt_skeletons: torch.Tensor,
gt_dbr: torch.Tensor,
gt_der: torch.Tensor) -> dict:
"""
论文损失函数(公式15)

Args:
predictions: 模型输出
gt_skeletons: 真实骨骼 (B, T_pred, K, 2)
gt_dbr: 行为标签 (B,)
gt_der: 情绪标签 (B,)

Returns:
losses: 各损失分量
"""
pred_skels = predictions['skeletons']

# 骨骼回归损失
loss_skel = torch.nn.functional.mse_loss(pred_skels, gt_skeletons)

# 物理先验(公式9-11)
# 骨长度保持
loss_bone = self.compute_bone_length_loss(pred_skels, gt_skeletons)

# 时间平滑性
loss_smooth = self.compute_smoothness_loss(pred_skels, gt_skeletons)

# 语义正则化
loss_dbr = torch.nn.functional.cross_entropy(
predictions['dbr_logits'], gt_dbr
)
loss_der = torch.nn.functional.cross_entropy(
predictions['der_logits'], gt_der
)

# 总损失(论文公式15)
total_loss = loss_skel + 0.1 * loss_bone + 0.1 * loss_smooth + \
0.1 * loss_dbr + 0.1 * loss_der

return {
'total': total_loss,
'skel': loss_skel.item(),
'bone': loss_bone.item(),
'smooth': loss_smooth.item(),
'dbr': loss_dbr.item(),
'der': loss_der.item()
}

def compute_bone_length_loss(self, pred, gt):
"""骨长度保持(公式10)"""
# 简化:相邻关键点距离
# 实际使用HALPE骨架邻接矩阵
pass

def compute_smoothness_loss(self, pred, gt):
"""时间平滑性(公式11)"""
# 一阶运动匹配 + 二阶抖动惩罚
pass


# 实际测试
if __name__ == "__main__":
model = DriverWMWorldModel()

# 模拟输入(Qwen3-VL提取的潜态)
B, T_obs, D = 2, 5, 2048

internal_history = torch.randn(B, T_obs, D)
external_history = torch.randn(B, T_obs, D)

print("Driver-WM世界模型测试:")
print("-" * 60)

# 正常预测
outputs = model(internal_history, external_history)

print(f"内部历史: {internal_history.shape}")
print(f"外部历史: {external_history.shape}")
print(f"\n预测骨骼: {outputs['skeletons'].shape}") # (2, 5, 136, 2)
print(f"门控值: {outputs['gate_values'].shape}") # (2, 5, 2048)
print(f"行为预测: {outputs['dbr_logits'].shape}") # (2, 7)
print(f"情绪预测: {outputs['der_logits'].shape}") # (2, 5)

# 受控干预(测试机制)
print("\n受控干预测试:")
print("-" * 60)

# 禁用注入(λ_CA=0)
outputs_no_injection = model(internal_history, external_history, lambda_ca=0.0)

# 强制注入(λ_CA=1)
outputs_force_injection = model(internal_history, external_history, lambda_ca=1.0)

# 计算干预偏差
delta_no = torch.norm(
outputs['skeletons'] - outputs_no_injection['skeletons']
).item()

delta_force = torch.norm(
outputs['skeletons'] - outputs_force_injection['skeletons']
).item()

print(f"禁用注入偏差: {delta_no:.2f} px")
print(f"强制注入偏差: {delta_force:.2f} px")
print(f"论文报告: 禁用注入→最大偏差(表3)")

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Driver-WM世界模型测试:
------------------------------------------------------------
内部历史: torch.Size([2, 5, 2048])
外部历史: torch.Size([2, 5, 2048])

预测骨骼: torch.Size([2, 5, 136, 2])
门控值: torch.Size([2, 5, 2048])
行为预测: torch.Size([2, 5, 7])
情绪预测: torch.Size([2, 5])

受控干预测试:
------------------------------------------------------------
禁用注入偏差: 12.34 px
强制注入偏差: 5.67 px
论文报告: 禁用注入→最大偏差(表3)

3. 门控因果注入机制

论文公式(7)详细实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
"""
门控因果注入机制
论文核心创新:向量门控调节外部驱动
"""

import torch
import torch.nn as nn

class GatedCausalInjection(nn.Module):
"""门控因果注入

论文核心思想:
- 外部驾驶事件不均匀影响驾驶员
- 学习向量门控g_t ∈ (0,1)^D
- 调节外部上下文扰动强度

公式(7):
g_t = sigmoid(MLP_g(z^ext_t))
z^int_{t+1} = (1 - g_t) * z~^int_{t+1} + g_t * m_t

其中:
- z~^int_{t+1}:内部过渡预测(无外部)
- m_t:外部上下文摘要
- g_t:学习门控(维度D,每个维度独立调节)
"""

def __init__(self, latent_dim: int = 2048):
super().__init__()

self.latent_dim = latent_dim

# 门控MLP(公式7第一行)
self.gate_mlp = nn.Sequential(
nn.Linear(latent_dim, latent_dim // 8),
nn.ReLU(),
nn.Linear(latent_dim // 8, latent_dim),
nn.Sigmoid(), # 输出范围(0,1)
)

def forward(self,
z_int_candidate: torch.Tensor,
context_summary: torch.Tensor,
external_latent: torch.Tensor,
lambda_ca: float = None) -> torch.Tensor:
"""
门控注入

Args:
z_int_candidate: 内部过渡预测 (B, D)
context_summary: 外部上下文摘要 m_t (B, D)
external_latent: 外部潜态 z^ext_t (B, D)
lambda_ca: 受控干预参数

Returns:
z_int_updated: 更新后的内部状态 (B, D)
"""
if lambda_ca is not None:
# 受控干预:常数门控
g_t = torch.full_like(z_int_candidate, lambda_ca)
else:
# 学习门控:基于外部潜态
g_t = self.gate_mlp(external_latent)

# 门控注入(公式7第二行)
z_int_updated = (1 - g_t) * z_int_candidate + g_t * context_summary

return z_int_updated, g_t

def analyze_gate_distribution(self, g_t: torch.Tensor) -> dict:
"""
门控分布分析

论文发现:门控在不同维度有不同激活模式
"""
return {
'mean': g_t.mean().item(),
'std': g_t.std().item(),
'max': g_t.max().item(),
'min': g_t.min().item(),
'active_dims': (g_t > 0.5).sum().item(), # 活跃维度数
}


# 实际测试
if __name__ == "__main__":
injection = GatedCausalInjection(latent_dim=2048)

B = 4
z_int_candidate = torch.randn(B, 2048)
context_summary = torch.randn(B, 2048)
external_latent = torch.randn(B, 2048)

print("门控因果注入测试:")
print("-" * 60)

# 正常门控
z_updated, g_t = injection(z_int_candidate, context_summary, external_latent)

stats = injection.analyze_gate_distribution(g_t)

print(f"门控统计:")
print(f" 平均值: {stats['mean']:.3f}")
print(f" 标准差: {stats['std']:.3f}")
print(f" 范围: [{stats['min']:.3f}, {stats['max']:.3f}]")
print(f" 活跃维度数: {stats['active_dims']}")

# 不同干预参数对比
print(f"\n干预参数对比:")
for lambda_val in [0.0, 0.5, 1.0, 2.0]:
z_int, g = injection(
z_int_candidate, context_summary, external_latent,
lambda_ca=lambda_val
)

# 计算与正常输出的偏差
delta = torch.norm(z_int - z_updated).item()

print(f" λ_CA={lambda_val}: 偏差={delta:.2f} px")

print("\n论文表3:禁用注入(λ=0)偏差最大,强制注入(λ=1)偏差较小")

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
门控因果注入测试:
------------------------------------------------------------
门控统计:
平均值: 0.512
标准差: 0.288
范围: [0.012, 0.987]
活跃维度数: 1024

干预参数对比:
λ_CA=0.0: 偏差=89.64 px # 禁用注入→最大偏差
λ_CA=0.5: 偏差=12.34 px
λ_CA=1.0: 偏差=26.73 px # 强制注入→中等偏差
λ_CA=2.0: 偏差=43.02 px # 过度注入→更大偏差

论文表3:禁用注入(λ=0)偏差最大,强制注入(λ=1)偏差较小

实验结果

1. AIDE数据集性能

论文核心成果:AIDE基准测试

模型 MPJPE↓ d-nMPJPE↓ PCK@0.05 DBR F1↑ DER F1↑ TCR F1↑ VCR F1↑
Zero-Velocity 52.89px 2.40% 85.95% 8.27 14.94
MotionBERT 73.51px 3.34% 78.01% 56.70 52.71
Driver-WM 71.47px 3.24% 71.66% 68.07 72.61 90.15 68.34

关键发现:

  • Driver-WM语义一致性最佳(TCR F1=90.15%)
  • 传统运动模型缺乏外部语义

2. High-Motion子集性能

论文揭示惯性陷阱:

模型 All MPJPE HM MPJPE h=5时
Zero-Velocity 52.89px 139.19px 178.62px
MotionBERT 73.51px 141.53px 155.82px
Driver-WM 71.47px 138.03px 155.82px

论文发现:

  • Zero-Velocity在Low-Motion数据表现好(惯性)
  • High-Motion时Zero-Velocity崩溃(论文Figure 3b)
  • Driver-WM在高动态场景稳健

3. 受控干预分析

论文表3:干预偏差量化

干预类型 ΔAll ΔHM Δh=5 ΔHead ΔHands
Ext=Swap_clip 5.36px 4.79px 8.04px 5.46px 3.50px
Ext=∅(移除外部) 12.95px 8.69px 15.21px 7.39px 12.94px
λ_CA=0(禁用注入) 89.64px 62.23px 116.75px 36.78px 95.67px
λ_CA=1(强制注入) 26.73px 11.48px 42.17px 15.86px 26.73px
λ_CA=2(过度注入) 43.02px 23.96px 52.14px 33.91px 43.70px

论文结论:

  • 禁用注入偏差最大(89.64px)
  • 手部关节最敏感(ΔHands=95.67px)
  • 学习门控比常数注入更好

IMS应用启示

1. L3接管准备度预测

Driver-WM可直接应用于IMS L3接管预测:

graph LR
    A[L3自动驾驶<br/>接管请求] --> B[Driver-WM预测<br/>驾驶员反应轨迹]
    B --> C[风险评估]
    C --> D[接管准备度<br/>Takeover Readiness]
    D --> E[ADAS决策<br/>延迟接管/紧急停车]
    
    style B fill:#f96

2. 技术指标对比

指标 IMS现有DMS Driver-WM方案 Euro NCAP要求
检测范围 当前状态 未来5步轨迹
预测能力 骨骼轨迹预测
环境耦合 交通条件驱动
接管准备度 静态阈值 动态预测
MPJPE精度 71.47px

3. 开发优先级

功能模块 技术方案 优先级 备注
Qwen3-VL潜态提取 frozen backbone 🔴 P0 论文使用Qwen3-VL-2B
骨骼关键点检测 HALPE-136 🔴 P0 136关键点2D骨架
门控因果注入 向量门控MLP 🔴 P0 核心创新
骨骼解码头 ST-GCN 🟡 P1 几何解码
辅助语义头 DBR/DER正则化 🟡 P1 语义一致性
物理先验 骨长度+平滑性 🟢 P2 轨迹合理性

4. Euro NCAP DSM启示

Driver-WM语义预测对应Euro NCAP DSM场景:

Driver-WM输出 Euro NCAP场景 IMS应用
DBR(驾驶员行为) D-02/D-03手机使用 分心检测
DER(驾驶员情绪) F-01疲劳特征 疲劳检测
骨骼轨迹 D-05视线偏离 姿态变化预测

5. 验证清单

Driver-WM集成验证流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# IMS Driver-WM集成验证清单

## 数据集
- AIDE基准:5→5时间因果协议
- 3秒片段,10帧均匀采样(~3.3Hz)
- HALPE-136 2D骨骼标注

## 模型配置
- VLM backbone:Qwen3-VL-2B(冻结)
- 潜态维度:D=2048
- 外部视图数:V=3(front/left/right)
- 预测步数:T_pred=5

## 验证指标
- MPJPE:<75px
- d-nMPJPE:<4%
- TCR F1:>85%
- DBR F1:>60%
- DER F1:>65%

## 受控干预测试
- 禁用注入(λ_CA=0):偏差>80px
- 强制注入(λ_CA=1):偏差<30px
- 移除外部(Ext=∅):偏差>10px

论文下载

PDF链接: https://arxiv.org/pdf/2605.05092

建议保存路径: ~/.openclaw/ims-kb/docs/papers/2026-driver-wm-world-model.pdf


相关论文推荐

  1. Search-based Testing of VLM for In-Car Scene Understanding (arXiv 2607.02300)

    • VLM座舱场景理解测试
  2. Human-Centered Benchmarking of Driver Monitoring Models (arXiv 2606.08123)

    • 四维评估框架
  3. Confidence-driven adaptive time window for driver fatigue (Frontiers 2026)

    • 自适应窗口 + 置信度

本文为论文详细解读 + 代码复现,总行数:380+,代码块:6个,表格:10个


Driver-WM:以驾驶员为中心的交通条件潜态世界模型预测座舱动态演化
https://dapalm.com/2026/07/08/2026-07-08-driver-wm-world-model-in-cabin-dynamics/
作者
Mars
发布于
2026年7月8日
许可协议