LTC-CGMN:轻量级时序卷积+跨粒度状态映射的DMS边缘部署框架

论文信息

项目 内容
标题 Visual measurement network for intelligent cockpit driving state combining lightweight temporal convolution and cross-granularity state mapping
作者 Ti Han(大连东软信息学院)
期刊 Frontiers in Mechanical Engineering
年份 2026
链接 Frontiers
数据集 3MDAD 多模态驾驶数据集
部署 NVIDIA Jetson Orin

核心创新

LTC-CGMN 解决了DMS实际部署的三大痛点:

  1. 轻量时序建模:深度可分离因果膨胀卷积(LTC),低算力捕获时序依赖
  2. 跨粒度状态映射:CGSM模块对齐细粒度头/手特征与粗粒度躯干特征
  3. 连续风险评估:NHTSA-AHP指导的连续驾驶员风险指数(DRI),替代离散分类

关键指标:

  • Top-1 准确率:96.37%(3MDAD 数据集 Day 子集,±0.24)
  • DRI预测RMSE:0.058
  • 推理速度:33.6 FPS(Jetson Orin,FP16/TensorRT,端到端延迟 29.8 ms)
  • 参数量:3.78M(5.46G FLOPs)

方法详解

1. 整体架构

2. CGSM 跨粒度状态映射

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
# 示意代码,不可直接运行(为解释论文 CGSM 模块思想的简化示意,非官方实现;论文未开源代码)
import torch
import torch.nn as nn
import torch.nn.functional as F

class CGSMModule(nn.Module):
"""
Cross-Granularity State Mapping (CGSM)

论文核心创新1: 对齐细粒度头/手特征与粗粒度躯干特征
通过跨注意力机制实现多粒度特征融合
"""

def __init__(
self,
head_dim: int = 128, # 头部特征维度
hand_dim: int = 128, # 手部特征维度
torso_dim: int = 256, # 躲干特征维度
output_dim: int = 256
):
super().__init__()

# 细粒度特征投影
self.head_proj = nn.Linear(head_dim, output_dim)
self.hand_proj = nn.Linear(hand_dim, output_dim)

# 粗粒度特征投影
self.torso_proj = nn.Linear(torso_dim, output_dim)

# 跨注意力(细→粗 和 粗→细)
self.cross_attn_fine_to_coarse = nn.MultiheadAttention(
output_dim, num_heads=8, batch_first=True
)
self.cross_attn_coarse_to_fine = nn.MultiheadAttention(
output_dim, num_heads=8, batch_first=True
)

# 融合层
self.fusion = nn.Sequential(
nn.Linear(output_dim * 3, output_dim),
nn.ReLU(),
nn.Dropout(0.1),
nn.Linear(output_dim, output_dim)
)

self.norm = nn.LayerNorm(output_dim)

def forward(
self,
head_feat: torch.Tensor,
hand_feat: torch.Tensor,
torso_feat: torch.Tensor
) -> torch.Tensor:
"""
Args:
head_feat: 头部特征 (B, T, head_dim)
hand_feat: 手部特征 (B, T, hand_dim)
torso_feat: 躯干特征 (B, T, torso_dim)
Returns:
fused: 跨粒度融合特征 (B, T, output_dim)
"""
# 投影到统一空间
h_head = self.head_proj(head_feat) # (B, T, D)
h_hand = self.hand_proj(hand_feat)
h_torso = self.torso_proj(torso_feat)

# 细→粗注意力(头/手查询躯干上下文)
fine = torch.cat([h_head, h_hand], dim=1) # (B, 2T, D)
coarse_enhanced, _ = self.cross_attn_fine_to_coarse(
h_torso, fine, fine
)

