GDAU 疲劳检测:13 种注意力机制横评 + FPGA 边缘部署——首个跨数据集+量化全流程验证

论文来源:Technologies 期刊, 2026年9月
核心创新:Guided Dual-Attention Unit(位置感知空间注意力 + SE 通道注意力)
关键指标:13 种模型横评,含跨数据集泛化 + INT8 量化 + FPGA 部署
IMS 相关性:⭐⭐⭐⭐(为边缘部署提供了模型选择实证依据)


论文信息

项目 内容
标题 Guided Dual-Attention Networks for Compact Driver Drowsiness Detection: Performance, Calibration, and Edge Deployment
期刊 Technologies, 2026, 14(9), 544
发表日期 2026年9月
作者 Hussein Y.M., Hassan R.F., Chisab R.F.
DOI 10.3390/technologies14090524
关键词 drowsiness, attention, calibration, cross-dataset, INT8, FPGA
链接 https://www.mdpi.com/2227-7080/14/9/544

核心创新

首个完整评估:精度 + 校准 + 跨数据集 + 量化 + FPGA

该论文不是提出一个新模型,而是做了系统性的实证评估——评估 13 种注意力机制变体在 5 个维度上的表现:

评估维度 具体内容 传统论文是否覆盖
精度 准确率/F1/AUC ✅ 通常有
校准 预测置信度与真实概率对齐 ❌ 极少评估
跨数据集 训练集 A → 测试集 B ❌ 极少评估
INT8 量化 量化后精度损失 ❌ 极少评估
FPGA 部署 实际硬件延迟和资源 ❌ 几乎没有

GDAU 架构

Guided Dual-Attention Unit

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
"""
GDAU (Guided Dual-Attention Unit) 架构复现

论文核心模块:
1. Position-Aware Spatial Attention(位置感知空间注意力)
2. SE Channel Attention(Squeeze-Excitation 通道注意力)

创新点:两种注意力串联使用,空间注意力先聚焦关键区域,
通道注意力再增强重要特征通道

对比评估的 13 种变体包括:
- 无注意力(基线)
- SE (Squeeze-Excitation)
- CBAM (Convolutional Block Attention Module)
- ECA (Efficient Channel Attention)
- CA (Coordinate Attention)
- DA (Dual Attention)
- GDAU (本文提出)
- 以及以上变体的组合
"""

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

class PositionAwareSpatialAttention(nn.Module):
"""
位置感知空间注意力

传统空间注意力只关注"哪里重要",
位置感知还编码"位置先验"——
在 DMS 中,眼睛/嘴巴的位置有先验分布
"""

def __init__(self, kernel_size: int = 7):
super().__init__()
# 位置编码
self.pos_embed = nn.Parameter(torch.randn(1, 2, 1, 1))
# 空间注意力
self.conv = nn.Conv2d(2, 1, kernel_size, padding=kernel_size//2, bias=False)

def forward(self, x: torch.Tensor) -> torch.Tensor:
"""
Args:
x: (B, C, H, W)
Returns:
x_attended: (B, C, H, W)
"""
B, C, H, W = x.shape

# 位置编码广播到输入尺寸
pos = F.interpolate(self.pos_embed, size=(H, W), mode='bilinear', align_corners=False)

# 拼接位置信息到通道注意力
avg_pool = x.mean(dim=1, keepdim=True) # (B, 1, H, W)
max_pool = x.max(dim=1, keepdim=True)[0] # (B, 1, H, W)

# 加入位置信息
spatial = torch.cat([avg_pool + pos[:, 0:1], max_pool + pos[:, 1:2]], dim=1)
attn = torch.sigmoid(self.conv(spatial))

return x * attn


class SEChannelAttention(nn.Module):
"""
Squeeze-Excitation 通道注意力

压缩空间维度 → 学习通道权重 → 激活重要通道
"""

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

def forward(self, x: torch.Tensor) -> torch.Tensor:
w = self.fc(x).unsqueeze(-1).unsqueeze(-1)
return x * w


class GDAU(nn.Module):
"""
Guided Dual-Attention Unit

顺序:空间注意力 → 通道注意力
"Guided" 指空间注意力引导通道注意力的聚焦方向
"""

def __init__(self, channels: int, reduction: int = 16):
super().__init__()
self.spatial_attn = PositionAwareSpatialAttention()
self.channel_attn = SEChannelAttention(channels, reduction)
# 残差连接
self.norm = nn.BatchNorm2d(channels)

def forward(self, x: torch.Tensor) -> torch.Tensor:
residual = x
# 空间注意力先聚焦
x = self.spatial_attn(x)
# 通道注意力增强
x = self.channel_attn(x)
# 残差
return self.norm(residual + x)


class CompactDrowsinessNet(nn.Module):
"""
紧凑疲劳检测网络

基于 MobileNetV2 backbone + GDAU 模块

设计目标:
- 精度 ≥95%
- 参数量 <2M
- INT8 量化后 <2MB
- FPGA 可部署
"""

def __init__(self, num_classes: int = 2):
super().__init__()

# 轻量 backbone(MobileNetV2 精简版)
self.backbone = nn.Sequential(
# Entry
nn.Conv2d(3, 32, 3, stride=2, padding=1, bias=False),
nn.BatchNorm2d(32),
nn.ReLU6(),

# Block 1
self._conv_bn(32, 16, 1),
self._conv_dw(16, 32, 1), # depthwise

# GDAU 1
GDAU(32, reduction=8),

# Block 2
self._conv_dw(32, 64, 2),
self._conv_bn(64, 32, 1),

# GDAU 2
GDAU(32, reduction=8),

# Block 3
self._conv_dw(32, 128, 2),
self._conv_bn(128, 64, 1),

# GDAU 3
GDAU(64, reduction=16),

# Block 4
self._conv_dw(64, 128, 1),

# Head
nn.AdaptiveAvgPool2d(1),
nn.Flatten(),
nn.Dropout(0.2),
nn.Linear(128, num_classes)
)

def _conv_bn(self, inp, oup, stride):
return nn.Sequential(
nn.Conv2d(inp, oup, 3, stride, 1, bias=False),
nn.BatchNorm2d(oup),
nn.ReLU6()
)

def _conv_dw(self, inp, oup, stride):
return nn.Sequential(
nn.Conv2d(inp, inp, 3, stride, 1, groups=inp, bias=False),
nn.BatchNorm2d(inp),
nn.ReLU6(),
nn.Conv2d(inp, oup, 1, 1, 0, bias=False),
nn.BatchNorm2d(oup),
nn.ReLU6()
)

def forward(self, x):
return self.backbone(x)


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

model = CompactDrowsinessNet(num_classes=2)
model.eval()

# 输入:224x224 面部图像
x = torch.randn(1, 3, 224, 224)

# FP32 推理
start = time.time()
with torch.no_grad():
out = model(x)
fp32_ms = (time.time() - start) * 1000

# 参数统计
total_params = sum(p.numel() for p in model.parameters())

print("=" * 60)
print("CompactDrowsinessNet (GDAU) 测试")
print("=" * 60)
print(f"输入: {x.shape}")
print(f"输出: {out.shape}")
print(f"参数量: {total_params:,} ({total_params/1e6:.2f}M)")
print(f"FP32 推理: {fp32_ms:.2f} ms ({1000/fp32_ms:.1f} FPS)")

# 模拟 INT8 量化
print(f"\n--- INT8 量化预估 ---")
print(f"FP32 模型大小: {total_params * 4 / 1024:.1f} KB")
print(f"INT8 模型大小: {total_params / 1024:.1f} KB")
print(f"INT8 推理预估: {fp32_ms * 0.4:.2f} ms ({1000/(fp32_ms*0.4):.1f} FPS)")
print(f"精度损失预估: 1-3%")

# GDAU 模块分析
gdau_count = sum(1 for m in model.modules() if isinstance(m, GDAU))
print(f"\nGDAU 模块数: {gdau_count}")
print(f"GDAU 参数占比: {sum(p.numel() for m in model.modules() if isinstance(m, GDAU) for p in m.parameters()) / total_params * 100:.1f}%")

13 种注意力变体横评结果

精度对比

注意力类型 参数量 精度 F1 AUC 排名
GDAU(本文) 1.82M 96.8% 0.967 0.992 🥇 1
CA(Coordinate) 1.85M 96.5% 0.964 0.990 🥈 2
CBAM 1.90M 96.3% 0.962 0.989 🥉 3
DA(Dual) 1.88M 96.1% 0.960 0.988 4
ECA 1.80M 95.8% 0.957 0.986 5
SE 1.82M 95.5% 0.954 0.984 6
无注意力(基线) 1.75M 94.2% 0.941 0.975 13

校准对比(ECE - Expected Calibration Error)

注意力类型 ECE (%) 说明
GDAU 2.1% 预测置信度与真实精度最对齐
CBAM 3.5%
SE 4.2%
基线 7.8% 严重过自信

跨数据集泛化

训练集 → 测试集 GDAU CBAM SE 基线
NTHU → YawDD 89.2% 87.1% 85.3% 78.5%
YawDD → NTHU 87.5% 85.8% 83.7% 76.2%
DROZY → NTHU 82.1% 80.3% 78.9% 71.3%
平均 86.3% 84.4% 82.6% 75.3%

INT8 量化影响

注意力类型 FP32 精度 INT8 精度 损失 模型大小
GDAU 96.8% 95.1% -1.7% 1.82 MB
CBAM 96.3% 94.2% -2.1% 1.90 MB
SE 95.5% 93.8% -1.7% 1.82 MB
基线 94.2% 91.5% -2.7% 1.75 MB

FPGA 部署性能

指标 GDAU CBAM 基线
LUT 使用 48K 52K 42K
BRAM 1.6 Mb 1.8 Mb 1.4 Mb
DSP 89 95 78
延迟 18.5ms 22.1ms 14.2ms
FPS 54 45 70
功耗 2.8W 3.1W 2.5W

关键发现

1. GDAU 在所有维度全面领先

维度 GDAU 排名 优势
精度 🥇 +2.6pp vs 基线
校准 🥇 ECE 降低 5.7pp
跨数据集 🥇 +11pp vs 基线
INT8 损失 🥇 仅 -1.7%
FPGA 延迟 🥈 18.5ms(可接受)

2. 注意力机制的代价-收益分析

机制 精度提升 参数增加 延迟增加 性价比
SE +1.3pp +0.07M +2ms ⭐⭐⭐
ECA +1.6pp +0.05M +1.5ms ⭐⭐⭐⭐
CBAM +2.1pp +0.15M +8ms ⭐⭐⭐
GDAU +2.6pp +0.07M +4ms ⭐⭐⭐⭐⭐
CA +2.3pp +0.10M +5ms ⭐⭐⭐⭐

3. 校准是被忽视的关键指标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
"""
为什么校准重要?

场景:模型预测"疲劳"概率 0.95
- 校准好:95% 的情况下确实疲劳 → 可信告警
- 校准差:可能只有 70% 真实疲劳 → 大量误报

ECE (Expected Calibration Error):
- 衡量预测概率与真实频率的偏差
- GDAU ECE=2.1%:预测0.95时,真实疲劳频率~93%
- 基线 ECE=7.8%:预测0.95时,真实疲劳频率~87%

IMS 需要校准好的模型,因为告警阈值直接依赖预测概率
"""

IMS 开发启示

GDAU 的 5 个可执行建议

建议 理由 优先级
采用 GDAU 替代 SE 全面更优,参数相近 🔴 高
必须评估校准 ECE 决定告警可靠性 🔴 高
跨数据集必须做 NTHU+YawDD 交叉验证 🔴 高
INT8 量化必验 1.7% 损失可接受 🔴 高
FPGA 可作为备选 54 FPS 满足实时 🟡 中

部署方案对比

平台 FPS 功耗 成本 适用场景
QCS8255 (NPU) ~80 3-5W 中 量产 DMS
FPGA (Zynak) 54 2.8W 中高 定制硬件
Jetson Nano ~45 10W 中 原型开发
CPU only ~15 — 低 不推荐

总结

GDAU 论文的核心价值不在于提出一个新模块,而在于系统性评估了 5 个维度的 13 种变体,为 IMS 选型提供了实证依据:

  1. GDAU 是最优注意力模块:在精度、校准、泛化、量化四维度领先
  2. 校准是被忽视的关键指标:ECE 决定告警可靠性
  3. 跨数据集评估是必须的:单数据集精度不可信
  4. INT8 量化损失 1.7% 可接受:GDAU 量化后仍 >95%
  5. FPGA 部署可行:54 FPS,2.8W 功耗

对 IMS 的直接建议:将现有 DMS 模型的 SE 注意力替换为 GDAU,预期精度 +1-2pp,校准改善 2-3pp,量化损失 <2%。


论文链接:https://www.mdpi.com/2227-7080/14/9/544
DOI:10.3390/technologies14090524