PART:物理感知雷达 Transformer——1.1M 参数实现 0.88 类不可知移动目标检测

论文来源:arXiv 2609.02289,2026年9月2日
核心创新:Doppler-Aware Query Initialization + Physics-Guided Cross-Attention
关键指标:1.1M 参数,CA-AP 0.8827,全天候/全遮挡鲁棒
IMS 相关性:⭐⭐⭐⭐(CPD 和座舱移动目标检测的雷达-only 方案)


论文信息

项目 内容
标题 If It Moves, Radar Knows: A Physics-Aware Radar Transformer for Class-Agnostic Moving-Object Detection
arXiv 2609.02289
发表日期 2026年9月2日
作者 Yinghao Sun 等
投稿目标 ICRA 2027
代码 将开源(GitHub: sunyinghao-uestc/PART)
链接 https://arxiv.org/abs/2609.02289

核心创新

用 1.1M 参数实现类不可知的移动目标检测

PART(Physics-Aware Radar Transformer)是一个纯雷达检测器,不依赖摄像头,利用多普勒物理特性检测任意类别的移动目标。

三个关键模块

模块 缩写 创新点 解决的问题
Doppler-Aware Query Initialization DAQI 按位置和速度聚类雷达回波生成查询 替代场景无关的学习查询
Physics-Guided Cross-Attention PGCA 引入径向-多普勒一致性和 RCS 增强查询-点关联
Uncertainty-Aware Supervision UAS 随机遮蔽 GT,给模糊查询软标签 减少对穷举标注的依赖

方法详解

1. DAQI(Doppler-Aware Query Initialization)

传统 Transformer 使用场景无关的学习查询(learnable queries),在稀疏雷达场景中效果差。DAQI 改为从输入雷达回波中聚类生成查询:

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
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
"""
PART 论文 DAQI 模块复现

论文 Section 3.2: Doppler-Aware Query Initialization
核心: 在位置和速度空间聚类雷达回波 → 生成输入依赖的查询

对比:
- 传统 DETR: queries = nn.Parameter(num_queries, dim)
- PART DAQI: queries = cluster(radar_points, by=[position, velocity])
"""

import torch
import torch.nn as nn
import torch.nn.functional as F

class DAQI(nn.Module):
"""
Doppler-Aware Query Initialization

将雷达回波点按 (x, y, velocity) 聚类,
每个聚类中心初始化为一个查询。

优势:
- 输入依赖:不同场景不同查询
- 多普勒感知:利用速度信息区分目标
- 稀疏友好:聚类减少空查询
"""

def __init__(self, radar_dim: int = 5, query_dim: int = 256,
num_queries: int = 100, num_clusters: int = 100):
super().__init__()
self.num_queries = num_queries
self.query_dim = query_dim

# 将聚类特征投影到查询维度
self.query_proj = nn.Sequential(
nn.Linear(radar_dim, 128),
nn.ReLU(),
nn.Linear(128, query_dim)
)

# 可学习的查询 refinement
self.refine = nn.Sequential(
nn.Linear(query_dim, query_dim),
nn.LayerNorm(query_dim),
nn.GELU(),
nn.Linear(query_dim, query_dim)
)

def forward(self, radar_points: torch.Tensor,
mask: torch.Tensor = None) -> torch.Tensor:
"""
Args:
radar_points: (B, N, 5) [x, y, z, doppler, rcs]
mask: (B, N) True for valid points

Returns:
queries: (B, num_queries, query_dim)
"""
B, N, _ = radar_points.shape

# 简化版聚类:基于多普勒速度和位置的 K-means
# 实际论文使用更复杂的聚类策略
queries = self.query_proj(radar_points) # (B, N, query_dim)

# 选择 top-K 个点作为初始查询
# 基于多普勒幅值排序(移动越快越可能是目标)
if mask is not None:
doppler_score = radar_points[..., 3].abs() # 多普勒速度
doppler_score = doppler_score.masked_fill(~mask, -1e6)
else:
doppler_score = radar_points[..., 3].abs()

