EEG脑电信号驾驶员疲劳分析:改进TSception模型 | arXiv 2025 论文解读

论文信息

核心创新

改进 TSception 模型同时分析驾驶员疲劳状态和认知工作负荷,使用EEG脑电信号。模型通过时空特征提取网络同时捕捉大脑不同区域的时序动态和空间关联。

技术背景

EEG在DMS中的价值

维度 摄像头方案 EEG方案 优势对比
疲劳检测 间接(眼部特征) 直接(脑电变化) EEG更早
认知负荷 无法检测 直接检测 EEG独有
预警提前量 2-5秒 10-30秒 EEG大幅领先
接触方式 非接触 需电极 摄像头优
部署难度 低 极高 摄像头优

核心挑战

  • 接触式: 需要电极贴附,不适合日常驾驶
  • 信号噪声: 车辆振动/电磁干扰严重
  • 个体差异: 脑电模式因人而异
  • 实时性: 需要实时推理低延迟

方法详解

1. TSception 架构

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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
"""
Modified TSception: EEG脑电信号驾驶员疲劳与认知负荷分析
基于: arXiv 2512.21747 (2025)

TSception 核心思想:
- 时间维度: 捕捉EEG信号的时序动态
- 空间维度: 捕捉大脑不同区域的空间关联
- 双流网络: 分别处理后融合
"""

import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from typing import Tuple


class TemporalBlock(nn.Module):
"""时间特征提取块"""

def __init__(
self,
in_channels: int,
num_filters: int = 32,
kernel_sizes: Tuple[int, ...] = (15, 31, 63)
):
super().__init__()
# 多尺度时间卷积
self.branches = nn.ModuleList([
nn.Sequential(
nn.Conv2d(in_channels, num_filters, (1, k), padding=(0, k//2)),
nn.BatchNorm2d(num_filters),
nn.ELU(inplace=True),
)
for k in kernel_sizes
])
# 融合
self.fusion = nn.Sequential(
nn.Conv2d(num_filters * len(kernel_sizes), num_filters, 1),
nn.BatchNorm2d(num_filters),
nn.ELU(inplace=True),
)

def forward(self, x):
# x: (B, C, T, 1) C=通道数, T=时间步
outs = [branch(x) for branch in self.branches]
out = torch.cat(outs, dim=1)
return self.fusion(out)


class SpatialBlock(nn.Module):
"""空间特征提取块"""

def __init__(
self,
in_channels: int,
num_electrodes: int = 32,
num_filters: int = 32
):
super().__init__()
# 空间卷积: 跨电极通道
self.spatial_conv = nn.Sequential(
nn.Conv2d(in_channels, num_filters,
(num_electrodes, 1)),
nn.BatchNorm2d(num_filters),
nn.ELU(inplace=True),
)

def forward(self, x):
# x: (B, C, T, 1)
# 空间卷积: (num_electrodes, 1) → 融合所有电极
return self.spatial_conv(x)


class ModifiedTSception(nn.Module):
"""
改进版 TSception 模型

输入: EEG信号 (B, num_electrodes, T)
输出:
- 疲劳等级 (0: 清醒, 1: 轻度, 2: 中度, 3: 重度)
- 认知负荷 (0: 低, 1: 中, 2: 高)

改进点:
1. 多尺度时间卷积 (15/31/63)
2. 空间注意力机制
3. 双任务输出 (疲劳+认知负荷)
4. 域对抗训练 (个体差异消除)
"""

def __init__(
self,
num_electrodes: int = 32,
sampling_rate: int = 250,
num_classes_drowsy: int = 4,
num_classes_workload: int = 3
):
super().__init__()
self.num_electrodes = num_electrodes

# 时间块 (多尺度)
self.temporal = TemporalBlock(
in_channels=num_electrodes,
num_filters=32,
kernel_sizes=(15, 31, 63)
)

# 空间块
self.spatial = SpatialBlock(
in_channels=32,
num_electrodes=1, # 时间块后已变化
num_filters=64
)

# 空间注意力
self.spatial_attn = nn.Sequential(
nn.Linear(64, 32),
nn.ReLU(inplace=True),
nn.Linear(32, 64),
nn.Sigmoid()
)

# 时间注意力
self.temporal_attn = nn.Sequential(
nn.Linear(64, 32),
nn.ReLU(inplace=True),
nn.Linear(32, 64),
nn.Sigmoid()
)

# 疲劳分类头
self.drowsy_head = nn.Sequential(
nn.AdaptiveAvgPool2d(1),
nn.Flatten(),
nn.Linear(64, 128),
nn.ELU(inplace=True),
nn.Dropout(0.5),
nn.Linear(128, num_classes_drowsy)
)

# 认知负荷分类头
self.workload_head = nn.Sequential(
nn.AdaptiveAvgPool2d(1),
nn.Flatten(),
nn.Linear(64, 128),
nn.ELU(inplace=True),
nn.Dropout(0.5),
nn.Linear(128, num_classes_workload)
)

# 域对抗分类器 (个体差异)
self.domain_head = nn.Sequential(
nn.Linear(64, 32),
nn.ReLU(inplace=True),
nn.Linear(32, 10), # 10个受试者
nn.LogSoftmax(dim=1)
)

def forward(self, x):
"""
Args:
x: EEG信号 (B, num_electrodes, T)
B=batch, T=时间步
"""
# (B, E, T) -> (B, E, T, 1)
x = x.unsqueeze(-1)

# 1. 时间特征 (多尺度)
t_feat = self.temporal(x) # (B, 32, T, 1)

# 2. 空间特征
s_feat = self.spatial(t_feat) # (B, 64, 1, 1)

# 3. 注意力增强
# 空间注意力
s_flat = s_feat.view(s_feat.size(0), -1) # (B, 64)
s_attn = self.spatial_attn(s_flat)
s_feat = s_feat * s_attn.view(s_feat.size(0), -1, 1, 1)

# 4. 分类
drowsy_out = self.drowsy_head(s_feat)
workload_out = self.workload_head(s_feat)
domain_out = self.domain_head(s_feat.view(s_feat.size(0), -1))

return {
'drowsiness': drowsy_out,
'workload': workload_out,
'domain': domain_out # 用于域对抗训练
}


class TSceptionLoss(nn.Module):
"""多任务损失 (疲劳+认知负荷+域对抗)"""

def __init__(self, alpha=1.0, beta=0.5, gamma=0.1):
super().__init__()
self.alpha = alpha # 疲劳
self.beta = beta # 认知负荷
self.gamma = gamma # 域对抗 (梯度反转)

def forward(self, outputs, targets):
drowsy_loss = F.cross_entropy(
outputs['drowsiness'], targets['drowsiness']
)
workload_loss = F.cross_entropy(
outputs['workload'], targets['workload']
)
# 域对抗: 最大化域分类损失 (梯度反转)
domain_loss = -F.nll_loss(
outputs['domain'], targets['domain']
)

total = (
self.alpha * drowsy_loss +
self.beta * workload_loss +
self.gamma * domain_loss
)

return total, {
'drowsy': drowsy_loss.item(),
'workload': workload_loss.item(),
'domain': domain_loss.item()
}


# ============ 测试 ============

if __name__ == "__main__":
print("=" * 60)
print("Modified TSception EEG 分析")
print("=" * 60)

model = ModifiedTSception(
num_electrodes=32,
sampling_rate=250
)

# 模拟EEG: 32通道, 250Hz, 2秒
eeg = torch.randn(4, 32, 500)

outputs = model(eeg)

print(f"输入: {eeg.shape}")
print(f"疲劳: {outputs['drowsiness'].shape}")
print(f"认知负荷: {outputs['workload'].shape}")
print(f"域: {outputs['domain'].shape}")

# 参数量
params = sum(p.numel() for p in model.parameters())
print(f"\n参数量: {params:,}")

# 推理速度
import time
times = []
model.eval()
with torch.no_grad():
for _ in range(50):
t0 = time.time()
_ = model(eeg)
times.append((time.time() - t0) * 1000)

print(f"推理延迟: {np.median(times):.2f}ms")
print(f"吞吐率: {1000/np.median(times):.0f} samples/s")

2. EEG电极配置

部位 电极 检测目标
额叶 F3, F4, Fz, F7, F8 注意力/执行功能
中央 C3, C4, Cz 运动相关
顶叶 P3, P4, Pz 视觉/空间
枕叶 O1, O2 视觉处理
颞叶 T3, T4, T5, T6 记忆/情绪

3. 疲劳EEG特征

频段 频率范围 疲劳时变化 含义
Delta 0.5-4 Hz ↑↑ 深度睡眠
Theta 4-8 Hz ↑ 困倦/微睡眠
Alpha 8-13 Hz ↑ 放松/闭眼
Beta 13-30 Hz ↓ 注意力下降
Gamma 30-100 Hz ↓ 高级认知减少

实验结果

性能对比

方法 疲劳准确率 认知负荷准确率 参数量
SVM 78.3% 71.2% -
CNN-1D 85.6% 78.9% 1.2M
原始TSception 88.2% 82.1% 0.8M
Modified TSception 91.5% 86.3% 1.1M

疲劳预警提前量

方法 预警时间 准确率
摄像头(PERCLOS) 2-5秒 92%
摄像头(行为) 3-8秒 85%
EEG(TSception) 15-30秒 91.5%

IMS 开发启示

1. EEG作为DMS补充的价值

  • 认知负荷检测:摄像头无法替代的能力
  • 早期预警:比面部特征提前10-25秒
  • 多模态融合:EEG+摄像头可显著提升

2. 非接触EEG方向

方案 接触方式 可行性
头带电极 额头贴附 中(需佩戴)
座椅电极 头枕接触 低(信号差)
耳电极 耳道 中(需耳机)
毫米波雷达 非接触 低(精度不够)

3. 与IMS的融合建议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 多模态融合: EEG + 摄像头
class MultiModalFatigue:
def __init__(self):
self.eeg_model = ModifiedTSception()
self.camera_model = DrowsinessCNN()
self.fusion_weight_eeg = 0.4
self.fusion_weight_cam = 0.6

def predict(self, eeg, face_img):
eeg_out = self.eeg_model(eeg)['drowsiness']
cam_out = self.camera_model(face_img)

# 加权融合
fused = (
self.fusion_weight_eeg * F.softmax(eeg_out, dim=-1) +
self.fusion_weight_cam * F.softmax(cam_out, dim=-1)
)
return fused

总结

改进TSception在EEG疲劳+认知负荷检测上达到91.5%/86.3%,比原始TSception提升3.3%/4.2%。虽然EEG目前接触式限制明显,但其早期预警能力(15-30秒)是摄像头方案无法替代的。

对 IMS 的价值:

  • 认知负荷检测是摄像头方案的盲区,EEG是唯一直接方案
  • 域对抗训练消除个体差异的思路可借鉴
  • 未来非接触EEG成熟后可直接集成

https://dapalm.com/2026/10/04/2026-10-04-007-modified-tsception-eeg-drowsiness-mental-workload-arxiv2025/
作者
Mars
发布于
2026年10月4日
许可协议