【脑机接口 算法】EEGNet: 通用神经网络应用于脑电信号

本文介绍了一种名为EEGNet的紧凑型卷积神经网络,专为基于脑电图的脑机接口设计。研究显示,即使在训练数据有限的情况下,EEGNet也能在多种BCI范式中表现出强大的泛化能力和高精度,且其结构有助于解释性特征的提取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

中文题目

论文下载:

DOI:

算法程序下载:

地址

摘要

  脑机接口(BCI)使用神经活动作为控制信号,实现与计算机的直接通信。这种神经信号通常是从各种研究透彻的脑电图(EEG)信号中挑选出来的。卷积神经网络(CNN)主要用来自动特征提取和分类,其在计算机视觉和语音识别领域中的使用已经很广泛。CNN已成功应用于基于EEG的BCI;但是,CNN主要应用于单个BCI范式,在其他范式中的使用比较少,论文作者提出是否可以设计一个CNN架构来准确分类来自不同BCI范式的EEG信号,同时尽可能地紧凑(定义为模型中的参数数量)。该论文介绍了EEGNet,这是一种用于基于EEG的BCI的紧凑型卷积神经网络。论文介绍了使用深度和可分离卷积来构建特定于EEG的模型,该模型封装了脑机接口中常见的EEG特征提取概念。论文通过四种BCI范式(P300视觉诱发电位、错误相关负性反应(ERN)、运动相关皮层电位(MRCP)和感觉运动节律(SMR)),将EEGNet在主体内和跨主体分类方面与目前最先进的方法进行了比较。结果显示,在训练数据有限的情况下,EEGNet比参考算法具有更强的泛化能力和更高的性能。同时论文也证明了EEGNet可以有效地推广到ERP和基于振荡的BCI。

1 项目介绍

  实验结果如下图,P300数据集的所有CNN模型之间的差异非常小,但是MRCP数据集却存在显著的差异,两个EEGNet模型的性能都优于所有其他模型。对于ERN数据集来说,两个EEGNet模型的性能都优于其他所有模型(p < 0.05)。
在这里插入图片描述

2 EEGNet网络原理

  到目前为止,

2.1EEGNet原理架构

  
在这里插入图片描述

2.2FBCCA 算法

  FBCCA在

2.3自适应FBCCA算法

  从上述FBCCA算法可以看出,

3EEGNet网络实现

  

import numpy as np
from sklearn.metrics import roc_auc_score, precision_score, recall_score, accuracy_score
import torch
import torch.nn as nn
import torch.optim as optim
from torch.autograd import Variable
import torch.nn.functional as F
import torch.optim as optim

class EEGNet(nn.Module):
    def __init__(self):
        super(EEGNet, self).__init__()
        self.T = 120
        
        # Layer 1
        self.conv1 = nn.Conv2d(1, 16, (1, 64), padding = 0)
        self.batchnorm1 = nn.BatchNorm2d(16, False)
        
        # Layer 2
        self.padding1 = nn.ZeroPad2d((16, 17, 0, 1))
        self.conv2 = nn.Conv2d(1, 4, (2, 32))
        self.batchnorm2 = nn.BatchNorm2d(4, False)
        self.pooling2 = nn.MaxPool2d(2, 4)
        
        # Layer 3
        self.padding2 = nn.ZeroPad2d((2, 1, 4, 3))
        self.conv3 = nn.Conv2d(4, 4, (8, 4))
        self.batchnorm3 = nn.BatchNorm2d(4, False)
        self.pooling3 = nn.MaxPool2d((2, 4))
        
        # 全连接层
        # 此维度将取决于数据中每个样本的时间戳数。
        # I have 120 timepoints. 
        self.fc1 = nn.Linear(4*2*7, 1)
        

    def forward(self, x):
        # Layer 1
        x = F.elu(self.conv1(x))
        x = self.batchnorm1(x)
        x = F.dropout(x, 0.25)
        x = x.permute(0, 3, 1, 2)
        
        # Layer 2
        x = self.padding1(x)
        x = F.elu(self.conv2(x))
        x = self.batchnorm2(x)
        x = F.dropout(x, 0.25)
        x = self.pooling2(x)
        
        # Layer 3
        x = self.padding2(x)
        x = F.elu(self.conv3(x))
        x = self.batchnorm3(x)
        x = F.dropout(x, 0.25)
        x = self.pooling3(x)
        
        # 全连接层
        x = x.view(-1, 4*2*7)
        x = F.sigmoid(self.fc1(x))
        return x
