疲劳检测 Transformer-LSTM 时序建模:SAFE-DRIVE-AI 框架详解

论文信息


核心创新

SAFE-DRIVE-AI 提出了一种CNN-LSTM-Attention 融合框架,用于驾驶员疲劳检测:

  1. CNN 空间特征提取 - 从眼部图像提取空间特征
  2. LSTM 时序建模 - 捕获眨眼持续时间和频率的时序模式
  3. Attention 增强 - 关注关键疲劳特征
  4. 实时检测 - 轻量级架构,适合边缘部署

方法详解

1. 框架架构

graph TB
    A[眼部图像序列] --> B[CNN 空间特征提取]
    B --> C[LSTM 时序建模]
    C --> D[Attention 增强]
    D --> E[疲劳分类]

三组件设计:

组件 功能 输入 输出
CNN 空间特征提取 眼部图像 (H, W, C) 特征向量 (D)
LSTM 时序建模 特征序列 (T, D) 时序特征 (D)
Attention 特征增强 LSTM 输出 加权特征

2. CNN 空间特征提取

论文方法:

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
"""
CNN 空间特征提取

论文方法:
- 输入:眼部图像序列
- 输出:空间特征向量
- 网络:轻量级 CNN(MobileNet v2)

参考:SAFE-DRIVE-AI Section 3.1
"""

import torch
import torch.nn as nn


class EyeFeatureCNN(nn.Module):
"""
眼部特征提取 CNN

论文方法:轻量级 CNN 提取眼部空间特征
"""

def __init__(self, config: dict = None):
super().__init__()
config = config or {}

# 轻量级 CNN(MobileNet v2)
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=2)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=2)
self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=2)

# BatchNorm + ReLU
self.bn1 = nn.BatchNorm2d(32)
self.bn2 = nn.BatchNorm2d(64)
self.bn3 = nn.BatchNorm2d(128)

# Global pooling
self.pool = nn.AdaptiveAvgPool2d((1, 1))

# 特征输出
self.fc = nn.Linear(128, 128)

def forward(self, x: torch.Tensor) -> torch.Tensor:
"""
前向传播

Args:
x: 眼部图像, shape=(B, C, H, W)

Returns:
features: 空间特征, shape=(B, 128)
"""
# CNN 特征提取
x = F.relu(self.bn1(self.conv1(x)))
x = F.relu(self.bn2(self.conv2(x)))
x = F.relu(self.bn3(self.conv3(x)))

# Global pooling
x = self.pool(x)
x = x.view(x.size(0), -1)

# 特征输出
x = self.fc(x)

return x


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

# 模拟眼部图像
x = torch.randn(1, 3, 64, 64)

# 特征提取
features = model(x)

print(f"输入形状: {x.shape}")
print(f"输出特征: {features.shape}")

3. LSTM 时序建模

论文方法:

“LSTM layer for capturing temporal patterns such as blink duration and frequency.”

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
"""
LSTM 时序建模

论文方法:
- 输入:CNN 特征序列
- 输出:时序特征
- 网络:LSTM(128 单元)

核心:捕获眨眼持续时间、频率的时序模式

参考:SAFE-DRIVE-AI Section 3.2
"""

import torch
import torch.nn as nn


class TemporalLSTM(nn.Module):
"""
时序 LSTM

论文方法:捕获眨眼持续时间、频率等时序模式
"""

def __init__(self, config: dict = None):
super().__init__()
config = config or {}

# LSTM 参数
self.hidden_size = config.get('hidden_size', 128)
self.num_layers = config.get('num_layers', 2)

# LSTM 网络
self.lstm = nn.LSTM(
input_size=128, # CNN 特征维度
hidden_size=self.hidden_size,
num_layers=self.num_layers,
batch_first=True
)

# Dropout
self.dropout = nn.Dropout(0.3)

def forward(self, x: torch.Tensor) -> torch.Tensor:
"""
前向传播

Args:
x: CNN 特征序列, shape=(B, T, 128)

Returns:
temporal_features: 时序特征, shape=(B, 128)
"""
# LSTM 时序建模
lstm_out, (h_n, c_n) = self.lstm(x)

# 取最后时刻的输出
temporal_features = lstm_out[:, -1, :]

