EEGDM: 潜在扩散模型学习EEG表征,自监督新范式驱动座舱认知监测

论文信息

  • 标题: EEGDM: Learning EEG Representation with Latent Diffusion Model
  • 作者: Tong Liu 等
  • arXiv: 2508.20705 (v4: 2026年8月30日)
  • 领域: cs.LG, cs.AI
  • 关键词: EEG, 自监督学习, 潜在扩散模型, 表征学习

核心创新

EEGDM首次将**潜在扩散模型(Latent Diffusion Model)**应用于EEG信号的自监督表征学习。与传统掩码重建不同,扩散生成迫使模型捕获EEG信号的全局时序模式和跨通道关系。

方法对比

方法 训练目标 优势 劣势
掩码重建 (Masked Reconstruction) 恢复随机遮挡的信号段 局部依赖建模强 不捕获全局生成约束
EEGDM (本文) 从噪声生成EEG信号 全局时序+跨通道关系 训练成本较高

方法详解

整体架构

1
2
3
4
5
6
7
原始EEG信号 ──→ EEG Encoder ──→ 紧凑潜在表征 z
│
│ (条件信息)
▼
噪声 z_T ~ N(0,I) ──→ 扩散去噪过程 ──→ 重建EEG信号
↑
z 作为条件引导

核心设计

  1. EEG Encoder: 将原始信号和通道增强蒸馏为紧凑表征
  2. 扩散去噪: 以encoder输出为条件,从高斯噪声逐步去噪生成EEG
  3. 联合优化: encoder和扩散模型通过生成目标联合训练
  4. 下游迁移: 紧凑潜在空间可直接用于分类、检测等下游任务

模型实现

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
264
265
266
267
268
"""
论文:EEGDM: Learning EEG Representation with Latent Diffusion Model
arXiv: 2508.20705

核心方法:基于潜在扩散模型的自监督EEG表征学习
"""

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

class EEGEncoder(nn.Module):
"""
EEG编码器: 将原始EEG信号蒸馏为紧凑潜在表征

输入: (B, C, T) - C通道, T时间步
输出: (B, D) - D维潜在表征
"""

def __init__(self,
num_channels: int = 32,
time_steps: int = 1000,
latent_dim: int = 256,
hidden_dim: int = 128):
super().__init__()

# 1D时序卷积提取特征
self.conv1d_1 = nn.Conv1d(num_channels, hidden_dim, kernel_size=7, padding=3)
self.conv1d_2 = nn.Conv1d(hidden_dim, hidden_dim*2, kernel_size=5, padding=2)
self.conv1d_3 = nn.Conv1d(hidden_dim*2, hidden_dim*4, kernel_size=3, padding=1)

self.bn1 = nn.BatchNorm1d(hidden_dim)
self.bn2 = nn.BatchNorm1d(hidden_dim*2)
self.bn3 = nn.BatchNorm1d(hidden_dim*4)

# 通道注意力
self.channel_attention = ChannelAttention(hidden_dim*4, num_channels)

# 全局池化 + 投影
self.global_pool = nn.AdaptiveAvgPool1d(1)
self.projector = nn.Sequential(
nn.Linear(hidden_dim*4, latent_dim*2),
nn.ReLU(),
nn.Linear(latent_dim*2, latent_dim)
)

def forward(self, x):
"""
Args:
x: (B, C, T) EEG信号

Returns:
z: (B, D) 紧凑潜在表征
"""
# 时序卷积
x = F.relu(self.bn1(self.conv1d_1(x)))
x = F.relu(self.bn2(self.conv1d_2(x)))
x = F.relu(self.bn3(self.conv1d_3(x)))

# 通道注意力
x = self.channel_attention(x)

# 全局池化
x = self.global_pool(x).squeeze(-1) # (B, hidden_dim*4)

# 投影到潜在空间
z = self.projector(x) # (B, latent_dim)

return z


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

def __init__(self, embed_dim, num_channels):
super().__init__()
self.attn = nn.MultiheadAttention(embed_dim, num_heads=4, batch_first=True)
self.norm = nn.LayerNorm(embed_dim)

def forward(self, x):
# x: (B, C', T) → 转置为 (B, T, C')
x_t = x.transpose(1, 2)
attn_out, _ = self.attn(x_t, x_t, x_t)
x_t = self.norm(x_t + attn_out)
return x_t.transpose(1, 2) # 回到 (B, C', T)


