ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

EEGNet三种卷积层图解:从时间卷积到可分离卷积的完整拆解

EEGNet三种卷积层图解:从时间卷积到可分离卷积的完整拆解 去年年底我把EEGnet的论文从头到尾啃了一遍代码也照着Keras官方实现跑通了。说实话刚接触这个模型的时候读论文里的Figure 2是一脸懵的一张网络图上画了Conv2D、DepthwiseConv2D、SeparableConv2D三种卷积层乍一看都叫卷积实际干的事情完全不同。我当时最大的困惑就是“为什么不能直接用一层普通卷积搞定”以及“这三个操作分别在脑电信号上做了什么”。后来自己动手把每一层的前向传播过程、特征图尺寸变化、参数量都画了出来才真正理解这套设计的精妙之处。这篇内容就是想把当时画图搞懂的整个过程整理出来把EEGnet的三种卷积层操作拆开讲清楚从脑电信号的特点、每种卷积的计算逻辑到完整尺寸推演和复现时容易踩的坑一次讲透。如果你正在做脑机接口、情绪识别、睡眠分期这类任务或者只是想在小型时序数据集上找一个参数少、效果稳的基线模型这篇应该能帮你省下不少看代码和猜图的时间。1. 脑电信号为什么难处理频段、通道、样本量三个暴击1.1 脑电信号的“三维组织方式”先别急着看网络结构得先搞清楚EEGnet的输入到底长什么样否则后面讲卷积操作的时候很容易对不上号。一段原始脑电信号放在数组里看是二维的形状是(C, T)其中 C 是电极通道数T 是时间采样点数。举个例子64导联的脑电帽采样率250Hz采集2秒数据得到的就是(64, 500)的矩阵。但在神经网络里这个二维矩阵通常还要扩展一维变成(1, C, T)或者(C, T, 1)多出来的这一维是卷积神经网络的“通道维”。这里特别容易绕晕脑电的“通道”和卷积网络的“通道”是两个概念。EEGnet输入里的1是卷积网络的通道数C和T反而被当成类似图像的“空间尺寸”来处理。为什么这么组织因为EEGnet的做法是把脑电信号当作“伪图像”来处理时间维像图像的宽度电极通道维像图像的高度卷积网络的通道维为1。这样一来所有成熟的2D卷积操作都能直接复用不需要写特殊的1D网络结构。理解这一点后面看三种卷积层的kernel尺寸就顺了。脑电信号本身的特性也给建模出了难题。一是信噪比极低几微伏到几百微伏的幅值里混着肌电、眼电、工频干扰二是有效信息分散在多个频段比如α波8-13Hz、β波13-30Hz不同任务激活的频段不一样三是空间模式复杂某个认知状态往往对应多个电极的协同变化单看某一个通道很难判断。传统做法是先做带通滤波再用CSP公共空间模式做空间滤波最后提取特征喂给分类器。EEGnet的巧妙之处在于它把“频段特征提取”和“空间特征提取”直接设计成了卷积层让网络自己学这就是为什么它有三种不同的卷积层操作。1.2 紧凑模型是BCI落地绕不开的路脑电建模还有一个客观限制样本量太少。做一次脑电实验能采到的有效 trial 通常只有几十到几百个这和ImageNet那种百万级数据集完全不是一个量级。如果直接上一个ResNet这样的大模型大概率是严重过拟合——训练集损失降到底验证集一塌糊涂。EEGnet在论文里反复强调的关键词是“compact”紧凑。整个模型的可训练参数量才几千个后面第3章会具体算却能在一堆BCI竞赛数据集上取得和当时很多复杂模型相当甚至更好的效果。这种“小模型也能干活”的特性恰恰是BCI实时系统最需要的。嵌入式设备、在线解码、反馈实验都对延迟和显存有要求模型越小部署越现实。所以EEGnet的设计哲学可以概括成一句话用最少的参数把脑电信号里最核心的“时间节律”和“空间模式”提取出来。三种卷积层正好各自承担一部分工作下面一章就逐个拆解。2. 三种卷积层图解时间卷积、空间深度卷积、可分离卷积各在干什么2.1 第1种操作时间卷积Conv2D先沿时间轴扫一遍EEGnet里的第一种卷积操作论文图中标注为Conv2D实际是时间卷积卷积核尺寸是(1, 64)只在时间维上滑动不做任何跨通道操作。这一步的作用是提取每个电极通道上的时间节律模式类似带通滤波但比固定滤波器更灵活。我当年画图时第一步就是把三维特征图画成一个小长方体然后让卷积核沿着时间轴慢慢滑动输入特征图(1, C, T) 例如 (1, 64, 128) 卷积核 (1, 64) —— 高度是1宽度是64 步长 1 padding: same时间维长度不变 时间轴 → ┌──────────────────────────────────────────┐ │ 通道1 ──┐ │ │ 通道2 ──┤ 这个卷积核只在时间方向滑 │ │ ... │ 每次覆盖连续64个采样点 │ │ 通道C ──┘ 在当前电极通道上做加权求和 │ └──────────────────────────────────────────┘这里有个容易忽略的点虽然输入有C个电极通道但这个时间卷积核的高度是1它是在每个电极通道上独立做卷积的。也就是说64个电极通道共享同一套时间卷积核论文默认F18即8个不同的时间卷积核每个核可以看作一个“可学习的带通滤波器组”。如果采样率是128Hz64个采样点就是0.5秒的信号长度正好覆盖几个完整周期的α波如果采样率是250Hz同样的0.5秒需要125个采样点这一步就涉及后面第4章说的参数联动调整。为什么不能用普通的全连接层或者1D卷积代替因为2D卷积配合(1, 64)这个尺寸可以让不同电极通道共享同一套滤波器参数。脑电的节律特征比如α波、β波在所有电极上形态是相似的共享参数一方面大幅减少模型参数另一方面也让模型具备一定的跨通道泛化能力。这一步的输出形状是(F1, C, T)其中F18相当于在每个电极上得到了8组“频率特征图”。2.2 第2种操作空间深度卷积DepthwiseConv2D跨通道融合第二种卷积层是DepthwiseConv2D在EEGnet里也叫空间卷积。它的卷积核尺寸是(C, 1)也就是说卷积核的高度等于全部电极通道数C宽度只有1。这一步可以把前面得来的8组时间特征图在空间方向上进行融合。为了画清楚我把它理解成对每个时间特征图单独做一次“跨电极加权组合”输入特征图(F18, C64, T128) 卷积核 (C64, 1) —— 高度覆盖全部电极宽度为1 对第1个特征图把当前时刻所有64个电极的值加权求和得到一个值 对第2个特征图同样操作但权重不同 ... 因为是depthwise卷积每个特征图独立计算互不干扰 电极维 ┌──────────────────────┐ │ 电极1 ─┐ │ │ 电极2 │ 卷积核高64 │ │ ... │ 一次覆盖全部 │ │ 电极64 ┘ │ └──────────────────────┘ ↓ (16, 1, T) —— 所有电极信息融合成一个空间单元这个操作思想上是向CSP公共空间模式靠拢的。CSP的核心就是寻找一组空间滤波器让两类任务下信号的方差差异最大化。EEGnet用深度卷积替代了手动设计的空间滤波器让网络根据任务loss自动学习每个电极的权重组合。但值得注意的是它用的是深度卷积不是普通卷积普通卷积会同时融合所有输入特征图通道而深度卷积对每个输入通道单独做卷积输出通道数和输入通道数是倍数关系。这里论文默认depth_multiplier2所以输入8个特征图输出变成8 * 2 16个特征图。为什么要2倍给模型多一点空间特征表达能力相当于每个时间特征图可以学出两个不同的空间滤波模式。这一步过后原来(8, 64, 128)的特征图变成了(16, 1, 128)电极维度被“压扁”了所有通道信息融合成了一个综合的空间表达。这也是EEGnet最关键的一步后面再接时间维度的处理就不再关心具体是哪个电极了。2.3 第3种操作可分离卷积SeparableConv2D深度可分离降参第三种卷积层叫SeparableConv2D可分离卷积。这个层在EEGnet里放在第二个block中用来进一步提取短时的时序特征同时把特征图的通道数整理成更紧凑的表示。可分离卷积拆成两步先做深度卷积再做1x1逐点卷积。以EEGnet默认参数为例深度卷积核尺寸是(1, 16)在时间方向上滑动每个特征图独立处理然后接一个核尺寸(1, 1)的逐点卷积把16个特征图在通道维度上加权融合输出 F216 个新特征图。第一步深度卷积DepthwiseConv2D 输入 (16, 1, 32) → 卷积核 (1, 16) → 输出 (16, 1, 32) 每个特征图只做自己时间轴上的短时卷积不跨通道 第二步逐点卷积Conv2D 1x1 输入 (16, 1, 32) → 卷积核 (1, 1) → 输出 (16, 1, 32) 这一步把16个特征图的结果在通道维上做线性组合实现跨特征图融合为什么非要用这种“拆两步”的卷积直接用一个普通的(16, 1, 16)卷积核不是更简单吗问题出在参数量上。假设输入特征图通道数是16输出也是16核尺寸在时间方向是16普通卷积的参数量16输出通道× 16输入通道× 1 × 16 4096 个权重可分离卷积的参数量深度卷积部分 16输入通道× 1 × 16 256逐点卷积部分 16输出通道× 16输入通道× 1 × 1 256合计512个权重参数量直接缩小到原来的八分之一。在脑电这种小样本场景下这种压缩很有价值。而且从效果上看深度卷积负责在每个特征图上提取局部时间模式逐点卷积负责把不同特征图的信息组合分工明确表达能力和普通卷积接近但需要拟合的参数少得多。到了这一层三种卷积操作就齐了。可以直观地总结一下时间卷积负责“频段筛选”空间深度卷积负责“通道融合”可分离卷积负责“短时特征提取特征重组”。三者组合起来几乎对应了脑电信号处理里经典的“滤波→空间滤波→特征分类”pipeline只不过全部变成了可学习的模块。3. 把三种卷积串起来完整前向传播尺寸推演3.1 输入、池化、Dropout这些“配角”也不能忽略论文图里还有几个容易被忽略的操作BatchNorm、ELU激活、平均池化、Dropout。这些不是卷积层但直接决定了网络能否训练起来、尺寸怎么变化。BatchNorm放在每个卷积层之后作用是稳定训练。脑电数据不同trial之间的幅值差异很大同一个被试不同时段的数据分布也可能漂移BatchNorm能强制把特征分布拉回均值为0、方差为1附近让模型不用花大力气适应幅值波动。EEGnet论文里的ELU激活函数也值得一提ELU在负数区域不是硬截断而是平滑过渡对脑电这种包含大量微弱负向波动的信号来说能保留更多信息。池化层用的是 AveragePooling2D分别发生在第一个block末和第二个block末。第一个block后池化核是(1, 4)把时间维压缩4倍第二个block后池化核是(1, 8)再压缩8倍。两次池化一共把时间维压缩32倍。这意味着如果输入时间长度是128经过两次池化后时间维只剩4。这种大幅压缩不是随便设计的而是为了让最后分类层看到的特征具有平移不变性同时把序列信息压缩成相对稳定的统计量。其实对于BCI任务分类器并不需要知道某个波形精确出现在第几个采样点只要知道“大概在这个时间窗内有这种模式”就够了。Dropout放在每个block的池化之后默认0.25作用是缓解小样本下的过拟合。它相当于在训练时随机丢弃一部分特征迫使网络学到更鲁棒的模式而不是过度依赖某几个特征图。3.2 用一张尺寸表核对自己的实现为了确保自己对模型没有理解偏差我把所有层的输入输出尺寸和参数量列成了一张表以输入(1, C64, T128)、默认参数 F18、D2、F216 为例。这张表后来也成了我复现时排查维度的主要参考。层操作核尺寸/参数输出形状参数量约Input-(1, 64, 128)0Conv2D(1, 64), F18(8, 64, 128)520BatchNorm-(8, 64, 128)16DepthwiseConv2D(64, 1), depth_multiplier2(16, 1, 128)1040BatchNorm-(16, 1, 128)32ELU-(16, 1, 128)0AveragePooling2D(1, 4)(16, 1, 32)0Dropout(0.25)-(16, 1, 32)0SeparableConv2D(1, 16), F216(16, 1, 32)560BatchNorm-(16, 1, 32)32ELU-(16, 1, 32)0AveragePooling2D(1, 8)(16, 1, 4)0Dropout(0.25)-(16, 1, 4)0Flatten-640DenseN_classesN_classes64×N10整理完这张表有几个体验值得拿出来说第一DepthwiseConv2D的核尺寸是(64, 1)但这里的64是电极通道数如果你换了导联数比如14导联的消费级设备这个核高度也要改成14否则维度就对不上。很多复现代码报维度错误原因就在这里。第二池化操作作用于时间维第一个block后时间维从128变32第二个block后从32变4如果原始窗口长度不是4的倍数也不是8的倍数最后一个Flatten的输出维度就不是64Dense层的输入维度也要跟着改。第三整个卷积部分的参数量加起来才2100左右对比普通CNN动辄几十万上百万的参数EEGnet确实是“小而能打”。4. 复现EEGnet的调参笔记为什么代码跑通但效果不对4.1 采样率和时间卷积核长度必须联动这是我在复现时踩的第一个坑。论文写的是时间卷积核长度64我直接套在自己的250Hz采样数据上结果验证集准确率一直上不去。后来一想64个采样点在128Hz采样率下是0.5秒但在250Hz下只有0.256秒能覆盖的完整脑电节律周期变少了相当于“滤波器”的频带分辨率完全变了。正确的做法是时间卷积核长度跟着采样率等比缩放。比如原设计在128Hz下核长64你的数据是256Hz核长就可以调整为128保持0.5秒的物理时间窗。第二个block里的(1, 16)时间卷积核同理。采样率差距不大时也可以先不调整但要意识到模型提取的节奏模式已经和论文设定不同了这会影响最终效果。另外时间窗口长度也要注意。EEGnet的两个池化层会把时间维压缩32倍如果输入时间长度是128最后时间维只剩4还有足够的可区分信息。如果窗口太短比如只有64个采样点第二个池化后时间维只剩2信息丢失严重如果窗口太长比如1000个采样点最后Flatten的维度会很大分类层参数变多小样本下容易过拟合。我的经验是在保持时间分辨率的前提下原始窗口长度调到128到256之间相对好用既能覆盖多个节律周期又不会让分类层过于臃肿。4.2 训练设置、batch size和BN的问题EEGnet论文里使用的是Adam优化器学习率方面论文给的设置比较激进实际复现时我更建议从0.001起步。脑电数据本身噪声大学习率太高容易在训练初期就震荡学习率太低又容易卡在局部最优。我自己习惯配合学习率衰减或者early stopping一旦验证集损失连续几个epoch不下降就调低学习率或者直接停止。Batch size这个参数在EEGnet里比在其他模型里更需要小心因为BatchNorm对batch的统计量很敏感。BCI实验数据量少如果batch size只有8或16BatchNorm计算的均值和方差波动很大训练和推理时的统计量不一致会让验证集结果忽高忽低。我有一次把batch size从32调到64验证集准确率从82%稳定到了86%原因就在这里。如果确实因为显存或数据量限制只能用很小的batch可以考虑把BatchNorm换成GroupNorm或者LayerNorm这类不依赖batch统计量的归一化方式在少样本脑电数据上往往更稳。Dropout的值也值得调一下。论文默认是0.25但这个值是针对它当时的训练数据量和任务难度设定的。如果你的分类任务很简单比如二分类且两类差异很大Dropout可以降到0.1甚至关掉如果类别很多且数据量寥寥适当提高到0.5能明显缓解过拟合。建议把这个当超参来对待而不是一直用默认值。4.3 分类头和损失函数怎么换EEGnet论文里的分类头是Flatten加Dense加Softmax适用于多分类任务。实际使用时这里可以灵活改二分类任务把Dense层输出改成1个节点配合Sigmoid和二元交叉熵损失训练更稳。连续值回归比如疲劳程度、注意力水平把Dense改成1个节点的线性输出损失函数换成MSE。想在特征层做领域自适应可以从Flatten之后那一层64维特征引出分支接上对抗判别器。这个64维特征本质上是原始脑电信号经过充分时空压缩后的浓缩表示做迁移学习效果不错。我试过在EEGnet的Flatten层后面接一个小的全连接层比如64→32→N来提升非线性表达能力在小数据集上有一点提升但代价是参数量增加过拟合风险也上升。要不要加建议用验证集准确率说话不要盲目堆结构。还有一个常被忽略的细节类别不平衡。BCI数据里不同类别的trial数经常不一样特别是“静息态”这类容易采集的类别数量往往比任务态多不少。如果不做处理模型会偏向多数类。建议先按类别统计trial数再决定用加权损失还是过采样解决。5. 从EEGnet里反推出来的通用经验与后续扩展5.1 这套设计对其他生理信号同样适用把EEGnet拆透之后我最大的收获其实不在脑电本身而是它给了一整套处理“低样本量时序信号”的通用范式先用窄核在时间维度提取局部节奏模式再用跨通道卷积融合多传感器信息然后用深度可分离卷积继续提特征并控制参数量最后用全局池化或大跨度池化压缩成分类特征。这套范式不只能用在EEG上。心电信号ECG的多导联数据、肌电信号EMG的多通道记录、甚至可穿戴设备里加速度计和陀螺仪的多轴时序数据结构上都类似通道数不多、样本量有限、信噪比一般、时间维度上的局部模式是关键。我后来在一个多通道心电分类任务里几乎原封不动地沿用了EEGnet的block设计只是把时间卷积核长度按照采样率做了调整效果比之前手搓的1D CNN基线好不少而且训练速度快得多。这里面最值得学习的是“深度卷积”的使用思路。很多人在处理多通道时序数据时习惯一上来就把所有通道拼成一个大的输入向量。EEGnet用空间深度卷积提示了一个更合理的方式先在每个通道上分别提取局部特征再在融合阶段把通道信息组合起来“分而治之”既减少参数又更符合物理含义。5.2 如果想进一步压参/提精度往哪里发力EEGnet已经很紧凑但如果你面对的数据量比论文里的BCI竞赛数据还少还可以从几个方向继续压参。一是把F1从8降到4D从2降到1模型容量直接砍一半适合只有几十个trial的极限小样本场景。二是把第二个block的SeparableConv2D替换成单纯的逐点卷积减少短时特征提取的开销如果任务本身对精细时序模式不敏感效果损失不大。三是把Dense分类层改成GlobalAveragePooling加一个全连接点直接去掉Flatten之后的向量展平参数。反过来如果数据量足够想提精度可以在时间卷积这一层做多尺度改进同时用(1, 32)、(1, 64)、(1, 128)三种不同长度的卷积核并行提取短、中、长三种时长的节奏模式然后拼在一起再送入空间卷积层。这类多尺度时间卷积在脑电上的提升通常比较明显毕竟不同脑电节律的频率范围跨越很大一个固定核长很难同时照顾到θ波和γ波。还有人在EEGnet的基础上引入注意力机制在空间卷积之后加一个通道注意力模块自动加权不同特征图的重要性。从我的实验经验看注意力在通道数较多大于16时收益更明显对于最紧凑的EEGnet配置帮助有限可以把它当作数据量充足时的锦上添花。最后分享一个我自己一直在用的组合拳把EEGnet当作特征提取器先在大规模公开数据上预训练然后在你的目标任务数据上冻结卷积层、只微调分类头。由于EEGnet参数量极少这种迁移策略即使在目标数据只有几十个trial时也能work是我在几个脑电项目里最稳妥的基线方案。
返回列表