第二讲:脑电信号基础回顾
各位同学好,我是你们的老朋友。今天咱们聊聊脑电信号的基础知识。说实话,很多做迁移学习的同学,一上来就急着调模型,结果数据质量不行,再好的算法也白搭。我当年刚入行时就吃过这个亏——花了两周跑出来的结果,最后发现是电极帽没戴好。
所以这一讲,咱们把地基打牢。我会结合自己踩过的坑,把EEG采集原理、10-20系统、常见伪迹和预处理流程讲透。
1. EEG采集原理:大脑的电信号从哪来?
说白了,EEG记录的是大脑皮层神经元的电活动。你想想看,我们大脑里有上千亿个神经元,它们通过电信号互相交流。当大量神经元同步放电时,就会在头皮表面产生微弱的电压变化——这就是EEG信号的来源。
具体来说,EEG采集依赖的是容积导体效应。大脑产生的电信号,会经过脑脊液、颅骨、头皮这些组织传导到头皮表面。嗯,这里要注意:信号经过颅骨时会衰减很多,所以头皮上测到的信号只有微伏级别(μV),比心电信号弱得多。
关键参数:
- 幅度范围:通常 1-100 μV
- 频率范围:0.5-100 Hz(主要分析 0.5-50 Hz)
- 采样率:临床常用 250-1000 Hz,研究常用 500-2000 Hz
我在项目中遇到过采样率设置不当的情况。有一次做运动想象分类,用了128 Hz的采样率,结果高频gamma波的信息全丢了。后来我建议至少用250 Hz,最好500 Hz以上。
2. 国际10-20系统:电极怎么放?
10-20系统是EEG电极放置的国际标准。为什么叫10-20?因为相邻电极之间的距离是颅骨前后或左右总长的10%或20%。
这个系统有几个关键点:
- 参考点:鼻根(Nasion)和枕骨隆突(Inion)
- 中线电极:Fz、Cz、Pz、Oz(z代表zero,即中线)
- 左右对称:奇数在左(F3、C3、P3),偶数在右(F4、C4、P4)
- 前缀含义:F=额叶,C=中央区,P=顶叶,O=枕叶,T=颞叶
我的小技巧:做跨被试迁移学习时,我习惯先检查所有被试的电极位置是否一致。有些公开数据集标注的是10-20系统,但实际放置有偏差。我曾经因为没检查这个,导致迁移效果差了10%。
现在很多研究用高密度EEG(64导、128导甚至256导),但10-20系统仍然是基础。你想想看,如果连标准位置都搞不清楚,怎么判断不同被试之间的信号差异是来自大脑还是来自电极偏移?
3. 常见伪迹:信号里的"噪音"从哪来?
EEG信号很微弱,所以特别容易受干扰。我把常见的伪迹分成三类:
| 伪迹类型 | 来源 | 特征 | 我的处理建议 |
|---|---|---|---|
| 眼动伪迹 | 眨眼、眼球转动 | 额叶区域大幅波动(>100 μV) | ICA去除或回归法 |
| 肌电伪迹 | 咬牙、皱眉、颈部紧张 | 高频成分(>30 Hz),幅度不规则 | 低通滤波 + 手动剔除 |
| 工频干扰 | 50/60 Hz电源 | 固定频率的正弦波 | 陷波滤波器(注意带宽别太大) |
嗯,这里要特别说一下眼电伪迹。我做迁移学习时发现,不同被试的眨眼模式差异很大。有的人眨得快(0.2秒),有的人眨得慢(0.5秒)。如果用统一的阈值去检测,很容易漏掉或误判。
避坑指南:我曾经用50 Hz陷波滤波器时,把带宽设成了48-52 Hz。结果发现附近频段的信号也被衰减了,影响了后续的频带特征提取。现在我建议用窄带陷波(49.5-50.5 Hz),或者用自适应滤波。
4. 预处理流程:从原始信号到干净数据
预处理是EEG分析中最耗时的一步,但也是最关键的一步。我总结了一个标准流程:
- 数据加载与可视化:先看一眼原始信号,心里有个数
- 重参考:常用平均参考或双极参考
- 滤波:0.5-50 Hz带通滤波(去除低频漂移和高频噪声)
- 坏导检测与插值:识别阻抗过高或信号异常的通道
- 伪迹去除:ICA或阈值法去除眼电、肌电
- 分段与基线校正:按事件标记切分数据
- 伪迹剔除:去除幅度超过±100 μV的试次
下面是我常用的预处理代码片段:
import mne
# 加载原始数据
raw = mne.io.read_raw_brainvision('subj01.vhdr', preload=True)
# 设置电极位置
montage = mne.channels.make_standard_montage('standard_1020')
raw.set_montage(montage)
# 滤波
raw.filter(0.5, 50, fir_design='firwin')
# 去除工频干扰
raw.notch_filter(50, notch_widths=2)
# ICA去除眼电
ica = mne.preprocessing.ICA(n_components=20, random_state=42)
ica.fit(raw)
eog_indices, eog_scores = ica.find_bads_eog(raw, ch_name=['Fp1', 'Fp2'])
ica.exclude = eog_indices
raw_clean = ica.apply(raw)
你可能会问:为什么先滤波再做ICA?我个人习惯是先滤波,因为低频漂移和高频噪声会影响ICA的分解质量。但有些同行喜欢先ICA再滤波,各有道理。我建议你两种都试试,看哪个效果更好。
跨被试迁移学习的预处理要点:
- 所有被试使用相同的预处理参数(滤波范围、ICA成分数等)
- 记录每个被试剔除的试次比例,如果某个被试剔除太多(>30%),建议重新采集
- 保存预处理后的数据,避免每次跑实验都重新处理
知识体系总览
为了让你更直观地理解本章内容,我画了一张结构图:
这张图把四个核心模块串起来了。你想想看,从采集原理到预处理,每一步都影响着后续迁移学习的效果。我见过太多人跳过预处理直接上模型,结果就是"垃圾进,垃圾出"。
好了,这一讲就到这里。记住:好的EEG数据是成功的一半。下一讲我们会深入迁移学习的核心方法,到时候见。
公众号:蓝海资料掘金营,微信deep3321