class LatentDiffusion(nn.Module):
"""
潜在扩散模型

从高斯噪声逐步去噪,以EEG encoder的潜在表征为条件
"""

def __init__(self,
latent_dim: int = 256,
signal_channels: int = 32,
signal_length: int = 1000,
num_timesteps: int = 1000):
super().__init__()

self.num_timesteps = num_timesteps

# 噪声调度
betas = torch.linspace(1e-4, 0.02, num_timesteps)
alphas = 1.0 - betas
alphas_cumprod = torch.cumprod(alphas, dim=0)

self.register_buffer('betas', betas)
self.register_buffer('alphas', alphas)
self.register_buffer('alphas_cumprod', alphas_cumprod)
self.register_buffer('sqrt_alphas_cumprod', torch.sqrt(alphas_cumprod))
self.register_buffer('sqrt_one_minus_alphas_cumprod',
torch.sqrt(1.0 - alphas_cumprod))

# UNet去噪网络 (简化版)
self.denoise_net = UNet1D(
in_channels=signal_channels,
out_channels=signal_channels,
cond_dim=latent_dim,
hidden_dim=128
)

def forward_diffusion(self, x0, t):
"""前向扩散: 加噪"""
noise = torch.randn_like(x0)
sqrt_alpha = self.sqrt_alphas_cumprod[t].view(-1, 1, 1)
sqrt_one_minus = self.sqrt_one_minus_alphas_cumprod[t].view(-1, 1, 1)
return sqrt_alpha * x0 + sqrt_one_minus * noise, noise

def reverse_diffusion(self, x_t, t, cond):
"""反向去噪: 预测噪声"""
return self.denoise_net(x_t, t, cond)

def loss(self, x0, cond):
"""训练损失"""
B = x0.shape[0]
t = torch.randint(0, self.num_timesteps, (B,), device=x0.device)
x_t, noise = self.forward_diffusion(x0, t)
noise_pred = self.reverse_diffusion(x_t, t, cond)
return F.mse_loss(noise_pred, noise)


class UNet1D(nn.Module):
"""简化版1D UNet用于EEG去噪"""

def __init__(self, in_channels, out_channels, cond_dim, hidden_dim=128):
super().__init__()

# 时间嵌入
self.time_embed = nn.Sequential(
nn.Linear(1, hidden_dim),
nn.SiLU(),
nn.Linear(hidden_dim, hidden_dim)
)

# 条件嵌入
self.cond_embed = nn.Linear(cond_dim, hidden_dim)

# 编码器
self.enc1 = self._block(in_channels, hidden_dim)
self.enc2 = self._block(hidden_dim, hidden_dim*2)
self.enc3 = self._block(hidden_dim*2, hidden_dim*4)

# 瓶颈
self.bottleneck = self._block(hidden_dim*4, hidden_dim*4)

# 解码器 (带skip connection)
self.dec3 = self._block(hidden_dim*4 + hidden_dim*4, hidden_dim*2)
self.dec2 = self._block(hidden_dim*2 + hidden_dim*2, hidden_dim)
self.dec1 = self._block(hidden_dim + hidden_dim, out_channels)

def _block(self, in_ch, out_ch):
return nn.Sequential(
nn.Conv1d(in_ch, out_ch, 3, padding=1),
nn.GroupNorm(8, out_ch),
nn.SiLU(),
nn.Conv1d(out_ch, out_ch, 3, padding=1),
nn.GroupNorm(8, out_ch),
nn.SiLU()
)

def forward(self, x, t, cond):
# 时间+条件嵌入
t_emb = self.time_embed(t.float().unsqueeze(-1)) # (B, hidden)
c_emb = self.cond_embed(cond) # (B, hidden)
emb = t_emb + c_emb # (B, hidden)

# 编码器
e1 = self.enc1(x)
e2 = self.enc2(F.avg_pool1d(e1, 2))
e3 = self.enc3(F.avg_pool1d(e2, 2))

# 瓶颈
b = self.bottleneck(F.avg_pool1d(e3, 2))

# 解码器 (上采样 + skip)
d3 = self.dec3(torch.cat([F.interpolate(b, scale_factor=2), e3], dim=1))
d2 = self.dec2(torch.cat([F.interpolate(d3, scale_factor=2), e2], dim=1))
d1 = self.dec1(torch.cat([F.interpolate(d2, scale_factor=2), e1], dim=1))