# Top-K 选择
_, top_idx = doppler_score.topk(self.num_queries, dim=1) # (B, K)
top_idx = top_idx.unsqueeze(-1).expand(-1, -1, self.query_dim)
queries = queries.gather(1, top_idx) # (B, K, query_dim)

# Refinement
queries = self.refine(queries)

return queries


class PGCA(nn.Module):
"""
Physics-Guided Cross-Attention

论文 Section 3.3: Physics-Guided Cross-Attention

在标准 cross-attention 基础上加入:
1. 径向-多普勒一致性: 雷达径向速度应与位置变化一致
2. RCS (雷达截面积): 大目标 RCS 更高

公式:
attention = softmax(Q·K^T / sqrt(d) + α·physics_score)
"""

def __init__(self, dim: int = 256, num_heads: int = 8):
super().__init__()
self.num_heads = num_heads
self.scale = (dim // num_heads) ** -0.5

self.q_proj = nn.Linear(dim, dim)
self.k_proj = nn.Linear(dim, dim)
self.v_proj = nn.Linear(dim, dim)
self.out_proj = nn.Linear(dim, dim)

# 物理特征编码
self.physics_proj = nn.Sequential(
nn.Linear(3, 32), # radial-doppler consistency, rcs, distance
nn.ReLU(),
nn.Linear(32, num_heads) # 每个头的物理偏置
)

def forward(self, queries: torch.Tensor,
radar_points: torch.Tensor,
point_features: torch.Tensor,
physics_meta: torch.Tensor = None) -> torch.Tensor:
"""
Args:
queries: (B, Q, dim)
radar_points: (B, N, 5) [x,y,z,doppler,rcs]
point_features: (B, N, dim) 雷达点特征
physics_meta: (B, N, 3) 物理元数据
"""
B, Q, D = queries.shape
N = radar_points.shape[1]

Q_ = self.q_proj(queries) # (B, Q, dim)
K_ = self.k_proj(point_features) # (B, N, dim)
V_ = self.v_proj(point_features)

# Multi-head reshape
Q_ = Q_.view(B, Q, self.num_heads, D // self.num_heads).transpose(1, 2)
K_ = K_.view(B, N, self.num_heads, D // self.num_heads).transpose(1, 2)
V_ = V_.view(B, N, self.num_heads, D // self.num_heads).transpose(1, 2)

# Standard attention
attn = torch.matmul(Q_, K_.transpose(-1, -2)) * self.scale # (B, H, Q, N)

# Physics-guided bias
if physics_meta is not None:
physics_bias = self.physics_proj(physics_meta) # (B, N, H)
physics_bias = physics_bias.transpose(1, 2).unsqueeze(2) # (B, H, 1, N)
attn = attn + physics_bias * 0.1 # 物理偏置权重

attn = F.softmax(attn, dim=-1)
out = torch.matmul(attn, V_) # (B, H, Q, D/H)
out = out.transpose(1, 2).reshape(B, Q, D)

return self.out_proj(out)


class PART(nn.Module):
"""
完整的 PART (Physics-Aware Radar Transformer)

纯雷达输入 → 类不可知移动目标检测

性能 (nuScenes):
- CA-AP: 0.8827
- mASTE: 0.3188m
- mAVE: 0.8084 m/s
- 参数量: 1.1M
- 夜间/雨/遮挡均有效
"""

def __init__(self, radar_dim: int = 5, dim: int = 256,
num_queries: int = 100, num_heads: int = 8):
super().__init__()

# 输入特征编码
self.input_proj = nn.Linear(radar_dim, dim)

# DAQI 查询初始化
self.daqi = DAQI(radar_dim=radar_dim, query_dim=dim, num_queries=num_queries)

# PGCA cross-attention 层 (简化版,实际有6层)
self.cross_attn = PGCA(dim=dim, num_heads=num_heads)
self.self_attn = nn.MultiheadAttention(dim, num_heads, batch_first=True)
self.ffn = nn.Sequential(
nn.Linear(dim, dim * 4),
nn.GELU(),
nn.Linear(dim * 4, dim)
)
self.norm1 = nn.LayerNorm(dim)
self.norm2 = nn.LayerNorm(dim)

# 预测头
self.exist_head = nn.Linear(dim, 1) # 存在性
self.position_head = nn.Linear(dim, 3) # 表面点位置
self.velocity_head = nn.Linear(dim, 2) # 2D 速度

def forward(self, radar_points: torch.Tensor,
mask: torch.Tensor = None) -> dict:
"""
Args:
radar_points: (B, N, 5) [x, y, z, doppler, rcs]
mask: (B, N) valid mask

Returns:
dict with 'existence', 'position', 'velocity'
"""
# 输入编码
point_feat = self.input_proj(radar_points)

# DAQI 生成查询
queries = self.daqi(radar_points, mask)

# Cross-attention with physics guidance
queries = self.cross_attn(queries, radar_points, point_feat)

# Self-attention
residual = queries
queries = self.self_attn(queries, queries, queries)[0]
queries = self.norm1(residual + queries)

# FFN
residual = queries
queries = self.norm2(residual + self.ffn(queries))

# 预测
return {
'existence': self.exist_head(queries).squeeze(-1), # (B, Q)
'position': self.position_head(queries), # (B, Q, 3)
'velocity': self.velocity_head(queries), # (B, Q, 2)
}


# ==================== 测试代码 ====================
if __name__ == "__main__":
import time

# 模型初始化
model = PART(radar_dim=5, dim=256, num_queries=50)
model.eval()

# 模拟雷达点云输入(nuScenes 雷达格式)
B, N = 1, 300 # 1 batch, 300 radar points
radar_points = torch.randn(B, N, 5) * torch.tensor([50, 50, 5, 5, 10])
mask = torch.ones(B, N, dtype=torch.bool)

# 推理
start = time.time()
with torch.no_grad():
outputs = model(radar_points, mask)
infer_time = (time.time() - start) * 1000

print("=" * 60)
print("PART 物理感知雷达 Transformer 测试")
print("=" * 60)
print(f"输入: {B}x{N} 雷达点, 5维 [x,y,z,doppler,rcs]")
print(f"查询数: {outputs['existence'].shape[1]}")
print(f"存在性预测: {outputs['existence'].shape}")
print(f"位置预测: {outputs['position'].shape}")
print(f"速度预测: {outputs['velocity'].shape}")

total_params = sum(p.numel() for p in model.parameters())
print(f"\n模型参数量: {total_params:,} ({total_params/1e6:.2f}M)")
print(f"推理时间: {infer_time:.2f} ms")

# 分析检测结果
existence_prob = torch.sigmoid(outputs['existence'])
high_conf = (existence_prob > 0.5).sum().item()
print(f"\n高置信度目标数: {high_conf}/{outputs['existence'].shape[1]}")

# 模拟 CPD 场景
print("\n" + "=" * 60)
print("座舱 CPD 场景模拟")
print("=" * 60)

# 模拟儿童呼吸微动雷达信号
child_radar = torch.randn(B, 50, 5) * torch.tensor([2, 2, 0.5, 0.1, 0.5])
child_radar[:, :, 3] *= 0.05 # 极小多普勒(呼吸)

with torch.no_grad():
cpd_out = model(child_radar, torch.ones(B, 50, dtype=torch.bool))

cpd_exist = torch.sigmoid(cpd_out['existence'])
cpd_detect = (cpd_exist > 0.3).sum().item()
print(f"微动目标检测: {cpd_detect} 个")
print(f"最大置信度: {cpd_exist.max():.4f}")
print("💡 提示:儿童呼吸的微多普勒信号极弱,需调参优化")

2. 不确定性感知监督(UAS)

UAS 解决了雷达标注不完整的问题:

问题 传统方案 UAS 方案
标注遗漏 漏标目标被视为负样本 给模糊查询分配软标签
部分标注 只训练有标注的类别 类不可知,检测所有移动目标
假阳性 直接惩罚 检查是否对应真实未标注目标

论文发现:部分”假阳性”实际对应了 nuScenes 标注中遗漏的移动目标。


实验结果

nuScenes 性能

指标 PART 对比方法 提升
CA-AP 0.8827 基线 0.82 +7.6%
mASTE 0.3188m 基线 0.45m -29%
mAVE 0.8084m/s 基线 1.2m/s -33%
参数量 1.1M 基线 10M+ -90%
稀有类别召回 0.9203 基线 0.75 +23%

环境鲁棒性

条件 性能下降 说明
夜间 <2% 雷达不依赖光照
雨天 <3% 雷达穿透雨滴
严重遮挡 <5% 雷达穿透部分遮挡
逆光 0% 无视觉干扰

IMS 座舱应用

1. CPD 儿童检测

检测目标 雷达信号特征 PART 适用性
儿童呼吸 微多普勒 ~0.1-0.5 m/s ⚠️ 需优化极低速度检测
儿童移动 多普勒 0.5-3 m/s ✅ 直接适用
无人座椅 零多普勒 ✅ 存在性=0
物品放置 零多普勒(静止) ✅ 不会被误检

2. 乘员分类

3. 与现有 CPD 方案对比

方案 检测维度 精度 隐私 成本 部署难度
PART 雷达 移动+存在 ⭐⭐⭐⭐ ✅ 中 中
60GHz FMCW 距离+速度 ⭐⭐⭐⭐ ✅ 低 低
摄像头 视觉特征 ⭐⭐⭐⭐⭐ ❌ 低 中
重力传感器 重量 ⭐⭐⭐ ✅ 极低 低
温度传感器 热源 ⭐⭐ ✅ 极低 低

硬件部署建议

组件 型号 参数 用途
雷达 TI IWR6843AOP 60GHz, 4T4R, 多普勒分辨率 0.1m/s 座舱雷达
替代 Infineon BGT60TR13C 60GHz, 3Tx/3Rx, 小型化 座舱集成
处理器 QCS8255 (共享) Hexagon NPU PART 推理
模型大小 ~4.5MB (量化后) INT8 1.1M params

部署可行性评估

指标 要求 PART 性能 评估
参数量 <5M 1.1M ✅ 优秀
推理速度 >30FPS 估计 <10ms ✅ 足够
精度 AP >0.85 0.8827 ✅ 达标
功耗 <2W 预计 <1W ✅ 低功耗
全天候 必须 夜间/雨天鲁棒 ✅ 优势

IMS 开发启示

启示 建议行动 优先级
1.1M 参数极轻量 可与 DMS 算法共用 QCS8255 🔴 高
类不可知检测 适合 CPD(不依赖特定目标类别) 🔴 高
多普勒物理感知 儿童呼吸微多普勒需调优 🟡 中
夜间/遮挡鲁棒 补充视觉 DMS 的遮挡盲区 🔴 高
将开源代码 优先跟踪 GitHub 代码发布 🟡 中

后续研究计划

  1. 微多普勒优化:当前 PART 针对车辆级移动目标(>1m/s),需优化到呼吸级(~0.1m/s)
  2. 座舱场景数据:nuScenes 是室外自动驾驶场景,需在座舱内采集数据
  3. 多雷达融合:座舱内可部署多个 60GHz 雷达,利用 PART 的类不可知特性
  4. 与视觉融合:PART 检测移动目标 + 视觉识别具体类别

总结

PART 的核心价值在于用极轻量模型(1.1M 参数)实现了纯雷达的类不可知移动目标检测。其物理感知设计使其在夜间、雨天和遮挡场景中表现优异,这些正是视觉方法的弱点。

对 IMS 而言,PART 可作为 CPD 检测的雷达基座模型:

  • 检测”是否有移动目标”(存在性)→ CPD 第一步
  • 估计”目标在哪”(位置)→ 定位精度 0.32m
  • 判断”目标多快”(速度)→ 区分呼吸/活动/无人

但需要针对座舱场景进行微多普勒优化和室内数据采集。


论文链接:https://arxiv.org/abs/2609.02289
代码:https://github.com/sunyinghao-uestc/PART(即将开源)
投稿目标:ICRA 2027