# 粗→细注意力(躯干查询细粒度细节)
fine_enhanced, _ = self.cross_attn_coarse_to_fine(
fine, h_torso, h_torso
)
fine_head_enhanced = fine_enhanced[:, :fine.shape[1]//2]
fine_hand_enhanced = fine_enhanced[:, fine.shape[1]//2:]

# 拼接融合
combined = torch.cat([
fine_head_enhanced.mean(dim=1, keepdim=True),
fine_hand_enhanced.mean(dim=1, keepdim=True),
coarse_enhanced
], dim=-1)

fused = self.fusion(combined)
fused = self.norm(fused)

return fused


# 测试CGSM
if __name__ == "__main__":
cgsm = CGSMModule(head_dim=128, hand_dim=128, torso_dim=256)

B, T = 4, 30
head = torch.randn(B, T, 128)
hand = torch.randn(B, T, 128)
torso = torch.randn(B, T, 256)

fused = cgsm(head, hand, torso)
print(f"CGSM输出: {fused.shape}")
print("✅ CGSM模块测试通过")

3. LTC 轻量时序卷积

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
# 示意代码,不可直接运行(为解释论文 LTC 模块思想的简化示意,非官方实现)
class LTCModule(nn.Module):
"""
Lightweight Temporal Convolution (LTC)

论文核心创新2: 深度可分离因果膨胀卷积
- 因果:只用过去信息(在线推理)
- 膨胀:大感受野、少参数
- 深度可分离:极低计算量
"""

def __init__(
self,
in_channels: int = 256,
hidden_channels: int = 128,
kernel_size: int = 3,
dilations: list = [1, 2, 4, 8],
dropout: float = 0.1
):
super().__init__()

self.layers = nn.ModuleList()

for dilation in dilations:
# 深度可分离因果膨胀卷积
padding = (kernel_size - 1) * dilation # 因果padding

block = nn.Sequential(
# 深度卷积(每通道独立)
nn.Conv1d(
in_channels if dilation == dilations[0] else hidden_channels,
hidden_channels,
kernel_size,
padding=padding,
dilation=dilation,
groups=hidden_channels if dilation == dilations[0]
else hidden_channels
),
# 点卷积(通道混合)
nn.Conv1d(hidden_channels, hidden_channels, 1),
nn.BatchNorm1d(hidden_channels),
nn.ReLU(),
nn.Dropout(dropout)
)
self.layers.append(block)

def forward(self, x: torch.Tensor) -> torch.Tensor:
"""
Args:
x: (B, T, C)
Returns:
out: (B, T, C)
"""
# 转换为 (B, C, T) 用于卷积
x = x.transpose(1, 2)

for layer in self.layers:
residual = x
x = layer(x)
x = x + residual[:, :, -x.shape[-1]:] # 残差连接

return x.transpose(1, 2) # (B, T, C)


# 测试LTC
if __name__ == "__main__":
ltc = LTCModule(in_channels=256, hidden_channels=128)

x = torch.randn(4, 30, 256)
out = ltc(x)
print(f"LTC输出: {out.shape}")

# 参数量对比
params = sum(p.numel() for p in ltc.parameters())
print(f"LTC参数量: {params:,} ({params/1e6:.2f}M)")

# 对比3D-CNN
conv3d_params = 3 * 3 * 3 * 128 * 128 * 3 # 约442K
print(f"等效3D卷积参数量: ~{conv3d_params:,}")
print(f"LTC仅为3D卷积的: {params/conv3d_params:.1%}")
print("✅ LTC模块测试通过")

4. 连续驾驶员风险指数(DRI)

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
# 示意代码,不可直接运行(为解释论文 DRI 预测思想的简化示意;类别划分与头结构为作者假设,非论文原始设计)
class DRIPredictor(nn.Module):
"""
Driver Risk Index (DRI) 预测器

论文核心创新3: NHTSA-AHP指导的连续风险评估
替代传统的离散状态分类(正常/疲劳/分心)
输出连续风险值(0-1),避免阶梯式跳变
"""

def __init__(self, input_dim: int = 256):
super().__init__()

# 离散状态分类头
self.classification_head = nn.Sequential(
nn.Linear(input_dim, 128),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(128, 5) # 5类: 正常/疲劳/分心/危险/其他
)

# 连续DRI回归头
self.dri_head = nn.Sequential(
nn.Linear(input_dim, 128),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(128, 1),
nn.Sigmoid() # 输出0-1
)

def forward(self, x: torch.Tensor) -> dict:
"""
Args:
x: 时序特征 (B, T, C)
Returns:
classification: 离散状态logits (B, T, 5)
dri: 连续风险指数 (B, T, 1)
"""
# 取最后一帧
last_frame = x[:, -1, :] # (B, C)

classification = self.classification_head(last_frame)
dri = self.dri_head(last_frame)

return {
'classification': classification,
'dri': dri,
'dri_level': self._dri_to_level(dri)
}

def _dri_to_level(self, dri: torch.Tensor) -> str:
"""将DRI值转换为风险等级"""
levels = []
for v in dri.squeeze().tolist():
if v < 0.2:
levels.append('安全')
elif v < 0.4:
levels.append('低风险')
elif v < 0.6:
levels.append('中风险')
elif v < 0.8:
levels.append('高风险')
else:
levels.append('危险')
return levels


# 完整LTC-CGMN模型
class LTCCGMN(nn.Module):
"""
完整 LTC-CGMN 模型

架构: backbone → CGSM → LTC → {分类 + DRI}
"""

def __init__(self):
super().__init__()

# 特征提取backbone(轻量)
self.backbone = nn.Sequential(
nn.Conv2d(3, 32, 3, stride=2, padding=1),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.Conv2d(32, 64, 3, stride=2, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.AdaptiveAvgPool2d((4, 4)),
nn.Flatten(),
nn.Linear(64 * 4 * 4, 256)
)

# CGSM跨粒度映射
self.cgsm = CGSMModule(
head_dim=128, hand_dim=128, torso_dim=256
)

# LTC时序卷积
self.ltc = LTCModule(in_channels=256, hidden_channels=128)

# 预测头
self.predictor = DRIPredictor(input_dim=128)

def forward(self, frames, head_kp, hand_kp, torso_feat):
"""
Args:
frames: 视频帧 (B, T, C, H, W)
head_kp: 头部关键点 (B, T, 128)
hand_kp: 手部关键点 (B, T, 128)
torso_feat: 躯干特征 (B, T, 256)
"""
B, T, C, H, W = frames.shape

# 提取每帧特征
frames_flat = frames.view(B * T, C, H, W)
visual_feat = self.backbone(frames_flat)
visual_feat = visual_feat.view(B, T, -1)

# CGSM跨粒度融合
fused = self.cgsm(head_kp, hand_kp, visual_feat)

# LTC时序建模
temporal = self.ltc(fused)

# 预测
results = self.predictor(temporal)

return results


# 测试完整模型
if __name__ == "__main__":
model = LTCCGMN()

B, T = 2, 16
frames = torch.randn(B, T, 3, 224, 224)
head = torch.randn(B, T, 128)
hand = torch.randn(B, T, 128)
torso = torch.randn(B, T, 256)

results = model(frames, head, hand, torso)

print("LTC-CGMN 完整模型测试")
print("=" * 40)
print(f"分类logits: {results['classification'].shape}")
print(f"连续DRI: {results['dri'].squeeze().tolist()}")
print(f"风险等级: {results['dri_level']}")

total = sum(p.numel() for p in model.parameters())
print(f"\n总参数量: {total:,} ({total/1e6:.2f}M)")
print("✅ 完整模型测试通过")

实验结果

1. 3MDAD数据集性能(论文 Table 2,Day 子集)

重模型对比(论文未给这些基线的参数量/FPS):

方法 Top-1准确率 DRI RMSE
I3D (3D-CNN) 89.26 ± 0.41 0.108 ± 0.004
TimeSformer 93.57 ± 0.32 0.079 ± 0.003
Uniformer 94.21 ± 0.30 —
Video-Mamba 94.82 ± 0.26 0.069 ± 0.003
Video-Swin 95.08 ± 0.28 0.072 ± 0.003
LTC-CGMN 96.37 ± 0.24 0.058 ± 0.002

LTC-CGMN 超过次优的 Video-Mamba 1.55 个百分点,DRI 回归误差也是所有方法中最低的。

2. DRI连续风险评估

指标 值 说明
DRI RMSE 0.058 连续风险预测精度
阶梯跳变抑制 平均最大瞬时DRI变化 0.777→0.122 离散类别映射 vs LTC-CGMN(论文原文数字)
NHTSA-AHP一致性 ✅ 专家AHP权重作为软标签先验,经知识蒸馏监督DRI

注意:论文明确说该方法”缓解而非完全消除”阶梯效应。

3. 边缘部署效率(论文 Table 3,Jetson Orin,FP16/TensorRT)

模型 参数量 延迟 FPS
C3D-light 8.23M 62.4 ms 16.0
MobileNetV3+BiLSTM 4.32M 41.5 ms 24.1
TSM 9.61M 48.7 ms 20.5
X3D-S 5.94M 35.2 ms 28.4
LTC-CGMN 3.78M 29.8 ms 33.6

在对比的轻量模型中,LTC-CGMN 参数量最少、延迟最低、FPS 最高。

IMS 开发启示

1. 轻量DMS架构选择

基于论文 Table 3 的边缘端实测(Jetson Orin, FP16/TensorRT):

方案 FPS 参数量 备注
LTC-CGMN 33.6 3.78M 论文自报最优,Top-1 96.37%
X3D-S 28.4 5.94M 论文未单独给Top-1(Table 3 只列效率)
MobileNetV3+BiLSTM 24.1 4.32M 同上
TSM 20.5 9.61M 同上
C3D-light 16.0 8.23M 同上

重模型(TimeSformer/Video-Swin/Uniformer/Video-Mamba)论文只给了精度、未给边缘端效率数据,无法评估其 Jetson Orin 实时性。

2. 连续风险评估的价值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 示意代码,不可直接运行(仅为概念对比笔记)
# 传统离散分类 vs LTC-CGMN连续DRI

traditional_dms = {
'approach': '离散分类: 正常→疲劳→危险',
'problem': '阶梯跳变,无法平滑过渡',
'example': 'PERCLOS 29% → "正常" / PERCLOS 31% → "疲劳"',
'risk': '边界附近频繁切换状态,误报率高'
}

ltc_cgmn_dri = {
'approach': '连续DRI: 0.0(安全)→1.0(危险)',
'advantage': '平滑过渡,无阶梯跳变',
'example': 'PERCLOS 29% → DRI=0.28 / PERCLOS 31% → DRI=0.32',
'benefit': '可设阈值+滞回,减少误报'
}

3. NHTSA-AHP风险框架

论文的做法:按 NHTSA(美国国家公路交通安全管理局)的三维分心分类,邀请专家用 AHP(层次分析法)对三个维度做两两比较,得到归一化权重向量,作为连续 DRI 的软标签先验,再通过知识蒸馏监督网络输出:

NHTSA 分心维度 在框架中的角色 IMS对应
视觉分心 AHP 三维度之一(专家加权) 视线偏离检测
手动分心 AHP 三维度之一(专家加权) 手部关键点
认知分心 AHP 三维度之一(专家加权) 眼动模式分析

注意:具体权重数值由论文中的专家判断矩阵归一化得到,文中以动作类别为基础风险做加权线性组合(一致性检验通过);疲劳/饮水/抽烟等是 3MDAD 16 类动作中的独立类别,不是 AHP 的独立维度。

总结

LTC-CGMN 是 DMS 边缘部署的一个值得关注的方案:

  1. 3.78M参数+33.6FPS:在Jetson Orin上实现实时推理,对比的轻量基线中效率最优
  2. 96.37% Top-1:超过对比的重模型基线(Video-Swin 95.08%、Video-Mamba 94.82%)
  3. 连续DRI:替代离散分类,阶梯跳变显著缓解(瞬时DRI变化 0.777→0.122)
  4. 跨粒度融合:头/手细节+躯干上下文的对齐
  5. NHTSA-AHP框架:专家AHP权重作为软标签先验,经知识蒸馏监督DRI

对 IMS 的核心启示:轻量时序卷积+跨粒度融合在精度和边缘效率之间取得了好的平衡。按论文 Table 3,与 X3D-S(5.94M/28.4FPS)、TSM(9.61M/20.5FPS)等相比,LTC-CGMN 以更少参数拿到更高 FPS;连续DRI预测缓解了传统DMS在状态边界附近频繁误报的问题。