MVMD-FCASNN:脑启发 AI 在强噪声下的疲劳检测突破

98.8% 精度 EEG 疲劳检测论文深度解读与代码复现

论文信息

核心突破

关键指标

指标 结果 对比
分类精度 98.81% 实验室级 EEG 方法通常 85-92%
强噪声鲁棒性 SNR=-6dB 仍有效 多数方法在 SNR<0dB 时崩溃
方法 MVMD-FCASNN 脑启发 SNN + 多变量分解
应用场景 塔式起重机操作员 工业强噪声环境

三大技术创新

技术 全称 作用
MVMD Multivariate Variational Mode Decomposition 多通道联合分解,抗噪声
FCASNN Frequency-Channel Attention Spiking Neural Network 脑启发脉冲神经网络
IMF Attention Intrinsic Mode Function Attention 自适应频率权重

方法详解

1. MVMD(多变量变分模态分解)

传统 EMD(经验模态分解)对噪声敏感。MVMD 同时分解所有 EEG 通道:

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
"""
MVMD (Multivariate Variational Mode Decomposition) 实现

核心思想:
1. 不逐通道独立分解,而是联合分解所有通道
2. 搜索跨通道频率对齐的固有模态函数(IMF)
3. 带宽约束优化 → 抗噪声

对比 EMD:
- EMD: 每通道独立 → 噪声通道污染其他通道
- MVMD: 联合约束 → 频率一致性保证
"""

import numpy as np
from scipy.signal import hilbert


class MVMD:
"""
多变量变分模态分解

将多通道 EEG 信号分解为多个固有模态函数(IMF)

输入: multichannel_signal, shape=(channels, time)
输出: imfs, shape=(num_imfs, channels, time)
"""

def __init__(self, num_imfs=4, max_iter=300,
tol=1e-7, alpha=2000, tau=0.0):
self.K = num_imfs # IMF 数量
self.max_iter = max_iter
self.tol = tol
self.alpha = alpha # 带宽约束
self.tau = tau # 噪声松弛参数

def decompose(self, signal: np.ndarray) -> np.ndarray:
"""
分解多通道信号

Args:
signal: shape=(channels, num_samples)

Returns:
imfs: shape=(K, channels, num_samples)
"""
C, T = signal.shape
# 初始化 IMF
imfs = np.zeros((self.K, C, T))

# 残差
residual = signal.copy()

for k in range(self.K):
# 提取第 k 个 IMF
imf_k = self._extract_imf(residual, k)
imfs[k] = imf_k
residual -= imf_k

return imfs

def _extract_imf(self, signal, imf_idx):
"""
提取单个 IMF(简化实现)

使用变分优化:
min sum ||u_k - f||^2 + alpha * ||D(u_k)||^2
"""
C, T = signal.shape

# 初始化为中心频率的带通滤波
# 不同 IMF 对应不同频段
freq_center = 0.5 - imf_idx * 0.1 # 简化的中心频率

# FFT 域带通滤波
fft_signal = np.fft.fft(signal, axis=1)
freqs = np.fft.fftfreq(T, d=1/250) # 假设 250Hz 采样

# 高斯带通
bandwidth = 0.15
bandpass = np.exp(
-((np.abs(freqs) - freq_center) / bandwidth)**2
)

imf = np.real(
np.fft.ifft(fft_signal * bandpass[np.newaxis, :],
axis=1)
)

return imf

def compute_imf_features(self, imfs: np.ndarray) -> dict:
"""
从 IMF 提取特征

关键特征:
1. 各频段能量分布
2. 频谱熵
3. 跨通道一致性
"""
K, C, T = imfs.shape
features = {}

for k in range(K):
# Hilbert 变换获取瞬时频率和幅度
analytic = hilbert(imfs[k], axis=1)
inst_phase = np.unwrap(np.angle(analytic), axis=1)
inst_freq = np.diff(inst_phase, axis=1) / (2*np.pi) * 250

# 能量
energy = np.sum(imfs[k]**2, axis=1)

# 频谱熵
psd = np.abs(np.fft.fft(imfs[k], axis=1))**2
psd_norm = psd / (psd.sum(axis=1, keepdims=True) + 1e-10)
entropy = -np.sum(
psd_norm * np.log(psd_norm + 1e-10), axis=1
)

features[f'imf_{k}'] = {
'energy': energy.tolist(),
'mean_freq': np.mean(inst_freq, axis=1).tolist(),
'spectral_entropy': entropy.tolist()
}

return features


# 测试
if __name__ == "__main__":
np.random.seed(42)

# 模拟 32 通道 EEG,10秒,250Hz
num_channels = 32
num_samples = 2500
fs = 250

# 生成模拟信号(alpha + beta + theta + 噪声)
t = np.arange(num_samples) / fs

# 清晰信号
alpha = 50 * np.sin(2*np.pi*10*t) # alpha 10Hz
beta = 30 * np.sin(2*np.pi*20*t) # beta 20Hz
theta = 40 * np.sin(2*np.pi*5*t) # theta 5Hz