return d1


# 完整EEGDM训练流程
class EEGDMTrainer:
"""EEGDM自监督训练"""

def __init__(self, num_channels=32, signal_length=1000, latent_dim=256):
self.encoder = EEGEncoder(num_channels, signal_length, latent_dim)
self.diffusion = LatentDiffusion(latent_dim, num_channels, signal_length)

self.optimizer = torch.optim.AdamW(
list(self.encoder.parameters()) + list(self.diffusion.parameters()),
lr=1e-4, weight_decay=1e-5
)

def train_step(self, eeg_batch):
"""
单步训练

Args:
eeg_batch: (B, C, T) 原始EEG信号
"""
# 1. EEG编码
z = self.encoder(eeg_batch)

# 2. 扩散损失
loss = self.diffusion.loss(eeg_batch, z)

# 3. 反向传播
self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()

return {"loss": loss.item()}

def extract_features(self, eeg_batch):
"""提取EEG表征用于下游任务"""
with torch.no_grad():
z = self.encoder(eeg_batch)
return z


# 测试
if __name__ == "__main__":
# 模拟EEG数据
B, C, T = 8, 32, 1000
eeg_data = torch.randn(B, C, T) # 32通道, 1000时间步

# 初始化
trainer = EEGDMTrainer(num_channels=C, signal_length=T)

# 训练步骤
print("=== EEGDM 训练 ===")
for step in range(3):
result = trainer.train_step(eeg_data)
print(f"Step {step+1}: loss = {result['loss']:.4f}")

# 提取特征
features = trainer.extract_features(eeg_data)
print(f"\nEEG表征形状: {features.shape}")
print(f"表征维度: {features.shape[1]}")

# 下游任务示例: 疲劳分类
classifier = nn.Linear(256, 2) # 256 = latent_dim
logits = classifier(features)
print(f"分类logits形状: {logits.shape}")

实验结果

论文报告性能

下游任务 EEGDM 掩码重建基线 提升
EEG重建质量 ✅ 高质量 中等 显著提升
跨任务性能 ✅ 有竞争力 有竞争力 持平或提升
表征鲁棒性 ✅ 鲁棒 一般 增强
潜在空间可控性 ✅ 充分控制 有限 新能力

与传统方法对比

方法 训练目标 全局模式 跨通道关系 潜在空间 下游迁移
掩码重建 局部恢复 ⚠️ ⚠️ ❌ 无 中等
对比学习 区分正负 ✅ ⚠️ ⚠️ 良好
EEGDM 扩散生成 ✅ ✅ ✅ 紧凑可控 良好+

IMS开发启示

1. 座舱EEG自监督学习路线

1
2
3
4
5
6
7
8
9
原始EEG数据 (无需标注)
│
▼
EEGDM自监督预训练
│
├──→ 疲劳检测 (下游分类)
├──→ 分心检测 (下游分类)
├──→ 认知负荷评估 (下游回归)
└──→ 异常检测 (自监督)

2. 与EEG Hazard Perception论文的联动

将EEGDM与arXiv 2609.07128的3D-CRNN结合:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# EEGDM预训练 + 3D-CRNN微调
class EEGDM pretrained CRNN(nn.Module):
"""
用EEGDM预训练的encoder初始化3D-CRNN
实现迁移学习
"""
def __init__(self, eegdm_encoder, num_classes=2):
super().__init__()
# 冻结EEGDM encoder或微调
self.encoder = eegdm_encoder
self.classifier = nn.Linear(256, num_classes)

def forward(self, x):
z = self.encoder(x) # 自监督预训练特征
return self.classifier(z)

3. 座舱EEG未来展望

阶段 能力 时间表
当前 EEGDM自监督预训练 2026
下一步 EEGDM + 干电极头枕集成 2027-2028
中期 个性化EEG表征 (联邦学习) 2028-2030
远期 实时EEG认知监控 (无感化) 2030+

4. 实际落地挑战

挑战 EEGDM方案 解决方向
训练成本 扩散模型训练慢 潜在空间压缩+DDIM加速
信号质量 真实车内EEG噪声大 EEGDM生成增强数据增广
个体差异 跨被试泛化 EEGDM+个性化微调
实时推理 扩散采样慢 只用encoder,不需生成

参考


发布时间: 2026-09-24 04:00
分类: EEG | 自监督学习 | 扩散模型 | 认知监测 | 论文解读