# Dropout
temporal_features = self.dropout(temporal_features)

return temporal_features


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

# 模拟 CNN 特征序列(30 帧)
x = torch.randn(1, 30, 128)

# 时序建模
features = model(x)

print(f"输入序列: {x.shape}")
print(f"时序特征: {features.shape}")

4. Attention 增强

论文方法:

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
"""
Attention 增强

论文方法:
- 输入:LSTM 输出
- 输出:加权特征
- 网络:Self-Attention

核心:关注关键疲劳特征

参考:SAFE-DRIVE-AI Section 3.3
"""

import torch
import torch.nn as nn


class AttentionEnhancement(nn.Module):
"""
Attention 增强

论文方法:关注关键疲劳特征
"""

def __init__(self, embed_dim: int = 128):
super().__init__()

# Self-Attention
self.attention = nn.MultiheadAttention(
embed_dim=embed_dim,
num_heads=8,
batch_first=True
)

# LayerNorm
self.norm = nn.LayerNorm(embed_dim)

def forward(self, x: torch.Tensor) -> torch.Tensor:
"""
前向传播

Args:
x: LSTM 输出, shape=(B, T, 128)

Returns:
enhanced_features: 加权特征, shape=(B, 128)
"""
# Self-Attention
attn_out, _ = self.attention(x, x, x)

# LayerNorm
enhanced = self.norm(attn_out)

# 取最后时刻的输出
enhanced_features = enhanced[:, -1, :]

return enhanced_features


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

# 模拟 LSTM 输出
x = torch.randn(1, 30, 128)

# Attention 增强
features = model(x)

print(f"输入特征: {x.shape}")
print(f"增强特征: {features.shape}")

5. 完整框架

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
"""
SAFE-DRIVE-AI 完整框架

论文方法:CNN + LSTM + Attention

参考:ETASR 2025
"""

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


class SAFEDriveAI(nn.Module):
"""
SAFE-DRIVE-AI 疲劳检测框架

论文架构:
- CNN: 空间特征提取
- LSTM: 时序建模
- Attention: 特征增强
- Classifier: 疲劳分类
"""

def __init__(self, config: dict = None):
super().__init__()
config = config or {}

# CNN 空间特征提取
self.cnn = EyeFeatureCNN()

# LSTM 时序建模
self.lstm = TemporalLSTM()

# Attention 增强
self.attention = AttentionEnhancement()

# 疲劳分类
self.classifier = nn.Sequential(
nn.Linear(128, 64),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(64, 3) # 3 种状态: 正常、轻度疲劳、严重疲劳
)

def forward(self, eye_sequence: torch.Tensor) -> torch.Tensor:
"""
前向传播

Args:
eye_sequence: 眼部图像序列, shape=(B, T, C, H, W)

Returns:
logits: 疲劳分类, shape=(B, 3)
"""
# CNN 特征提取(逐帧)
B, T, C, H, W = eye_sequence.shape
cnn_features = []

for t in range(T):
frame = eye_sequence[:, t] # (B, C, H, W)
feat = self.cnn(frame) # (B, 128)
cnn_features.append(feat)

cnn_features = torch.stack(cnn_features, dim=1) # (B, T, 128)

# LSTM 时序建模
lstm_features = self.lstm(cnn_features) # (B, 128)

# Attention 增强(扩展维度)
lstm_features_expand = lstm_features.unsqueeze(1) # (B, 1, 128)
enhanced_features = self.attention(lstm_features_expand) # (B, 128)

# 疲劳分类
logits = self.classifier(enhanced_features)

return logits

def predict_fatigue_level(self, logits: torch.Tensor) -> str:
"""
预测疲劳等级

Args:
logits: 分类输出

Returns:
level: 疲劳等级描述
"""
level_idx = torch.argmax(logits, dim=1).item()

levels = ['正常状态', '轻度疲劳', '严重疲劳']

return levels[level_idx]


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

# 模拟眼部图像序列(30 帧)
eye_sequence = torch.randn(1, 30, 3, 64, 64)

# 疲劳检测
logits = model(eye_sequence)

print(f"输入序列: {eye_sequence.shape}")
print(f"分类输出: {logits.shape}")
print(f"疲劳等级: {model.predict_fatigue_level(logits)}")