# 多通道(每个通道略有不同的幅度和相位)
clean_signal = np.zeros((num_channels, num_samples))
for ch in range(num_channels):
clean_signal[ch] = (
alpha * (0.8 + 0.2*np.random.rand()) +
beta * (0.6 + 0.3*np.random.rand()) +
theta * (0.7 + 0.2*np.random.rand())
)

# 添加强噪声(SNR = -6dB)
noise_power = np.var(clean_signal) * 10**(6/10)
noise = np.sqrt(noise_power) * np.random.randn(
num_channels, num_samples
)
noisy_signal = clean_signal + noise

# MVMD 分解
mvmd = MVMD(num_imfs=4)
imfs = mvmd.decompose(noisy_signal)

# 特征提取
features = mvmd.compute_imf_features(imfs)

print(f"=== MVMD 分解结果 ===")
print(f" 输入: {num_channels}ch × {num_samples}samples")
print(f" SNR: -6dB")
print(f" IMF 数: {mvmd.K}")
print(f" IMF shape: {imfs.shape}")
print()

for k in range(min(3, mvmd.K)):
f = features[f'imf_{k}']
print(f" IMF {k}:")
print(f" 平均能量: {np.mean(f['energy']):.2f}")
print(f" 平均频率: {np.mean(f['mean_freq']):.1f} Hz")
print(f" 频谱熵: {np.mean(f['spectral_entropy']):.2f}")

2. FCASNN(频率-通道注意力脉冲神经网络)

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
"""
FCASNN (Frequency-Channel Attention Spiking Neural Network)

脑启发架构:
1. SNN 模拟生物神经元脉冲发射
2. 频率注意力 → 自适应选择重要频段
3. 通道注意力 → 自适应选择重要脑区

对比传统 CNN/RNN:
- SNN: 事件驱动,低功耗
- 注意力: 自适应特征选择
- 脑启发: 更好的生物可解释性
"""

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


class SpikingNeuron(nn.Module):
"""
LIF (Leaky Integrate-and-Fire) 脉冲神经元

模拟生物神经元:
1. 积分输入
2. 达到阈值时发射脉冲
3. 重置膜电位
"""

def __init__(self, threshold=1.0, decay=0.95):
super().__init__()
self.threshold = threshold
self.decay = decay # 膜电位衰减

def forward(self, x):
"""
x: 输入电流, shape=(batch, ...)
返回: 脉冲序列, shape=(batch, ...)
"""
# 初始化膜电位
v = torch.zeros_like(x)
spikes = torch.zeros_like(x)

# 逐时间步模拟
for t in range(x.shape[-1]):
# 积分
v = self.decay * v + x[..., t]
# 发射
spikes[..., t] = (v >= self.threshold).float()
# 重置
v = v * (1 - spikes[..., t])

return spikes


class FrequencyAttention(nn.Module):
"""
频率注意力模块

自适应评估每个 IMF(频率分量)的贡献
自动加权重要的频段(如疲劳相关的 theta/alpha)
"""

def __init__(self, num_imfs, hidden_dim=64):
super().__init__()
self.attention = nn.Sequential(
nn.Linear(num_imfs, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, num_imfs),
nn.Sigmoid()
)

def forward(self, x):
"""
x: shape=(batch, num_imfs, ...)
返回: 加权后的特征
"""
# 全局平均池化
pooled = x.mean(dim=-1) # (batch, num_imfs)

# 注意力权重
weights = self.attention(pooled) # (batch, num_imfs)

# 加权
return x * weights.unsqueeze(-1)


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

自适应评估每个 EEG 通道(脑区)的贡献
强调前额叶和中央区(疲劳相关区域)

灵感来源:Squeeze-and-Excitation Networks
"""

def __init__(self, num_channels, reduction=4):
super().__init__()
self.squeeze = nn.AdaptiveAvgPool1d(1)
self.excitation = nn.Sequential(
nn.Linear(num_channels, num_channels // reduction),
nn.ReLU(),
nn.Linear(num_channels // reduction, num_channels),
nn.Sigmoid()
)

def forward(self, x):
"""
x: shape=(batch, num_channels, time)
返回: 加权后的特征
"""
b, c, t = x.shape
# Squeeze
s = self.squeeze(x).squeeze(-1) # (batch, channels)
# Excitation
w = self.excitation(s) # (batch, channels)
# Reweight
return x * w.unsqueeze(-1)


class FCASNNModel(nn.Module):
"""
完整的 MVMD-FCASNN 模型

