动态疲劳检测注意力增强CNN:实时监测与Euro NCAP合规

动态疲劳检测注意力增强CNN:实时监测与Euro NCAP合规

来源:ResearchGate (June 2026)
链接:https://www.researchgate.net/publication/406955713_Dynamic_driver_drowsiness_detection_with_attention_enhanced_convolutional_neural_networks_for_real_time_monitoring_and_road_safety_applications

核心创新

注意力增强CNN实现动态疲劳检测

  • 准确率:95.8%
  • 实时性:实时推理(30+ FPS)
  • 注意力机制:SE-Net + CBAM融合

技术架构

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
import torch
import torch.nn as nn

class AttentionEnhancedCNN(nn.Module):
"""
注意力增强CNN疲劳检测模型

架构:
- Backbone: ResNet-18
- 注意力: SE-Net + CBAM
- 动态时序: LSTM
"""

def __init__(self, num_classes=3): # 清醒/轻度疲劳/重度疲劳
super().__init__()

# Backbone
self.backbone = self._make_backbone()

# SE-Net注意力
self.se_attention = SE_Block(512, 16)

# CBAM注意力
self.cbam = CBAM(512)

# 时序模块
self.lstm = nn.LSTM(512, 256, num_layers=2, batch_first=True)

# 分类头
self.classifier = nn.Linear(256, num_classes)

def forward(self, x_sequence):
"""
Args:
x_sequence: (B, T, 3, 224, 224) 视频序列

Returns:
logits: (B, num_classes)
"""
B, T, C, H, W = x_sequence.shape

# 逐帧特征提取
frame_features = []
for t in range(T):
frame = x_sequence[:, t] # (B, 3, 224, 224)

# Backbone特征
feat = self.backbone(frame) # (B, 512, 7, 7)

# SE注意力
feat = self.se_attention(feat)

# CBAM注意力
feat = self.cbam(feat)

# 全局池化
feat = feat.mean(dim=[2, 3]) # (B, 512)

frame_features.append(feat)

# 堆叠为序列
sequence = torch.stack(frame_features, dim=1) # (B, T, 512)

# LSTM时序建模
lstm_out, _ = self.lstm(sequence) # (B, T, 256)

# 取最后时刻
final_feat = lstm_out[:, -1] # (B, 256)

# 分类
return self.classifier(final_feat)

def _make_backbone(self):
"""构建ResNet-18 backbone"""
import torchvision.models as models
resnet = models.resnet18(pretrained=True)
# 移除全连接层
backbone = nn.Sequential(*list(resnet.children())[:-2])
return backbone


class SE_Block(nn.Module):
"""
Squeeze-and-Excitation注意力

通道注意力机制
"""

def __init__(self, channels, reduction=16):
super().__init__()
self.squeeze = nn.AdaptiveAvgPool2d(1)
self.excitation = nn.Sequential(
nn.Linear(channels, channels // reduction),
nn.ReLU(),
nn.Linear(channels // reduction, channels),
nn.Sigmoid()
)

def forward(self, x):
B, C, H, W = x.shape
# Squeeze
squeezed = self.squeeze(x).view(B, C)
# Excitation
scale = self.excitation(squeezed).view(B, C, 1, 1)
# Scale
return x * scale


class CBAM(nn.Module):
"""
Convolutional Block Attention Module

通道+空间双注意力
"""

def __init__(self, channels):
super().__init__()
self.channel_attention = ChannelAttention(channels)
self.spatial_attention = SpatialAttention()

def forward(self, x):
# 通道注意力
x = self.channel_attention(x)
# 空间注意力
x = self.spatial_attention(x)
return x


class ChannelAttention(nn.Module):
"""通道注意力"""

def __init__(self, channels, reduction=16):
super().__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.max_pool = nn.AdaptiveMaxPool2d(1)
self.fc = nn.Sequential(
nn.Linear(channels, channels // reduction),
nn.ReLU(),
nn.Linear(channels // reduction, channels)
)
self.sigmoid = nn.Sigmoid()

def forward(self, x):
B, C, H, W = x.shape
avg_out = self.fc(self.avg_pool(x).view(B, C))
max_out = self.fc(self.max_pool(x).view(B, C))
scale = self.sigmoid(avg_out + max_out).view(B, C, 1, 1)
return x * scale


class SpatialAttention(nn.Module):
"""空间注意力"""

def __init__(self, kernel_size=7):
super().__init__()
self.conv = nn.Conv2d(2, 1, kernel_size, padding=kernel_size//2)
self.sigmoid = nn.Sigmoid()

def forward(self, x):
avg_out = x.mean(dim=1, keepdim=True)
max_out = x.max(dim=1, keepdim=True)[0]
concat = torch.cat([avg_out, max_out], dim=1)
scale = self.sigmoid(self.conv(concat))
return x * scale

实验结果

性能对比

方法 准确率 FPS 参数量
ResNet-18基线 91.2% 35 11M
+SE-Net 93.5% 33 11.2M
+CBAM 94.1% 32 11.3M
+LSTM 95.8% 30 15M

Euro NCAP疲劳检测场景

场景 检测率 延迟
F-01 微睡眠 96.2% 2.1s
F-02 长时间闭眼 98.5% 1.8s
F-03 频繁眨眼 94.3% 2.5s
F-04 眼睑下垂 95.7% 2.2s

IMS部署优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def optimize_for_ims():
"""
IMS部署优化

目标:
- 模型<10MB
- FPS>30
- 功耗<500mW
"""
model = AttentionEnhancedCNN()

# 1. 知识蒸馏
student = LightweightNet()
distill_train(model, student)

# 2. 量化
quantized = torch.quantization.quantize_dynamic(
student, {nn.Linear, nn.LSTM}, dtype=torch.qint8
)

# 3. 导出ONNX
torch.onnx.export(quantized, dummy_input, 'drowsiness.onnx')

return quantized

参考文献

  1. Dynamic driver drowsiness detection with attention enhanced CNN. ResearchGate (2026).

总结: 注意力增强CNN在保持实时性的同时提升疲劳检测精度,适合部署到车载嵌入式系统。


动态疲劳检测注意力增强CNN:实时监测与Euro NCAP合规
https://dapalm.com/2026/08/03/2026-08-03-dynamic-drowsiness-detection-attention-enhanced-cnn-2026/
作者
Mars
发布于
2026年8月3日
许可协议