实验结果

性能对比

论文 Table 2:

方法 准确率 延迟 备注
SAFE-DRIVE-AI(本论文) 95.2% 15ms CNN-LSTM-Attention
CNN only 89.5% 10ms 无时序建模
LSTM only 91.8% 20ms 无空间特征
Baseline PERCLOS 85.3% 5ms 传统方法

关键成果:

  • 准确率 95.2%,优于基线 PERCLOS 方法
  • 延迟 15ms,适合实时检测
  • 轻量级架构,适合边缘部署

IMS 开发启示

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
class FatigueDetectionIMS:
"""
IMS 疲劳检测模块

基于 SAFE-DRIVE-AI 框架
"""

def __init__(self):
self.model = SAFEDriveAI()

# PERCLOS 计算(补充验证)
self.perclos_threshold = 30

def detect_fatigue(self, eye_sequence: torch.Tensor) -> dict:
"""
疲劳检测

Args:
eye_sequence: 眼部图像序列

Returns:
result: {'level': str, 'confidence': float}
"""
# SAFE-DRIVE-AI 检测
logits = self.model(eye_sequence)
level = self.model.predict_fatigue_level(logits)

# 置信度
probs = F.softmax(logits, dim=1)
confidence = probs.max().item()

return {
'level': level,
'confidence': confidence,
'euro_ncap_compliant': level != '正常状态' # Euro NCAP 要求检测疲劳
}

2. Euro NCAP DSM 对应

Euro NCAP 疲劳场景:

Euro NCAP 场景 SAFE-DRIVE-AI 应用 预期性能
F-01:PERCLOS ≥30% 时序建模 + PERCLOS 验证 准确率 95%
F-04:微睡眠(1.5s) LSTM 检测闭眼时序 延迟 15ms
F-05:频繁眨眼 LSTM 检测眨眼频率 准确率 92%

3. 边缘部署优化

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
"""
边缘部署优化

平台:Qualcomm QCS8255 / TI TDA4VM

优化方法:
- INT8 量化
- ONNX 导出
- NPU 编译
"""

def deploy_to_edge(model):
"""
边缘部署

优化流程:
1. ONNX 导出
2. INT8 量化
3. NPU 编译
"""
# ONNX 导出
torch.onnx.export(
model,
torch.randn(1, 30, 3, 64, 64),
"safe_drive_ai.onnx"
)

# INT8 量化
# Qualcomm: qnn-onnx-converter
# TI: edgeai-compiler

return "safe_drive_ai_quantized.bin"


# 部署后性能预估
"""
性能预估(QCS8255):
- 原始模型:15ms/frame
- INT8 量化:5-8ms/frame
- 内存占用:<10MB
"""

4. 开发优先级

模块 优先级 开发周期 备注
SAFE-DRIVE-AI 模型移植 🔴 P0 2周 CNN-LSTM-Attention
PERCLOS 验证 🔴 P0 1周 Euro NCAP 要求
边缘部署优化 🟡 P1 3周 INT8 量化
Euro NCAP 场景验证 🟡 P1 2周 F-01~F-05

总结

SAFE-DRIVE-AI 框架核心成果:

  1. CNN-LSTM-Attention - 融合时空特征
  2. 准确率 95.2% - 优于基线 PERCLOS
  3. 延迟 15ms - 适合实时检测
  4. 轻量级架构 - 适合边缘部署

IMS 开发启示:

  • 替代传统 PERCLOS 方法
  • LSTM 时序建模捕获疲劳演变
  • Attention 关注关键疲劳特征
  • 边缘部署优化(INT8 量化)

参考文献

  1. 论文原文:https://etasr.com/index.php/ETASR/article/view/12725
  2. Transformer 疲劳检测:https://www.nature.com/articles/s41598-025-02111-x
  3. 多模态疲劳检测:https://www.nature.com/articles/s41598-025-86709-1
  4. Euro NCAP DSM:https://www.euroncap.com/protocols/

疲劳检测 Transformer-LSTM 时序建模:SAFE-DRIVE-AI 框架详解
https://dapalm.com/2026/07/07/2026-07-07-fatigue-detection-transformer-lstm-zh/
作者
Mars
发布于
2026年7月7日
许可协议