def evaluate(model, X, Y, params = ["acc"]):
    results = []
    batch_size = 100
    
    predicted = []
    
    for i in range(len(X)//batch_size):
        s = i*batch_size
        e = i*batch_size+batch_size
        
        inputs = Variable(torch.from_numpy(X[s:e]))
        pred = model(inputs)
        
        predicted.append(pred.data.cpu().numpy())
        
    inputs = Variable(torch.from_numpy(X))
    predicted = model(inputs)
    predicted = predicted.data.cpu().numpy()
    """
    设置评估指标:
    acc:准确率
    auc:AUC 即 ROC 曲线对应的面积
    recall:召回率
    precision:精确率
    fmeasure:F值
    """
    for param in params:
        if param == 'acc':
            results.append(accuracy_score(Y, np.round(predicted)))
        if param == "auc":
            results.append(roc_auc_score(Y, predicted))
        if param == "recall":
            results.append(recall_score(Y, np.round(predicted)))
        if param == "precision":
            results.append(precision_score(Y, np.round(predicted)))
        if param == "fmeasure":
            precision = precision_score(Y, np.round(predicted))
            recall = recall_score(Y, np.round(predicted))
            results.append(2*precision*recall/ (precision+recall))
    return results


# 定义网络
net = EEGNet()
# 定义二分类交叉熵 (Binary Cross Entropy)
criterion = nn.BCELoss()
# 定义Adam优化器
optimizer = optim.Adam(net.parameters())

"""
生成训练数据集,数据集有100个样本
训练数据X_train:为[0,1)之间的随机数;
标签数据y_train:为0或1
"""
X_train = np.random.rand(100, 1, 120, 64).astype('float32')
y_train = np.round(np.random.rand(100).astype('float32')) 
"""
生成验证数据集,数据集有100个样本
验证数据X_val:为[0,1)之间的随机数;
标签数据y_val:为0或1
"""
X_val = np.random.rand(100, 1, 120, 64).astype('float32')
y_val = np.round(np.random.rand(100).astype('float32'))
"""
生成测试数据集,数据集有100个样本
测试数据X_test:为[0,1)之间的随机数;
标签数据y_test:为0或1
"""
X_test = np.random.rand(100, 1, 120, 64).astype('float32')
y_test = np.round(np.random.rand(100).astype('float32'))
batch_size = 32
# 训练 循环
for epoch in range(10): 
    print("\nEpoch ", epoch)
    
    running_loss = 0.0
    for i in range(len(X_train)//batch_size-1):
        s = i*batch_size
        e = i*batch_size+batch_size
        
        inputs = torch.from_numpy(X_train[s:e])
        labels = torch.FloatTensor(np.array([y_train[s:e]]).T*1.0)
        
        # wrap them in Variable
        inputs, labels = Variable(inputs), Variable(labels)

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        
        optimizer.step()
        
        running_loss += loss.item()
    
    # 验证
    params = ["acc", "auc", "fmeasure"]
    print(params)
    print("Training Loss ", running_loss)
    print("Train - ", evaluate(net, X_train, y_train, params))
    print("Validation - ", evaluate(net, X_val, y_val, params))
    print("Test - ", evaluate(net, X_test, y_test, params))

定义评估指标:

acc:准确率

auc:AUC 即 ROC 曲线对应的面积

recall:召回率

precision:精确率

fmeasure:F值

4结果

在这项工作中,我们提出了EEGNet,一个小型的卷积神经网络,用于基于脑电图的BCI,它可以在有限的数据存在的情况下泛化不同的BCI范式,并产生可解释的特征。我们通过四个EEG数据集:P300视觉诱发电位、错误相关负波(ERN)、运动相关皮层电位(MRCP)和感觉运动节律(SMR),对EEGNet与基于ERP和振荡的BCIs的最先进方法进行了评估。据我们所知,这是第一次验证跨多个BCI数据集使用单一网络架构的工作,每个数据集都有自己的特征和数据集大小。我们的工作介绍了使用深度和可分离卷积脑电图信号分类,并表明它们可以用来构建一个脑电图特定的模型,其中包含众所周知的脑电图特征提取概念。最后,通过使用特征可视化和消融分析,我们表明可以从EEGNet模型中提取神经生理学可解释的特征。最后这一发现尤其重要,因为它是理解CNN模型结构的有效性和鲁棒性的关键组成部分,不仅对EEG,而且对一般的CNN结构也是如此。

CNN的学习能力部分来自于它们从原始数据中自动提取复杂特征表示的能力。然而,由于这些特征不是由人类工程师手工设计的,理解这些特征的含义在生成可解释的模型方面是一个重大挑战。当cnn被用于脑电图数据的分析时,这一点尤其正确,因为神经信号的特征往往是非平稳的,并被噪声伪影损坏。在本研究中,我们展示了三种不同的方法来可视化EEGNet学到的特性:

(1)分析P300数据集上的空间滤波器输出,平均试次结果;

(2)可视化SMR数据集上的卷积核权值,并将其与FBCSP学到的权值进行比较;

(3)对MRCP和SMR数据集进行单试次相关性分析。对于ERN数据集,我们比较了单试次特征相关性和平均ERP,发现相关特征与正确和错误反馈试次的正峰值一致,这在之前的文献中已经表明与分类器性能呈正相关。此外,我们进行了一项特征消融研究,以了解分类决策对P300数据集上特定特征存在与否的影响。在每一项分析中,我们都表明EEGNet能够提取与已知神经生理现象相对应的可解释特征。

总体而言,DeepConvNet和EEGNet在所有跨被试分析中的分类表现相似,而DeepConvNet在几乎所有被试内分析中的分类表现较低(P300除外)。对这种差异的一种可能解释是用于训练模型的训练数据的数量;在跨被试分析中,训练集的大小大约是被试内分析的10-15倍。这表明,与EEGNet相比,DeepConvNet的数据密集型更强,考虑到DeepConvNet的模型规模比EEGNet大两个数量级,这一结果并不令人惊讶(见表3)。我们相信,这与DeepConvNet的开发人员最初报告的发现是一致的。他们指出,需要训练数据增强策略来获得对SMR数据集的良好分类性能。与他们的工作相比,我们表明EEGNet在所有测试数据集上表现良好,而不需要数据扩充,这使得模型在实践中更容易使用。

总的来说,我们发现,在被试内和跨被试分析中,ShallowConvNet倾向于在ERP BCI数据集上比在振荡BCI数据集(SMR)上表现更差,而在DeepConvNet上观察到相反的行为。我们认为这是由于ShallowConvNet架构专门设计用于提取频带特征;在主要特征是信号幅度的情况下(如许多ERP BCIs中的情况),ShallowConvNet的性能往往会受到影响。而DeepConvNet则相反;由于其架构的设计不是为了提取频率特征,所以在频率功率为主要特征的情况下,其性能较低。相比之下,我们发现EEGNet与ShallowConvNet在鼻中隔黏膜下切除术后的分类和DeepConvNet在ERP分类一样好,这表明EEGNet足够强劲的学习各种各样的功能范围的BCI任务。

鉴于MRCP和SMR之间的神经反应相似,ShallowConvNet在被试内MRCP分类上的严重不足是意料之外的,但ShallowConvNet在SMR上表现良好。这种表现上的差异并不是因为使用了大量的训练数据,因为被试内MRCP分类大约有700个训练试次,平均分布在左右手指运动中,而SMR数据集只有192个训练试次,平均分布在四个类别中。此外,在其他数据集(P300和ERN)上,我们没有观察到ShallowConvNet性能的大偏差。事实上,尽管该数据集是本研究使用的所有数据集中最小的(总共只有170个训练试次),但ShallowConvNet在被试内ERN分类方面表现得相当好。确定这一现象的潜在来源将在未来的研究中进行探索。

脑电图深度学习模型一般采用三种输入方式,取决于他们的目标应用程序:(1)脑电图信号的所有可用的通道,(2)变换后的EEG信号(通常是一个时频分解)的所有可用的通道或(3)变换后的EEG信号通道的一个子集。属于(2)的模型通常会看到数据维数显著增加,因此需要更多的数据或更多的模型正则化(或两者都需要)来学习有效的特征表示。这引入了更多必须学习的超参数,增加了由于超参数错误描述而导致的模型性能的潜在可变性。属于(3)的模型通常需要关于要选择的通道的先验知识。我们认为属于(1)的模型,例如EEGNet和其他模型,在输入维度和通过提供所有可用通道来发现相关特性的灵活性之间提供了最好的权衡。当BCI技术发展到新的应用程序空间时,这一点尤其重要,因为这些未来BCI所需的特性可能事先不知道。

总之,我们提出的EEGNet鲁棒性很好,表现很好,在多个数据集上可获得一系列可解释性特征。

### EEGNet 教程:深度学习脑电图分类 #### 紧凑型卷积神经网络简介 EEGNet 是一种专为基于脑电图(EEG)的脑机接口设计的紧凑型卷积神经网络。该模型旨在减少参数数量的同时保持高效的性能,适用于实时应用中的资源受限环境[^1]。 #### 网络架构详解 EEGNet 的核心组成部分包括两个主要模块: - **Block1**: 包含时间卷积层和空间滤波器,负责捕捉输入信号的时间特征并提取大脑不同区域之间的关联特性。 - **Block2**: 应用深度可分离卷积技术进一步压缩模型尺寸而不损失准确性;此阶段还引入了平均池化操作以降低维度。 最后是**预测层**, 它接收来自 Block2 处理后的特征映射作为输入,并输出最终类别概率分布用于决策判断。 #### 实现代码示例 下面是一个简单的 Python 代码片段展示如何构建一个基本版本的 EEGNet 架构: ```python import tensorflow as tf from tensorflow.keras.models import Model from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, AveragePooling2D, Flatten, Dense, DepthwiseConv2D def create_eegnet_model(input_shape=(1, 64, 128), num_classes=2): inputs = Input(shape=input_shape) # Temporal convolution and spatial filtering (Block1) block1 = Conv2D(filters=8, kernel_size=(1, 64), padding='same')(inputs) block1 = BatchNormalization()(block1) block1 = Activation('elu')(block1) # Separable convolutions with depth-wise separability (Block2) block2 = DepthwiseConv2D(kernel_size=(16, 1))(block1) block2 = BatchNormalization()(block2) block2 = Activation('elu')(block2) block2 = AveragePooling2D((4, 1))(block2) flatten = Flatten()(block2) dense = Dense(num_classes)(flatten) outputs = Activation('softmax')(dense) model = Model(inputs=inputs, outputs=outputs) return model ``` 上述实现仅提供了一个简化版框架供理解原理之用,在实际部署时可能需要根据具体应用场景调整超参数设置以及优化策略等细节部分。 #### 关键实验结果概述 研究表明,相比于传统方法和其他复杂度较高的深层架构而言,EEGNet 不仅能够显著提高计算效率而且还能获得更好的泛化能力。特别是在某些特定任务上实现了超越以往记录的表现水平,证明其有效性与优越性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高山仰止景

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值