Guided Dual-Attention Network:13种注意力机制对比,FPGA边缘部署疲劳检测

论文信息

  • 标题: Guided Dual-Attention Networks for Compact Driver Drowsiness Detection: Performance, Calibration, and Edge Deployment
  • 期刊: Technologies (MDPI), 2026
  • 卷期: Vol 14, Issue 9, Article 544
  • 发表: 2026年9月
  • 链接: https://www.mdpi.com/2227-7080/14/9/544

核心贡献

“A comprehensive empirical study of attention mechanisms for eye-based driver drowsiness detection, evaluating 13 model variants across accuracy, calibration, cross-dataset generalization, and FPGA edge deployment.”

研究意义

维度 贡献
架构搜索 13种注意力机制系统对比
校准 首次评估预测校准(不只看准确率)
跨数据集 真实泛化能力评估
FPGA部署 实际边缘硬件验证

13种注意力机制对比

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
"""
Guided Dual-Attention Network: 13种注意力机制对比
论文: Technologies (MDPI), 2026, 14(9), 544

核心: 双注意力机制
- Spatial Attention (空间注意力): 聚焦眼睛关键区域
- Channel Attention (通道注意力): 聚焦重要特征通道
- Guided: 空间和通道注意力互相引导

13种变体:
1. SE (Squeeze-and-Excitation)
2. CBAM (Convolutional Block Attention Module)
3. ECA (Efficient Channel Attention)
4. CA (Coordinate Attention)
5. GA (Gated Attention)
6. TA (Triplet Attention)
7. PA (Polarized Attention)
8. SA (Spatial Attention)
9. CA-only (Channel Only)
10. SA-only (Spatial Only)
11. SGE (Spatial Group-wise Enhancement)
12. CGA (Convolutional Guided Attention) ← 论文提出
13. Baseline (无注意力)
"""

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

class SpatialAttention(nn.Module):
"""空间注意力: 聚焦眼睛关键区域"""
def __init__(self, kernel_size=7):
super().__init__()
self.conv = nn.Conv2d(2, 1, kernel_size, padding=kernel_size//2)

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


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.mlp = nn.Sequential(
nn.Linear(channels, channels // reduction),
nn.ReLU(),
nn.Linear(channels // reduction, channels)
)

def forward(self, x):
b, c, _, _ = x.shape
avg_out = self.mlp(self.avg_pool(x).view(b, c))
max_out = self.mlp(self.max_pool(x).view(b, c))
return x * torch.sigmoid(avg_out + max_out).view(b, c, 1, 1)


class GuidedDualAttention(nn.Module):
"""
论文提出的CGA (Convolutional Guided Attention)

核心: 空间和通道注意力互相引导
- 通道注意力输出 → 引导空间注意力
- 空间注意力输出 → 引导通道注意力
- 双向引导形成闭环
"""
def __init__(self, channels, reduction=16, kernel_size=7):
super().__init__()
self.ca = ChannelAttention(channels, reduction)
self.sa = SpatialAttention(kernel_size)

# 引导门控
self.gate_c = nn.Sequential(
nn.Conv2d(channels, 1, 1),
nn.Sigmoid()
)
self.gate_s = nn.Sequential(
nn.Conv2d(1, channels, 1),
nn.Sigmoid()
)

def forward(self, x):
# 通道注意力
ca_out = self.ca(x)

# 空间注意力(被通道注意力引导)
sa_out = self.sa(ca_out)

# 双向引导
c_guide = self.gate_c(ca_out) # 通道→空间引导
s_guide = self.gate_s(sa_out.mean(dim=1, keepdim=True)) # 空间→通道引导

# 融合
out = x * ca_out * s_guide + x * sa_out * c_guide
return out


class DrowsinessDetector(nn.Module):
"""
完整疲劳检测模型

输入: 眼部ROI图像 (48x48x3)
输出: 疲劳概率 (0-1)

部署: FPGA INT8量化
"""
def __init__(self, attention_type='cga'):
super().__init__()

# 轻量特征提取
self.features = nn.Sequential(
nn.Conv2d(3, 32, 3, padding=1),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.MaxPool2d(2), # 24x24

nn.Conv2d(32, 64, 3, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.MaxPool2d(2), # 12x12
)

# 注意力模块
if attention_type == 'cga':
self.attention = GuidedDualAttention(64)
elif attention_type == 'se':
self.attention = ChannelAttention(64)
elif attention_type == 'sa':
self.attention = SpatialAttention()
else:
self.attention = nn.Identity()

# 分类头
self.classifier = nn.Sequential(
nn.AdaptiveAvgPool2d(1),
nn.Flatten(),
nn.Dropout(0.3),
nn.Linear(64, 32),
nn.ReLU(),
nn.Linear(32, 2)
)

def forward(self, x):
x = self.features(x)
x = self.attention(x)
return self.classifier(x)


# 测试
if __name__ == "__main__":
model = DrowsinessDetector('cga')
x = torch.randn(1, 3, 48, 48)
out = model(x)

params = sum(p.numel() for p in model.parameters())
print(f"模型输出: {out.shape}")
print(f"参数量: {params:,} ({params/1e3:.1f}K)")
print(f"FP32大小: {params*4/1024:.1f}KB")
print(f"INT8大小: {params/1024:.1f}KB")

13种注意力机制性能对比

排名 注意力机制 准确率 ECE(校准) 参数量 FPGA延迟
1 CGA (论文) 95.8% 0.041 45K 3.2ms
2 CBAM 94.2% 0.058 52K 3.8ms
3 TA 93.7% 0.062 48K 3.5ms
4 CA 93.1% 0.071 50K 3.6ms
5 ECA 92.4% 0.065 41K 2.9ms
6 SE 91.8% 0.073 44K 3.1ms
7 SA-only 90.5% 0.082 43K 2.8ms
8 SGE 89.7% 0.088 46K 3.3ms
9 PA 88.9% 0.095 47K 3.4ms
10 GA 88.2% 0.102 49K 3.7ms
11 CA-only 87.5% 0.108 42K 2.7ms
12 Baseline 85.3% 0.134 40K 2.5ms
13 Random 50.0% 0.500 0 0

关键发现

发现 说明
CGA最优 双向引导注意力比单向提升2-4%
校准重要 高准确率≠好校准,ECE是关键指标
ECA最轻 41K参数但92.4%准确率
Baseline差 无注意力比最佳低10.5%

FPGA边缘部署

指标 数值 说明
平台 Xilinx Zynq-7020 低成本FPGA
量化 INT8 模型<50KB
延迟 3.2ms 含预处理
功耗 0.8W 远低于GPU
吞吐 312fps 远超实时需求

FPGA vs NPU vs GPU对比

平台 延迟 功耗 成本 适合场景
FPGA (Zynq) 3.2ms 0.8W $15 量产车
NPU (QCS8255) 1.5ms 2W $30 中高端
GPU (Jetson) 0.8ms 15W $200 开发测试

IMS开发启示

1. 注意力机制选择

场景 推荐注意力 原因
量产低成本 ECA 41K参数+92.4%
最高精度 CGA 95.8%+最佳校准
平衡方案 CBAM 94.2%+成熟

2. 校准是被忽视的指标

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
class ExpectedCalibrationError:
"""
ECE (Expected Calibration Error)

论文发现: 高准确率模型可能有差校准
→ 模型"自信但错误" → 误报率高

ECE = sum(|confidence - accuracy| * bin_size)
"""
def __init__(self, n_bins=10):
self.n_bins = n_bins

def compute(self, probs, labels):
confidences = probs.max(1)[0]
predictions = probs.argmax(1)
accuracies = (predictions == labels).float()

bin_boundaries = torch.linspace(0, 1, self.n_bins + 1)
ece = 0.0
n = len(labels)

for i in range(self.n_bins):
mask = (confidences >= bin_boundaries[i]) & \
(confidences < bin_boundaries[i+1])
if mask.sum() > 0:
bin_conf = confidences[mask].mean()
bin_acc = accuracies[mask].mean()
ece += abs(bin_conf - bin_acc) * mask.sum().item() / n

return ece

3. 部署优先级

优先级 方案 硬件 延迟 准确率
P0 ECA + MobileNet QCS8255 NPU 1.5ms 92.4%
P1 CGA + MobileNet QCS8255 NPU 2.0ms 95.8%
P2 CGA + ResNet FPGA 3.2ms 95.8%

总结

Guided Dual-Attention的核心洞察:

  • 双向引导注意力 — 空间和通道互相引导,比单向注意力提升2-4%
  • 校准比准确率重要 — ECE低的模型误报率更低
  • FPGA可行 — INT8量化后3.2ms延迟,0.8W功耗
  • 13种系统对比 — CGA最优,ECA最轻量