架构:
1. MVMD 分解后的 IMF → 频率注意力
2. 加权 IMF 特征 → 通道注意力
3. SNN 脉冲编码 → 分类
"""

def __init__(self, num_channels=32, num_imfs=4,
num_classes=2, hidden=128):
super().__init__()

# 频率注意力
self.freq_attn = FrequencyAttention(num_imfs)

# 通道注意力
self.channel_attn = ChannelAttention(num_channels)

# SNN 脉冲神经元
self.spiking = SpikingNeuron(threshold=0.5, decay=0.9)

# 分类器
self.classifier = nn.Sequential(
nn.Linear(num_channels * num_imfs, hidden),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(hidden, num_classes)
)

def forward(self, x):
"""
x: shape=(batch, num_imfs, num_channels, time)
返回: logits, shape=(batch, num_classes)
"""
# 频率注意力 (batch, num_imfs, channels, time)
x = self.freq_attn(x)

# 合并 IMF 维和 channel 维
b, k, c, t = x.shape
x = x.view(b * k, c, t)

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

# SNN 脉冲编码
spikes = self.spiking(x)

# 发射率编码
rates = spikes.mean(dim=-1) # (b*k, c)
rates = rates.view(b, k * c)

# 分类
logits = self.classifier(rates)
return logits


# 测试
if __name__ == "__main__":
model = FCASNNModel(
num_channels=32, num_imfs=4,
num_classes=2, hidden=128
)

# 模拟输入:4 IMFs × 32 channels × 250 time steps
x = torch.randn(8, 4, 32, 250)

logits = model(x)

print(f"=== FCASNN 模型 ===")
print(f" 输入: {x.shape}")
print(f" 输出: {logits.shape}")
print(f" 参数量: {sum(p.numel() for p in model.parameters()):,}")

# 预测
pred = F.softmax(logits, dim=-1)
print(f" 预测: {torch.argmax(pred, dim=-1).tolist()}")

3. 强噪声鲁棒性

论文的关键贡献是在 SNR=-6dB(噪声比信号强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
"""
噪声鲁棒性测试框架

对比不同方法在噪声环境下的性能退化
"""

import numpy as np


def add_noise(signal, target_snr_db):
"""添加高斯白噪声到指定 SNR"""
signal_power = np.var(signal)
noise_power = signal_power * 10**(-target_snr_db / 10)
noise = np.sqrt(noise_power) * np.random.randn(*signal.shape)
return signal + noise


def simulate_noise_robustness():
"""
模拟不同 SNR 下的精度退化

参考论文数据:
- MVMD-FCASNN: 98.81% (clean), ~92% (-6dB)
- 传统 EMD-CNN: 92% (clean), ~65% (-6dB)
- 基线 CNN: 90% (clean), ~50% (-6dB)
"""
snr_levels = [20, 10, 0, -3, -6]

# 论文报告的性能(近似)
methods = {
'MVMD-FCASNN (本文)': [98.8, 97.5, 95.0, 93.5, 92.0],
'EMD-CNN (传统)': [92.0, 88.5, 78.0, 70.0, 65.0],
'基线 CNN': [90.0, 82.0, 65.0, 55.0, 50.0],
}

print("=== 噪声鲁棒性对比 ===")
print(f"{'SNR (dB)':>10}", end="")
for snr in snr_levels:
print(f" {snr:>6}dB", end="")
print()

for method, accs in methods.items():
print(f"{method:>25}", end="")
for acc in accs:
print(f" {acc:>5.1f}%", end="")
print()

print(f"\n{'关键发现':>25}")
print(f" MVMD-FCASNN 在 -6dB 噪声下精度损失仅 ~7%")
print(f" 传统方法在 -6dB 噪声下精度损失 25-40%")


simulate_noise_robustness()

对 IMS 开发的启示

1. 强噪声环境 = 汽车座舱

起重机操作员环境与汽车座舱的噪声特征相似:

噪声源 起重机 汽车座舱
电气干扰 强 中(车载电子)
振动 强 中(发动机/路面)
肌电干扰 中 中(驾驶操作)
眨眼伪迹 中 中

MVMD 的抗噪声方法可以直接迁移到汽车 EEG/rPPG 信号处理。

2. SNN 的低功耗优势

脉冲神经网络(SNN)相比传统 CNN/RNN 的优势:

指标 CNN/RNN SNN
功耗 高 低 10-100x
事件驱动 否 是
生物可解释性 低 高
硬件部署 成熟 新兴

对汽车 IMS 的意义:SNN 可能是边缘部署 EEG/rPPG 处理的未来方案。

3. 跨域疲劳检测迁移路线

4. 近期可落地技术

技术 可行性 时间线 IMS 应用
MVMD 信号去噪 ✅ 高 0-6月 rPPG 呼吸/心跳提取
频率注意力 ✅ 高 0-6月 PERCLOS 频段选择
通道注意力 ✅ 高 0-6月 多传感器融合
SNN 部署 ⚠️ 中 6-12月 边缘 AI 低功耗
EEG 车载 ❌ 低 24月+ 需要干电极突破

结论

MVMD-FCASNN 证明了脑启发 AI 在强噪声工业环境下的疲劳检测能力。其核心技术(MVMD 多通道分解、频率-通道注意力)可以迁移到汽车座舱的 rPPG 和多传感器融合场景。SNN 的低功耗特性使其成为边缘部署的候选方案。


参考链接: