EEG解码框架用于自动驾驶乘客危险感知:3D-CRNN方法详解

论文信息

项目 内容
标题 EEG-Driven Decoding Framework for Passenger Hazard Perception in Highly Automated Vehicles
作者 Yingkai Yang, Ashton Yu Xuan Tan, Bowen Li, Xiaorong Gao, Sifa Zheng, Jianqiang Wang 等
期刊 Automotive Innovation(已接收)
年份 2026
链接 arXiv:2609.07128
代码 GitHub: SOTIF-AVLab/EEG2023
数据 DOI:10.21227/jw72-m261
规模 31页,8图13表

核心创新

论文提出首个将乘客EEG认知信号用于自动驾驶危险感知的完整框架,包含三个创新组件:

  1. 乘客认知模型(PCM):建模乘客对危险的神经响应
  2. 风险感知序列标注(RSL):解决EEG标注稀疏问题
  3. 乘客EEG解码策略(PEDS):集成3D-CRNN联合解码

关键突破: Balanced Accuracy 达 95.3%±2.7%(风险预测),跨被试 64.9%±8.5%(泛化性验证)

方法详解

1. 问题定义

1
2
3
4
5
6
任务定义:
├── 风险预测(RP):乘客是否感知到危险?→ 二分类
└── 危险识别(DI):哪个事件是危险的?→ 序列标注

输入:多通道EEG信号(64通道 NeuroScan Quik-Cap 采集、1000Hz 记录;预处理后模型输入为 54 通道、250Hz)
输出:风险概率 + 事件级危险标签

2. 乘客认知模型(PCM)

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
# 示意代码,不可直接运行:以下为按论文思路的示意性重构,并非论文官方实现
# (论文实际采用 GRU 循环结构且无通道注意力机制;官方代码见上文 GitHub 链接 SOTIF-AVLab/EEG2023)
import torch
import torch.nn as nn
import numpy as np
from typing import Tuple

class PassengerCognitiveModel(nn.Module):
"""
乘客认知模型(PCM)

论文 Section 3.1: 将乘客视为自动驾驶系统的辅助监督源
建模乘客对道路事件的神经认知响应

核心假设:乘客的EEG信号包含对道路危险的预感知
可作为AV决策的辅助监督信号
"""

def __init__(
self,
num_channels: int = 64, # EEG通道数
sampling_rate: int = 250, # 采样率 Hz
num_classes: int = 2 # 风险/安全
):
super().__init__()
self.num_channels = num_channels
self.sampling_rate = sampling_rate

# 空间-时间特征提取
self.spatial_filter = nn.Conv2d(1, num_channels, (num_channels, 1))
self.temporal_filter = nn.Conv2d(1, 32, (1, 25))

# 认知状态映射
self.cognitive_map = nn.Sequential(
nn.Linear(32 * (sampling_rate // 4), 256),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(256, 128),
nn.ReLU(),
nn.Linear(128, num_classes)
)

def forward(self, eeg: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
"""
Args:
eeg: EEG信号 (B, C, T)
B=batch, C=通道数, T=时间点
Returns:
risk_logits: 风险分类logits (B, num_classes)
cognitive_state: 认知状态特征 (B, 128)
"""
B, C, T = eeg.shape

# 空间滤波
x = eeg.unsqueeze(1) # (B, 1, C, T)
spatial = self.spatial_filter(x) # (B, C, 1, T)
spatial = spatial.squeeze(2) # (B, C, T)

# 时间滤波
x = spatial.unsqueeze(1) # (B, 1, C, T)
temporal = self.temporal_filter(x) # (B, 32, C, T-24)

# 展平
flat = temporal.reshape(B, -1)

# 认知状态
cognitive_state = self.cognitive_map[:-1](flat) # (B, 128)
risk_logits = self.cognitive_map[-1](cognitive_state) # (B, num_classes)

return risk_logits, cognitive_state


class CRNN3D(nn.Module):
"""
3D-CRNN: 论文核心模型

3D卷积提取时空频特征 + CRNN时序建模

架构:
1. 3D卷积层:提取EEG的空间-时间-频率联合特征
2. 通道注意力:自适应选择重要EEG通道
3. 双向LSTM:建模时序依赖
4. 分类头:风险预测 + 危险识别
"""

def __init__(
self,
num_channels: int = 64,
sampling_rate: int = 250,
window_sec: float = 2.0,
num_freq_bands: int = 5, # delta, theta, alpha, beta, gamma
hidden_dim: int = 256,
num_lstm_layers: int = 2,
num_classes: int = 2
):
super().__init__()
self.num_channels = num_channels
self.sampling_rate = sampling_rate
self.window_sec = window_sec
self.num_freq_bands = num_freq_bands

window_samples = int(sampling_rate * window_sec)

# Stage 1: 3D卷积提取时空特征
# 输入: (B, 1, F, C, T) - F=频带数, C=通道数, T=时间
self.conv3d_1 = nn.Conv3d(1, 16, kernel_size=(3, 3, 5), padding=(1, 1, 2))
self.bn1 = nn.BatchNorm3d(16)
self.conv3d_2 = nn.Conv3d(16, 32, kernel_size=(3, 3, 5), padding=(1, 1, 2))
self.bn2 = nn.BatchNorm3d(32)
self.conv3d_3 = nn.Conv3d(32, 64, kernel_size=(3, 3, 3), padding=(1, 1, 1))
self.bn3 = nn.BatchNorm3d(64)

self.pool = nn.MaxPool3d(kernel_size=(1, 2, 2))
self.relu = nn.ReLU()
self.dropout = nn.Dropout(0.3)

# Stage 2: 通道注意力
self.channel_attn = nn.Sequential(
nn.AdaptiveAvgPool3d(1),
nn.Flatten(1),
nn.Linear(64, 16),
nn.ReLU(),
nn.Linear(16, 64),
nn.Sigmoid()
)

# Stage 3: 计算展平后维度
# 经过3次pool后: T -> T//4, C -> C//4 (近似)
reduced_t = max(1, window_samples // 4)
reduced_c = max(1, num_channels // 8)
flat_dim = 64 * num_freq_bands * reduced_c * reduced_t

# 投影到LSTM维度
self.proj = nn.Linear(flat_dim // (num_freq_bands * reduced_c), hidden_dim)

# Stage 4: 双向LSTM
self.bilstm = nn.LSTM(
input_size=hidden_dim,
hidden_size=hidden_dim,
num_layers=num_lstm_layers,
batch_first=True,
bidirectional=True,
dropout=0.3 if num_lstm_layers > 1 else 0
)

# Stage 5: 多任务输出头
# 风险预测头
self.rp_head = nn.Sequential(
nn.Linear(hidden_dim * 2, hidden_dim),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(hidden_dim, num_classes)
)

# 危险识别头(序列标注)
self.di_head = nn.Sequential(
nn.Linear(hidden_dim * 2, hidden_dim),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(hidden_dim, num_classes)
)

def forward(
self,
eeg_stft: torch.Tensor
) -> Tuple[torch.Tensor, torch.Tensor]:
"""
Args:
eeg_stft: EEG短时傅里叶变换 (B, 1, F, C, T)
F=频带数, C=通道数, T=时间步
Returns:
rp_logits: 风险预测 (B, T_out, 2)
di_logits: 危险识别 (B, T_out, 2)
"""
B = eeg_stft.shape[0]

# 3D卷积
x = self.relu(self.bn1(self.conv3d_1(eeg_stft)))
x = self.pool(x)
x = self.dropout(x)

x = self.relu(self.bn2(self.conv3d_2(x)))
x = self.pool(x)
x = self.dropout(x)

x = self.relu(self.bn3(self.conv3d_3(x)))
x = self.pool(x)

# 通道注意力
attn = self.channel_attn(x)
x = x * attn.unsqueeze(-1).unsqueeze(-1).unsqueeze(-1)

# 展平空间维度,保留时间维度
B, C_out, F_out, H_out, T_out = x.shape
x = x.permute(0, 4, 1, 2, 3).contiguous() # (B, T, C, F, H)
x = x.reshape(B, T_out, -1)

# 投影
x = self.proj(x)

# 双向LSTM
lstm_out, _ = self.bilstm(x) # (B, T, 2*hidden)

# 多任务预测
rp_logits = self.rp_head(lstm_out) # (B, T, 2)
di_logits = self.di_head(lstm_out) # (B, T, 2)

return rp_logits, di_logits


# 测试代码
if __name__ == "__main__":
# 模拟EEG数据
batch_size = 8
num_channels = 64
sampling_rate = 250
window_sec = 2.0
num_freq_bands = 5

window_samples = int(sampling_rate * window_sec)

# 生成模拟EEG STFT输入 (B, 1, F, C, T)
eeg_stft = torch.randn(batch_size, 1, num_freq_bands,
num_channels, window_samples)

# 初始化模型
model = CRNN3D(
num_channels=num_channels,
sampling_rate=sampling_rate,
window_sec=window_sec,
num_freq_bands=num_freq_bands,
hidden_dim=256
)

# 前向传播
rp, di = model(eeg_stft)

print(f"输入: {eeg_stft.shape}")
print(f"风险预测输出: {rp.shape}")
print(f"危险识别输出: {di.shape}")

# 验证
assert rp.shape[0] == batch_size
assert rp.shape[-1] == 2

print("\n✅ 3D-CRNN 模型测试通过")

# 参数量统计
total_params = sum(p.numel() for p in model.parameters())
print(f"模型参数量: {total_params:,} ({total_params/1e6:.2f}M)")

3. 风险感知序列标注(RSL)

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
# 示意代码,不可直接运行:RSL 逻辑为示意重构;前/后窗口参数(5/10 个窗口)为示意假设,
# 论文未给出该具体数值(官方代码见上文 GitHub 链接)
class RiskAwareSequentialLabeling:
"""
风险感知序列标注(RSL)

论文 Section 3.3: 解决EEG标注稀疏问题

传统方法:每个时间窗口独立标注
RSL方法:考虑风险事件的时间延续性,
将危险事件的标签传播到前后窗口
"""

def __init__(
self,
pre_window: int = 5, # 危险事件前5个窗口标为"风险升高"
post_window: int = 10, # 危险事件后10个窗口标为"风险残留"
neutral_threshold: float = 0.5
):
self.pre_window = pre_window
self.post_window = post_window
self.neutral_threshold = neutral_threshold

def label_sequence(
self,
event_timestamps: list,
total_windows: int,
window_duration: float = 2.0
) -> torch.Tensor:
"""
生成RSL标签序列

Args:
event_timestamps: 危险事件时间戳列表 [秒]
total_windows: 总窗口数
window_duration: 每个窗口时长(秒)
Returns:
labels: (total_windows,) 0=安全, 1=风险升高, 2=危险
"""
labels = torch.zeros(total_windows, dtype=torch.long)

for ts in event_timestamps:
event_window = int(ts / window_duration)

# 前置:风险升高
start = max(0, event_window - self.pre_window)
labels[start:event_window] = torch.maximum(
labels[start:event_window],
torch.full_like(labels[start:event_window], 1)
)

# 事件点:危险
end = min(total_windows, event_window + 1)
labels[event_window:end] = 2

# 后置:风险残留
residual_end = min(total_windows, event_window + self.post_window)
labels[end:residual_end] = torch.maximum(
labels[end:residual_end],
torch.full_like(labels[end:residual_end], 1)
)

return labels


# 测试RSL
if __name__ == "__main__":
rsl = RiskAwareSequentialLabeling(pre_window=5, post_window=10)

# 模拟:在60秒视频中,第15秒和第35秒有危险事件
labels = rsl.label_sequence(
event_timestamps=[15.0, 35.0],
total_windows=30, # 60秒 / 2秒/窗口
window_duration=2.0
)

print("RSL标签序列:")
for i, label in enumerate(labels):
t = i * 2.0
name = ["安全", "风险升高", "危险"][label]
print(f" [{t:5.1f}s] 窗口{i:2d}: {name}")

print(f"\n✅ RSL测试通过")

实验结果

1. 风险预测(RP)性能

注:本表依据论文原文 Table 2 核对修正(此前版本的 SVM/CNN-1D/CRNN 基线数据有误,已删除)。

模型 Balanced Accuracy F1 说明
XGB-DIM 55.3%±5.3% 0.552±0.054 传统机器学习基线
DeepConvNet 64.6%±14.2% 0.602±0.187 深度学习基线
DSC-ConvLSTM 71.0%±12.9% 0.697±0.154 +时序建模
CTNet 71.9%±13.0% 0.719±0.130 Transformer 类基线
EEGNet 86.0%±12.9% 0.863±0.130 轻量 EEG 网络
ShallowConvNet 94.7%±3.2% 0.949±0.031 最强对比基线
3D-CRNN 95.3%±2.7% 0.955±0.027 论文方法(3D时空特征)

2. 危险识别(DI)性能

注:论文仅明确给出单被试条件下的无 RSL 对照(80.9%±3.9%);其余条件的无 RSL 数值在可核对文本中未提供,故不再列出。

方法 单被试 BA 跨会话 BA 跨被试(已见) BA 跨被试(未见) BA
独立标注 80.9%±3.9% 原文未提供 原文未提供 原文未提供
+RSL 85.0%±3.2% 77.0%±5.3% 77.4%±1.1% 64.9%±8.5%
提升 +4.1%(论文原文称 0.041 绝对提升) — — —

3. 事件类型分析

注:本表依据论文原文核对修正(此前版本的数值有误,且论文中不存在”红灯违规”场景,已删除)。论文共分析三种事件类型。

事件类型 RP BA(3D-CRNN) DI BA(+RSL) 说明
紧急制动(AEB) 88.0%±12.7% 77.8%±12.9% 明显EEG响应
急速变道(cut-in) 94.6%±3.2% 88.0%±2.6% 响应最强
行人穿越 88.9%±9.2% 79.9%±7.4% 预测性响应

IMS 开发启示

1. SOTIF(预期功能安全)支持

关键启示: 乘客认知信号可作为AV系统SOTIF分析的辅助验证源。当AV做出决策时,如果乘客的EEG显示”危险”响应,说明该决策可能存在问题。

2. 从乘客到驾驶员的迁移

维度 论文(乘客) IMS可迁移(驾驶员)
EEG采集 64通道实验室级 干电极少量通道(如Fp1/Fp2)
任务 被动危险感知 主动驾驶+危险预测
实时性 离线分析 在线<2s延迟
部署 实验室 车载边缘设备

3. 非EEG替代方案

论文证明EEG有效,但车载部署困难。IMS可考虑的替代认知信号:

认知信号 可获得性 延迟 相关EEG频带
瞳孔直径 高(红外摄像头) ~100ms 与alpha频带相关
心率变异 中(方向盘传感器) ~500ms 与theta频带相关
皮肤电导 中(方向盘传感器) ~1s 与beta频带相关
面部微表情 高(DMS摄像头) ~200ms 多频带综合

4. 落地建议

优先级 建议 理由
🔴高 跟踪EEG-BCI小型化进展 干电极+少量通道可量产
🔴高 用瞳孔直径替代EEG认知信号 已有DMS红外摄像头
🟡中 建立乘客感知数据集 对标自动出租车内监控
🟡中 研究”认知过载”检测 EEG在分心/疲劳中的应用
🟢低 探索方向盘心率传感器 已有硬件基础

总结

这篇论文是首个将EEG认知信号引入自动驾驶安全闭环的完整框架:

  1. 3D-CRNN 模型在风险预测上达 95.3% BA,优于论文对比的全部基线(次优 ShallowConvNet 94.7%)
  2. RSL 序列标注策略有效解决EEG标注稀疏问题
  3. 跨被试泛化性 64.9%,仍有提升空间但证明可行性
  4. 代码和数据开源,可直接复现

对 IMS 的核心启示:乘客/驾驶员的认知信号是AV安全闭环中被忽视的监督源。虽然EEG直接上车困难,但论文验证了认知信号的价值,可用瞳孔直径、微表情等非接触信号替代。这为 IMS 的认知分心检测开辟了新的技术路线。