
OpenBCI-脑电信号深度学习:CNN与RNN应用
文章目录
- OpenBCI-脑电信号深度学习:CNN与RNN应用
-
- 概述
- 一、深度学习在EEG处理中的优势
-
- [1.1 传统方法vs深度学习](#1.1 传统方法vs深度学习)
- [1.2 深度学习的优势](#1.2 深度学习的优势)
- [1.3 EEG深度学习挑战](#1.3 EEG深度学习挑战)
- 二、CNN在EEG中的应用
-
- [2.1 CNN原理概述](#2.1 CNN原理概述)
- [2.2 一维CNN处理EEG](#2.2 一维CNN处理EEG)
- [2.3 二维CNN处理EEG](#2.3 二维CNN处理EEG)
- [2.4 EEG到图像的转换](#2.4 EEG到图像的转换)
- 三、RNN在EEG中的应用
-
- [3.1 RNN原理概述](#3.1 RNN原理概述)
- [3.2 LSTM处理EEG](#3.2 LSTM处理EEG)
- [3.3 GRU处理EEG](#3.3 GRU处理EEG)
- 四、混合模型架构
-
- [4.1 CNN+LSTM混合模型](#4.1 CNN+LSTM混合模型)
- [4.2 Transformer模型](#4.2 Transformer模型)
- 五、数据预处理与增强
-
- [5.1 预处理流程](#5.1 预处理流程)
- [5.2 数据增强技术](#5.2 数据增强技术)
- [5.3 数据集准备](#5.3 数据集准备)
- 六、模型训练与评估
-
- [6.1 训练流程](#6.1 训练流程)
- [6.2 训练代码](#6.2 训练代码)
- [6.3 评估指标](#6.3 评估指标)
- 七、迁移学习
-
- [7.1 迁移学习原理](#7.1 迁移学习原理)
- [7.2 迁移学习实现](#7.2 迁移学习实现)
- 八、实战案例:运动想象分类
-
- [8.1 数据集描述](#8.1 数据集描述)
- [8.2 完整实现](#8.2 完整实现)
- 九、模型部署与优化
-
- [9.1 模型压缩](#9.1 模型压缩)
- [9.2 实时推理](#9.2 实时推理)
- 十、总结
关键字 : 深度学习, CNN, RNN, LSTM, EEG, 脑电信号, 脑机接口, BCI
概述
深度学习技术的兴起为脑电信号处理带来了革命性的突破。传统的机器学习方法依赖手工设计特征,而深度学习能够自动从原始信号中学习复杂特征表示。本文将深入介绍如何使用卷积神经网络(CNN)和循环神经网络(RNN)处理脑电信号。
一、深度学习在EEG处理中的优势
1.1 传统方法vs深度学习
#mermaid-svg-8xxLKSs521jf2Nsq{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8xxLKSs521jf2Nsq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8xxLKSs521jf2Nsq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8xxLKSs521jf2Nsq .error-icon{fill:#552222;}#mermaid-svg-8xxLKSs521jf2Nsq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8xxLKSs521jf2Nsq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8xxLKSs521jf2Nsq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8xxLKSs521jf2Nsq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8xxLKSs521jf2Nsq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8xxLKSs521jf2Nsq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8xxLKSs521jf2Nsq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8xxLKSs521jf2Nsq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8xxLKSs521jf2Nsq .marker.cross{stroke:#333333;}#mermaid-svg-8xxLKSs521jf2Nsq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8xxLKSs521jf2Nsq p{margin:0;}#mermaid-svg-8xxLKSs521jf2Nsq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8xxLKSs521jf2Nsq .cluster-label text{fill:#333;}#mermaid-svg-8xxLKSs521jf2Nsq .cluster-label span{color:#333;}#mermaid-svg-8xxLKSs521jf2Nsq .cluster-label span p{background-color:transparent;}#mermaid-svg-8xxLKSs521jf2Nsq .label text,#mermaid-svg-8xxLKSs521jf2Nsq span{fill:#333;color:#333;}#mermaid-svg-8xxLKSs521jf2Nsq .node rect,#mermaid-svg-8xxLKSs521jf2Nsq .node circle,#mermaid-svg-8xxLKSs521jf2Nsq .node ellipse,#mermaid-svg-8xxLKSs521jf2Nsq .node polygon,#mermaid-svg-8xxLKSs521jf2Nsq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8xxLKSs521jf2Nsq .rough-node .label text,#mermaid-svg-8xxLKSs521jf2Nsq .node .label text,#mermaid-svg-8xxLKSs521jf2Nsq .image-shape .label,#mermaid-svg-8xxLKSs521jf2Nsq .icon-shape .label{text-anchor:middle;}#mermaid-svg-8xxLKSs521jf2Nsq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8xxLKSs521jf2Nsq .rough-node .label,#mermaid-svg-8xxLKSs521jf2Nsq .node .label,#mermaid-svg-8xxLKSs521jf2Nsq .image-shape .label,#mermaid-svg-8xxLKSs521jf2Nsq .icon-shape .label{text-align:center;}#mermaid-svg-8xxLKSs521jf2Nsq .node.clickable{cursor:pointer;}#mermaid-svg-8xxLKSs521jf2Nsq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8xxLKSs521jf2Nsq .arrowheadPath{fill:#333333;}#mermaid-svg-8xxLKSs521jf2Nsq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8xxLKSs521jf2Nsq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8xxLKSs521jf2Nsq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8xxLKSs521jf2Nsq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8xxLKSs521jf2Nsq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8xxLKSs521jf2Nsq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8xxLKSs521jf2Nsq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8xxLKSs521jf2Nsq .cluster text{fill:#333;}#mermaid-svg-8xxLKSs521jf2Nsq .cluster span{color:#333;}#mermaid-svg-8xxLKSs521jf2Nsq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8xxLKSs521jf2Nsq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8xxLKSs521jf2Nsq rect.text{fill:none;stroke-width:0;}#mermaid-svg-8xxLKSs521jf2Nsq .icon-shape,#mermaid-svg-8xxLKSs521jf2Nsq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8xxLKSs521jf2Nsq .icon-shape p,#mermaid-svg-8xxLKSs521jf2Nsq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8xxLKSs521jf2Nsq .icon-shape .label rect,#mermaid-svg-8xxLKSs521jf2Nsq .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8xxLKSs521jf2Nsq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8xxLKSs521jf2Nsq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8xxLKSs521jf2Nsq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 深度学习
端到端
原始EEG
自动特征学习
特征提取
分类
输出
传统方法
手工设计
原始EEG
手动特征提取
特征选择
分类器
输出
1.2 深度学习的优势
#mermaid-svg-fgBIVJaamqWMiL2Q{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-fgBIVJaamqWMiL2Q .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fgBIVJaamqWMiL2Q .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fgBIVJaamqWMiL2Q .error-icon{fill:#552222;}#mermaid-svg-fgBIVJaamqWMiL2Q .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fgBIVJaamqWMiL2Q .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fgBIVJaamqWMiL2Q .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fgBIVJaamqWMiL2Q .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fgBIVJaamqWMiL2Q .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fgBIVJaamqWMiL2Q .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fgBIVJaamqWMiL2Q .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fgBIVJaamqWMiL2Q .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fgBIVJaamqWMiL2Q .marker.cross{stroke:#333333;}#mermaid-svg-fgBIVJaamqWMiL2Q svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fgBIVJaamqWMiL2Q p{margin:0;}#mermaid-svg-fgBIVJaamqWMiL2Q .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-fgBIVJaamqWMiL2Q .cluster-label text{fill:#333;}#mermaid-svg-fgBIVJaamqWMiL2Q .cluster-label span{color:#333;}#mermaid-svg-fgBIVJaamqWMiL2Q .cluster-label span p{background-color:transparent;}#mermaid-svg-fgBIVJaamqWMiL2Q .label text,#mermaid-svg-fgBIVJaamqWMiL2Q span{fill:#333;color:#333;}#mermaid-svg-fgBIVJaamqWMiL2Q .node rect,#mermaid-svg-fgBIVJaamqWMiL2Q .node circle,#mermaid-svg-fgBIVJaamqWMiL2Q .node ellipse,#mermaid-svg-fgBIVJaamqWMiL2Q .node polygon,#mermaid-svg-fgBIVJaamqWMiL2Q .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fgBIVJaamqWMiL2Q .rough-node .label text,#mermaid-svg-fgBIVJaamqWMiL2Q .node .label text,#mermaid-svg-fgBIVJaamqWMiL2Q .image-shape .label,#mermaid-svg-fgBIVJaamqWMiL2Q .icon-shape .label{text-anchor:middle;}#mermaid-svg-fgBIVJaamqWMiL2Q .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-fgBIVJaamqWMiL2Q .rough-node .label,#mermaid-svg-fgBIVJaamqWMiL2Q .node .label,#mermaid-svg-fgBIVJaamqWMiL2Q .image-shape .label,#mermaid-svg-fgBIVJaamqWMiL2Q .icon-shape .label{text-align:center;}#mermaid-svg-fgBIVJaamqWMiL2Q .node.clickable{cursor:pointer;}#mermaid-svg-fgBIVJaamqWMiL2Q .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-fgBIVJaamqWMiL2Q .arrowheadPath{fill:#333333;}#mermaid-svg-fgBIVJaamqWMiL2Q .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-fgBIVJaamqWMiL2Q .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-fgBIVJaamqWMiL2Q .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fgBIVJaamqWMiL2Q .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-fgBIVJaamqWMiL2Q .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fgBIVJaamqWMiL2Q .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-fgBIVJaamqWMiL2Q .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-fgBIVJaamqWMiL2Q .cluster text{fill:#333;}#mermaid-svg-fgBIVJaamqWMiL2Q .cluster span{color:#333;}#mermaid-svg-fgBIVJaamqWMiL2Q div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fgBIVJaamqWMiL2Q .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-fgBIVJaamqWMiL2Q rect.text{fill:none;stroke-width:0;}#mermaid-svg-fgBIVJaamqWMiL2Q .icon-shape,#mermaid-svg-fgBIVJaamqWMiL2Q .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fgBIVJaamqWMiL2Q .icon-shape p,#mermaid-svg-fgBIVJaamqWMiL2Q .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-fgBIVJaamqWMiL2Q .icon-shape .label rect,#mermaid-svg-fgBIVJaamqWMiL2Q .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fgBIVJaamqWMiL2Q .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-fgBIVJaamqWMiL2Q .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-fgBIVJaamqWMiL2Q :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 深度学习优势
自动特征学习
端到端训练
处理复杂模式
泛化能力强
大规模数据处理
无需领域专家
发现隐藏特征
非线性关系
时空模式
1.3 EEG深度学习挑战
| 挑战 | 描述 | 解决方案 |
|---|---|---|
| 数据量小 | EEG数据集通常较小 | 数据增强、迁移学习 |
| 噪声大 | 信号质量受多种因素影响 | 预处理、正则化 |
| 个体差异 | 不同人EEG差异大 | 个性化模型、自适应 |
| 计算资源 | 深度学习需要GPU | 轻量级模型、量化 |
二、CNN在EEG中的应用
2.1 CNN原理概述
#mermaid-svg-G56JD02ZzwlPiDkM{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-G56JD02ZzwlPiDkM .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-G56JD02ZzwlPiDkM .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-G56JD02ZzwlPiDkM .error-icon{fill:#552222;}#mermaid-svg-G56JD02ZzwlPiDkM .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-G56JD02ZzwlPiDkM .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-G56JD02ZzwlPiDkM .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-G56JD02ZzwlPiDkM .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-G56JD02ZzwlPiDkM .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-G56JD02ZzwlPiDkM .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-G56JD02ZzwlPiDkM .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-G56JD02ZzwlPiDkM .marker{fill:#333333;stroke:#333333;}#mermaid-svg-G56JD02ZzwlPiDkM .marker.cross{stroke:#333333;}#mermaid-svg-G56JD02ZzwlPiDkM svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-G56JD02ZzwlPiDkM p{margin:0;}#mermaid-svg-G56JD02ZzwlPiDkM .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-G56JD02ZzwlPiDkM .cluster-label text{fill:#333;}#mermaid-svg-G56JD02ZzwlPiDkM .cluster-label span{color:#333;}#mermaid-svg-G56JD02ZzwlPiDkM .cluster-label span p{background-color:transparent;}#mermaid-svg-G56JD02ZzwlPiDkM .label text,#mermaid-svg-G56JD02ZzwlPiDkM span{fill:#333;color:#333;}#mermaid-svg-G56JD02ZzwlPiDkM .node rect,#mermaid-svg-G56JD02ZzwlPiDkM .node circle,#mermaid-svg-G56JD02ZzwlPiDkM .node ellipse,#mermaid-svg-G56JD02ZzwlPiDkM .node polygon,#mermaid-svg-G56JD02ZzwlPiDkM .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-G56JD02ZzwlPiDkM .rough-node .label text,#mermaid-svg-G56JD02ZzwlPiDkM .node .label text,#mermaid-svg-G56JD02ZzwlPiDkM .image-shape .label,#mermaid-svg-G56JD02ZzwlPiDkM .icon-shape .label{text-anchor:middle;}#mermaid-svg-G56JD02ZzwlPiDkM .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-G56JD02ZzwlPiDkM .rough-node .label,#mermaid-svg-G56JD02ZzwlPiDkM .node .label,#mermaid-svg-G56JD02ZzwlPiDkM .image-shape .label,#mermaid-svg-G56JD02ZzwlPiDkM .icon-shape .label{text-align:center;}#mermaid-svg-G56JD02ZzwlPiDkM .node.clickable{cursor:pointer;}#mermaid-svg-G56JD02ZzwlPiDkM .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-G56JD02ZzwlPiDkM .arrowheadPath{fill:#333333;}#mermaid-svg-G56JD02ZzwlPiDkM .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-G56JD02ZzwlPiDkM .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-G56JD02ZzwlPiDkM .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-G56JD02ZzwlPiDkM .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-G56JD02ZzwlPiDkM .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-G56JD02ZzwlPiDkM .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-G56JD02ZzwlPiDkM .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-G56JD02ZzwlPiDkM .cluster text{fill:#333;}#mermaid-svg-G56JD02ZzwlPiDkM .cluster span{color:#333;}#mermaid-svg-G56JD02ZzwlPiDkM div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-G56JD02ZzwlPiDkM .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-G56JD02ZzwlPiDkM rect.text{fill:none;stroke-width:0;}#mermaid-svg-G56JD02ZzwlPiDkM .icon-shape,#mermaid-svg-G56JD02ZzwlPiDkM .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-G56JD02ZzwlPiDkM .icon-shape p,#mermaid-svg-G56JD02ZzwlPiDkM .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-G56JD02ZzwlPiDkM .icon-shape .label rect,#mermaid-svg-G56JD02ZzwlPiDkM .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-G56JD02ZzwlPiDkM .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-G56JD02ZzwlPiDkM .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-G56JD02ZzwlPiDkM :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 输入: EEG时间序列
卷积层1
激活函数ReLU
池化层1
卷积层2
激活函数ReLU
池化层2
全连接层
输出层
2.2 一维CNN处理EEG
python
import tensorflow as tf
from tensorflow.keras import layers, models
class EEG_CNN_Model:
def __init__(self, input_shape=(250, 8), num_classes=4):
self.input_shape = input_shape
self.num_classes = num_classes
def build_model(self):
model = models.Sequential([
layers.Conv1D(filters=32, kernel_size=5, activation='relu',
input_shape=self.input_shape),
layers.MaxPooling1D(pool_size=2),
layers.Conv1D(filters=64, kernel_size=5, activation='relu'),
layers.MaxPooling1D(pool_size=2),
layers.Conv1D(filters=128, kernel_size=5, activation='relu'),
layers.MaxPooling1D(pool_size=2),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dropout(0.5),
layers.Dense(self.num_classes, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
2.3 二维CNN处理EEG
python
class EEG_2DCNN_Model:
def __init__(self, input_shape=(32, 32, 1), num_classes=4):
self.input_shape = input_shape
self.num_classes = num_classes
def build_model(self):
model = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=self.input_shape),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(128, (3, 3), activation='relu'),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dropout(0.5),
layers.Dense(self.num_classes, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
2.4 EEG到图像的转换
python
def eeg_to_image(eeg_data, time_window=32, freq_bands=32):
"""将EEG数据转换为频谱图"""
import numpy as np
from scipy import signal
n_channels = eeg_data.shape[1]
images = []
for i in range(n_channels):
f, t, Sxx = signal.spectrogram(eeg_data[:, i], fs=250,
nperseg=time_window, noverlap=time_window//2)
Sxx = Sxx[:freq_bands, :time_window]
images.append(Sxx)
return np.stack(images, axis=-1)
三、RNN在EEG中的应用
3.1 RNN原理概述
输出 RNN单元 输入序列 输出 RNN单元 输入序列 #mermaid-svg-A29QiNc2mRmC9d34{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-A29QiNc2mRmC9d34 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-A29QiNc2mRmC9d34 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-A29QiNc2mRmC9d34 .error-icon{fill:#552222;}#mermaid-svg-A29QiNc2mRmC9d34 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-A29QiNc2mRmC9d34 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-A29QiNc2mRmC9d34 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-A29QiNc2mRmC9d34 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-A29QiNc2mRmC9d34 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-A29QiNc2mRmC9d34 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-A29QiNc2mRmC9d34 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-A29QiNc2mRmC9d34 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-A29QiNc2mRmC9d34 .marker.cross{stroke:#333333;}#mermaid-svg-A29QiNc2mRmC9d34 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-A29QiNc2mRmC9d34 p{margin:0;}#mermaid-svg-A29QiNc2mRmC9d34 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-A29QiNc2mRmC9d34 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-A29QiNc2mRmC9d34 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-A29QiNc2mRmC9d34 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-A29QiNc2mRmC9d34 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-A29QiNc2mRmC9d34 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-A29QiNc2mRmC9d34 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-A29QiNc2mRmC9d34 .sequenceNumber{fill:white;}#mermaid-svg-A29QiNc2mRmC9d34 #sequencenumber{fill:#333;}#mermaid-svg-A29QiNc2mRmC9d34 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-A29QiNc2mRmC9d34 .messageText{fill:#333;stroke:none;}#mermaid-svg-A29QiNc2mRmC9d34 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-A29QiNc2mRmC9d34 .labelText,#mermaid-svg-A29QiNc2mRmC9d34 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-A29QiNc2mRmC9d34 .loopText,#mermaid-svg-A29QiNc2mRmC9d34 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-A29QiNc2mRmC9d34 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-A29QiNc2mRmC9d34 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-A29QiNc2mRmC9d34 .noteText,#mermaid-svg-A29QiNc2mRmC9d34 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-A29QiNc2mRmC9d34 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-A29QiNc2mRmC9d34 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-A29QiNc2mRmC9d34 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-A29QiNc2mRmC9d34 .actorPopupMenu{position:absolute;}#mermaid-svg-A29QiNc2mRmC9d34 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-A29QiNc2mRmC9d34 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-A29QiNc2mRmC9d34 .actor-man circle,#mermaid-svg-A29QiNc2mRmC9d34 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-A29QiNc2mRmC9d34 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 记忆机制 x_t h_t = f(W*h_{t-1} + U*x_t) y_t
3.2 LSTM处理EEG
python
class EEG_LSTM_Model:
def __init__(self, input_shape=(250, 8), num_classes=4):
self.input_shape = input_shape
self.num_classes = num_classes
def build_model(self):
model = models.Sequential([
layers.LSTM(64, return_sequences=True, input_shape=self.input_shape),
layers.LSTM(128, return_sequences=True),
layers.LSTM(64),
layers.Dense(128, activation='relu'),
layers.Dropout(0.5),
layers.Dense(self.num_classes, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
3.3 GRU处理EEG
python
class EEG_GRU_Model:
def __init__(self, input_shape=(250, 8), num_classes=4):
self.input_shape = input_shape
self.num_classes = num_classes
def build_model(self):
model = models.Sequential([
layers.GRU(64, return_sequences=True, input_shape=self.input_shape),
layers.GRU(128, return_sequences=True),
layers.GRU(64),
layers.Dense(128, activation='relu'),
layers.Dropout(0.5),
layers.Dense(self.num_classes, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
四、混合模型架构
4.1 CNN+LSTM混合模型
#mermaid-svg-shUf7LUpPKewWeJK{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-shUf7LUpPKewWeJK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-shUf7LUpPKewWeJK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-shUf7LUpPKewWeJK .error-icon{fill:#552222;}#mermaid-svg-shUf7LUpPKewWeJK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-shUf7LUpPKewWeJK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-shUf7LUpPKewWeJK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-shUf7LUpPKewWeJK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-shUf7LUpPKewWeJK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-shUf7LUpPKewWeJK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-shUf7LUpPKewWeJK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-shUf7LUpPKewWeJK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-shUf7LUpPKewWeJK .marker.cross{stroke:#333333;}#mermaid-svg-shUf7LUpPKewWeJK svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-shUf7LUpPKewWeJK p{margin:0;}#mermaid-svg-shUf7LUpPKewWeJK .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-shUf7LUpPKewWeJK .cluster-label text{fill:#333;}#mermaid-svg-shUf7LUpPKewWeJK .cluster-label span{color:#333;}#mermaid-svg-shUf7LUpPKewWeJK .cluster-label span p{background-color:transparent;}#mermaid-svg-shUf7LUpPKewWeJK .label text,#mermaid-svg-shUf7LUpPKewWeJK span{fill:#333;color:#333;}#mermaid-svg-shUf7LUpPKewWeJK .node rect,#mermaid-svg-shUf7LUpPKewWeJK .node circle,#mermaid-svg-shUf7LUpPKewWeJK .node ellipse,#mermaid-svg-shUf7LUpPKewWeJK .node polygon,#mermaid-svg-shUf7LUpPKewWeJK .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-shUf7LUpPKewWeJK .rough-node .label text,#mermaid-svg-shUf7LUpPKewWeJK .node .label text,#mermaid-svg-shUf7LUpPKewWeJK .image-shape .label,#mermaid-svg-shUf7LUpPKewWeJK .icon-shape .label{text-anchor:middle;}#mermaid-svg-shUf7LUpPKewWeJK .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-shUf7LUpPKewWeJK .rough-node .label,#mermaid-svg-shUf7LUpPKewWeJK .node .label,#mermaid-svg-shUf7LUpPKewWeJK .image-shape .label,#mermaid-svg-shUf7LUpPKewWeJK .icon-shape .label{text-align:center;}#mermaid-svg-shUf7LUpPKewWeJK .node.clickable{cursor:pointer;}#mermaid-svg-shUf7LUpPKewWeJK .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-shUf7LUpPKewWeJK .arrowheadPath{fill:#333333;}#mermaid-svg-shUf7LUpPKewWeJK .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-shUf7LUpPKewWeJK .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-shUf7LUpPKewWeJK .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-shUf7LUpPKewWeJK .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-shUf7LUpPKewWeJK .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-shUf7LUpPKewWeJK .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-shUf7LUpPKewWeJK .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-shUf7LUpPKewWeJK .cluster text{fill:#333;}#mermaid-svg-shUf7LUpPKewWeJK .cluster span{color:#333;}#mermaid-svg-shUf7LUpPKewWeJK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-shUf7LUpPKewWeJK .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-shUf7LUpPKewWeJK rect.text{fill:none;stroke-width:0;}#mermaid-svg-shUf7LUpPKewWeJK .icon-shape,#mermaid-svg-shUf7LUpPKewWeJK .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-shUf7LUpPKewWeJK .icon-shape p,#mermaid-svg-shUf7LUpPKewWeJK .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-shUf7LUpPKewWeJK .icon-shape .label rect,#mermaid-svg-shUf7LUpPKewWeJK .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-shUf7LUpPKewWeJK .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-shUf7LUpPKewWeJK .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-shUf7LUpPKewWeJK :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} EEG输入
CNN层
特征图
LSTM层
时序特征
全连接层
输出
python
class EEG_CNN_LSTM_Model:
def __init__(self, input_shape=(250, 8), num_classes=4):
self.input_shape = input_shape
self.num_classes = num_classes
def build_model(self):
inputs = layers.Input(shape=self.input_shape)
x = layers.Conv1D(32, 5, activation='relu')(inputs)
x = layers.MaxPooling1D(2)(x)
x = layers.Conv1D(64, 5, activation='relu')(x)
x = layers.MaxPooling1D(2)(x)
x = layers.LSTM(128, return_sequences=True)(x)
x = layers.LSTM(64)(x)
x = layers.Dense(128, activation='relu')(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(self.num_classes, activation='softmax')(x)
model = models.Model(inputs, outputs)
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
4.2 Transformer模型
python
class EEG_Transformer_Model:
def __init__(self, input_shape=(250, 8), num_classes=4, num_heads=4, d_model=64):
self.input_shape = input_shape
self.num_classes = num_classes
self.num_heads = num_heads
self.d_model = d_model
def build_model(self):
inputs = layers.Input(shape=self.input_shape)
x = layers.Dense(self.d_model, activation='relu')(inputs)
transformer_block = layers.MultiHeadAttention(
num_heads=self.num_heads, key_dim=self.d_model
)
x = transformer_block(x, x)
x = layers.LayerNormalization(epsilon=1e-6)(x)
x = layers.GlobalAveragePooling1D()(x)
x = layers.Dense(128, activation='relu')(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(self.num_classes, activation='softmax')(x)
model = models.Model(inputs, outputs)
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
五、数据预处理与增强
5.1 预处理流程
#mermaid-svg-dwx3B2AmS5rAVCBi{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-dwx3B2AmS5rAVCBi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dwx3B2AmS5rAVCBi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dwx3B2AmS5rAVCBi .error-icon{fill:#552222;}#mermaid-svg-dwx3B2AmS5rAVCBi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dwx3B2AmS5rAVCBi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dwx3B2AmS5rAVCBi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dwx3B2AmS5rAVCBi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dwx3B2AmS5rAVCBi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dwx3B2AmS5rAVCBi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dwx3B2AmS5rAVCBi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dwx3B2AmS5rAVCBi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dwx3B2AmS5rAVCBi .marker.cross{stroke:#333333;}#mermaid-svg-dwx3B2AmS5rAVCBi svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dwx3B2AmS5rAVCBi p{margin:0;}#mermaid-svg-dwx3B2AmS5rAVCBi .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-dwx3B2AmS5rAVCBi .cluster-label text{fill:#333;}#mermaid-svg-dwx3B2AmS5rAVCBi .cluster-label span{color:#333;}#mermaid-svg-dwx3B2AmS5rAVCBi .cluster-label span p{background-color:transparent;}#mermaid-svg-dwx3B2AmS5rAVCBi .label text,#mermaid-svg-dwx3B2AmS5rAVCBi span{fill:#333;color:#333;}#mermaid-svg-dwx3B2AmS5rAVCBi .node rect,#mermaid-svg-dwx3B2AmS5rAVCBi .node circle,#mermaid-svg-dwx3B2AmS5rAVCBi .node ellipse,#mermaid-svg-dwx3B2AmS5rAVCBi .node polygon,#mermaid-svg-dwx3B2AmS5rAVCBi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-dwx3B2AmS5rAVCBi .rough-node .label text,#mermaid-svg-dwx3B2AmS5rAVCBi .node .label text,#mermaid-svg-dwx3B2AmS5rAVCBi .image-shape .label,#mermaid-svg-dwx3B2AmS5rAVCBi .icon-shape .label{text-anchor:middle;}#mermaid-svg-dwx3B2AmS5rAVCBi .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-dwx3B2AmS5rAVCBi .rough-node .label,#mermaid-svg-dwx3B2AmS5rAVCBi .node .label,#mermaid-svg-dwx3B2AmS5rAVCBi .image-shape .label,#mermaid-svg-dwx3B2AmS5rAVCBi .icon-shape .label{text-align:center;}#mermaid-svg-dwx3B2AmS5rAVCBi .node.clickable{cursor:pointer;}#mermaid-svg-dwx3B2AmS5rAVCBi .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-dwx3B2AmS5rAVCBi .arrowheadPath{fill:#333333;}#mermaid-svg-dwx3B2AmS5rAVCBi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-dwx3B2AmS5rAVCBi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-dwx3B2AmS5rAVCBi .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dwx3B2AmS5rAVCBi .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-dwx3B2AmS5rAVCBi .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dwx3B2AmS5rAVCBi .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-dwx3B2AmS5rAVCBi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-dwx3B2AmS5rAVCBi .cluster text{fill:#333;}#mermaid-svg-dwx3B2AmS5rAVCBi .cluster span{color:#333;}#mermaid-svg-dwx3B2AmS5rAVCBi div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-dwx3B2AmS5rAVCBi .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-dwx3B2AmS5rAVCBi rect.text{fill:none;stroke-width:0;}#mermaid-svg-dwx3B2AmS5rAVCBi .icon-shape,#mermaid-svg-dwx3B2AmS5rAVCBi .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dwx3B2AmS5rAVCBi .icon-shape p,#mermaid-svg-dwx3B2AmS5rAVCBi .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-dwx3B2AmS5rAVCBi .icon-shape .label rect,#mermaid-svg-dwx3B2AmS5rAVCBi .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dwx3B2AmS5rAVCBi .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-dwx3B2AmS5rAVCBi .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-dwx3B2AmS5rAVCBi :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 原始EEG数据
滤波
去伪迹
分段
标准化
数据增强
模型输入
5.2 数据增强技术
python
class EEGDataAugmenter:
def __init__(self):
pass
def add_gaussian_noise(self, data, std=0.01):
noise = np.random.normal(0, std, data.shape)
return data + noise
def time_shift(self, data, shift_range=50):
shift = np.random.randint(-shift_range, shift_range)
return np.roll(data, shift, axis=0)
def amplitude_scale(self, data, scale_range=(0.9, 1.1)):
scale = np.random.uniform(*scale_range)
return data * scale
def time_warp(self, data, warp_factor=0.1):
from scipy.interpolate import interp1d
t = np.arange(len(data))
warped_t = t + np.random.normal(0, warp_factor, len(t))
warped_t = np.clip(warped_t, 0, len(data)-1)
interpolated = []
for i in range(data.shape[1]):
f = interp1d(t, data[:, i], kind='linear')
interpolated.append(f(warped_t))
return np.array(interpolated).T
def augment(self, data, augment_prob=0.5):
if np.random.random() < augment_prob:
data = self.add_gaussian_noise(data)
if np.random.random() < augment_prob:
data = self.time_shift(data)
if np.random.random() < augment_prob:
data = self.amplitude_scale(data)
if np.random.random() < augment_prob:
data = self.time_warp(data)
return data
5.3 数据集准备
python
def prepare_dataset(file_paths, labels, window_size=250, step_size=125):
import numpy as np
X = []
y = []
for file_path, label in zip(file_paths, labels):
data = np.load(file_path)
for i in range(0, len(data) - window_size, step_size):
window = data[i:i+window_size]
X.append(window)
y.append(label)
return np.array(X), np.array(y)
六、模型训练与评估
6.1 训练流程
#mermaid-svg-mklzIszzhigOkFz6{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mklzIszzhigOkFz6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mklzIszzhigOkFz6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mklzIszzhigOkFz6 .error-icon{fill:#552222;}#mermaid-svg-mklzIszzhigOkFz6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mklzIszzhigOkFz6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mklzIszzhigOkFz6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mklzIszzhigOkFz6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mklzIszzhigOkFz6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mklzIszzhigOkFz6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mklzIszzhigOkFz6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mklzIszzhigOkFz6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mklzIszzhigOkFz6 .marker.cross{stroke:#333333;}#mermaid-svg-mklzIszzhigOkFz6 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mklzIszzhigOkFz6 p{margin:0;}#mermaid-svg-mklzIszzhigOkFz6 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-mklzIszzhigOkFz6 .cluster-label text{fill:#333;}#mermaid-svg-mklzIszzhigOkFz6 .cluster-label span{color:#333;}#mermaid-svg-mklzIszzhigOkFz6 .cluster-label span p{background-color:transparent;}#mermaid-svg-mklzIszzhigOkFz6 .label text,#mermaid-svg-mklzIszzhigOkFz6 span{fill:#333;color:#333;}#mermaid-svg-mklzIszzhigOkFz6 .node rect,#mermaid-svg-mklzIszzhigOkFz6 .node circle,#mermaid-svg-mklzIszzhigOkFz6 .node ellipse,#mermaid-svg-mklzIszzhigOkFz6 .node polygon,#mermaid-svg-mklzIszzhigOkFz6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mklzIszzhigOkFz6 .rough-node .label text,#mermaid-svg-mklzIszzhigOkFz6 .node .label text,#mermaid-svg-mklzIszzhigOkFz6 .image-shape .label,#mermaid-svg-mklzIszzhigOkFz6 .icon-shape .label{text-anchor:middle;}#mermaid-svg-mklzIszzhigOkFz6 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-mklzIszzhigOkFz6 .rough-node .label,#mermaid-svg-mklzIszzhigOkFz6 .node .label,#mermaid-svg-mklzIszzhigOkFz6 .image-shape .label,#mermaid-svg-mklzIszzhigOkFz6 .icon-shape .label{text-align:center;}#mermaid-svg-mklzIszzhigOkFz6 .node.clickable{cursor:pointer;}#mermaid-svg-mklzIszzhigOkFz6 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-mklzIszzhigOkFz6 .arrowheadPath{fill:#333333;}#mermaid-svg-mklzIszzhigOkFz6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mklzIszzhigOkFz6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mklzIszzhigOkFz6 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mklzIszzhigOkFz6 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-mklzIszzhigOkFz6 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mklzIszzhigOkFz6 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-mklzIszzhigOkFz6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mklzIszzhigOkFz6 .cluster text{fill:#333;}#mermaid-svg-mklzIszzhigOkFz6 .cluster span{color:#333;}#mermaid-svg-mklzIszzhigOkFz6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mklzIszzhigOkFz6 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-mklzIszzhigOkFz6 rect.text{fill:none;stroke-width:0;}#mermaid-svg-mklzIszzhigOkFz6 .icon-shape,#mermaid-svg-mklzIszzhigOkFz6 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mklzIszzhigOkFz6 .icon-shape p,#mermaid-svg-mklzIszzhigOkFz6 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-mklzIszzhigOkFz6 .icon-shape .label rect,#mermaid-svg-mklzIszzhigOkFz6 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mklzIszzhigOkFz6 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-mklzIszzhigOkFz6 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-mklzIszzhigOkFz6 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 过拟合
良好
加载数据
数据划分
构建模型
训练
验证
调整参数
测试
保存模型
6.2 训练代码
python
def train_model(model, X_train, y_train, X_val, y_val, epochs=50, batch_size=32):
early_stopping = tf.keras.callbacks.EarlyStopping(
monitor='val_loss', patience=10, restore_best_weights=True
)
history = model.fit(
X_train, y_train,
epochs=epochs,
batch_size=batch_size,
validation_data=(X_val, y_val),
callbacks=[early_stopping]
)
return history
6.3 评估指标
python
def evaluate_model(model, X_test, y_test):
loss, accuracy = model.evaluate(X_test, y_test)
y_pred = model.predict(X_test)
y_pred_classes = np.argmax(y_pred, axis=1)
from sklearn.metrics import classification_report
report = classification_report(y_test, y_pred_classes)
return loss, accuracy, report
七、迁移学习
7.1 迁移学习原理
#mermaid-svg-YOwEmB5B8aI0MWIs{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YOwEmB5B8aI0MWIs .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YOwEmB5B8aI0MWIs .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YOwEmB5B8aI0MWIs .error-icon{fill:#552222;}#mermaid-svg-YOwEmB5B8aI0MWIs .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YOwEmB5B8aI0MWIs .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YOwEmB5B8aI0MWIs .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YOwEmB5B8aI0MWIs .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YOwEmB5B8aI0MWIs .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YOwEmB5B8aI0MWIs .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YOwEmB5B8aI0MWIs .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YOwEmB5B8aI0MWIs .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YOwEmB5B8aI0MWIs .marker.cross{stroke:#333333;}#mermaid-svg-YOwEmB5B8aI0MWIs svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YOwEmB5B8aI0MWIs p{margin:0;}#mermaid-svg-YOwEmB5B8aI0MWIs .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-YOwEmB5B8aI0MWIs .cluster-label text{fill:#333;}#mermaid-svg-YOwEmB5B8aI0MWIs .cluster-label span{color:#333;}#mermaid-svg-YOwEmB5B8aI0MWIs .cluster-label span p{background-color:transparent;}#mermaid-svg-YOwEmB5B8aI0MWIs .label text,#mermaid-svg-YOwEmB5B8aI0MWIs span{fill:#333;color:#333;}#mermaid-svg-YOwEmB5B8aI0MWIs .node rect,#mermaid-svg-YOwEmB5B8aI0MWIs .node circle,#mermaid-svg-YOwEmB5B8aI0MWIs .node ellipse,#mermaid-svg-YOwEmB5B8aI0MWIs .node polygon,#mermaid-svg-YOwEmB5B8aI0MWIs .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YOwEmB5B8aI0MWIs .rough-node .label text,#mermaid-svg-YOwEmB5B8aI0MWIs .node .label text,#mermaid-svg-YOwEmB5B8aI0MWIs .image-shape .label,#mermaid-svg-YOwEmB5B8aI0MWIs .icon-shape .label{text-anchor:middle;}#mermaid-svg-YOwEmB5B8aI0MWIs .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-YOwEmB5B8aI0MWIs .rough-node .label,#mermaid-svg-YOwEmB5B8aI0MWIs .node .label,#mermaid-svg-YOwEmB5B8aI0MWIs .image-shape .label,#mermaid-svg-YOwEmB5B8aI0MWIs .icon-shape .label{text-align:center;}#mermaid-svg-YOwEmB5B8aI0MWIs .node.clickable{cursor:pointer;}#mermaid-svg-YOwEmB5B8aI0MWIs .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-YOwEmB5B8aI0MWIs .arrowheadPath{fill:#333333;}#mermaid-svg-YOwEmB5B8aI0MWIs .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YOwEmB5B8aI0MWIs .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YOwEmB5B8aI0MWIs .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YOwEmB5B8aI0MWIs .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YOwEmB5B8aI0MWIs .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YOwEmB5B8aI0MWIs .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-YOwEmB5B8aI0MWIs .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YOwEmB5B8aI0MWIs .cluster text{fill:#333;}#mermaid-svg-YOwEmB5B8aI0MWIs .cluster span{color:#333;}#mermaid-svg-YOwEmB5B8aI0MWIs div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-YOwEmB5B8aI0MWIs .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YOwEmB5B8aI0MWIs rect.text{fill:none;stroke-width:0;}#mermaid-svg-YOwEmB5B8aI0MWIs .icon-shape,#mermaid-svg-YOwEmB5B8aI0MWIs .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YOwEmB5B8aI0MWIs .icon-shape p,#mermaid-svg-YOwEmB5B8aI0MWIs .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-YOwEmB5B8aI0MWIs .icon-shape .label rect,#mermaid-svg-YOwEmB5B8aI0MWIs .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YOwEmB5B8aI0MWIs .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-YOwEmB5B8aI0MWIs .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-YOwEmB5B8aI0MWIs :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 源数据集
预训练模型
冻结特征提取层
目标数据集
微调分类层
适应新任务
7.2 迁移学习实现
python
def transfer_learning(base_model, X_train, y_train, num_classes=4):
base_model.trainable = False
inputs = layers.Input(shape=X_train.shape[1:])
x = base_model(inputs, training=False)
x = layers.Flatten()(x)
x = layers.Dense(128, activation='relu')(x)
outputs = layers.Dense(num_classes, activation='softmax')(x)
model = models.Model(inputs, outputs)
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
八、实战案例:运动想象分类
8.1 数据集描述
#mermaid-svg-0BcR2JIcKqDM3sLi{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0BcR2JIcKqDM3sLi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0BcR2JIcKqDM3sLi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0BcR2JIcKqDM3sLi .error-icon{fill:#552222;}#mermaid-svg-0BcR2JIcKqDM3sLi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0BcR2JIcKqDM3sLi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0BcR2JIcKqDM3sLi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0BcR2JIcKqDM3sLi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0BcR2JIcKqDM3sLi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0BcR2JIcKqDM3sLi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0BcR2JIcKqDM3sLi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0BcR2JIcKqDM3sLi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0BcR2JIcKqDM3sLi .marker.cross{stroke:#333333;}#mermaid-svg-0BcR2JIcKqDM3sLi svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0BcR2JIcKqDM3sLi p{margin:0;}#mermaid-svg-0BcR2JIcKqDM3sLi .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0BcR2JIcKqDM3sLi .cluster-label text{fill:#333;}#mermaid-svg-0BcR2JIcKqDM3sLi .cluster-label span{color:#333;}#mermaid-svg-0BcR2JIcKqDM3sLi .cluster-label span p{background-color:transparent;}#mermaid-svg-0BcR2JIcKqDM3sLi .label text,#mermaid-svg-0BcR2JIcKqDM3sLi span{fill:#333;color:#333;}#mermaid-svg-0BcR2JIcKqDM3sLi .node rect,#mermaid-svg-0BcR2JIcKqDM3sLi .node circle,#mermaid-svg-0BcR2JIcKqDM3sLi .node ellipse,#mermaid-svg-0BcR2JIcKqDM3sLi .node polygon,#mermaid-svg-0BcR2JIcKqDM3sLi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0BcR2JIcKqDM3sLi .rough-node .label text,#mermaid-svg-0BcR2JIcKqDM3sLi .node .label text,#mermaid-svg-0BcR2JIcKqDM3sLi .image-shape .label,#mermaid-svg-0BcR2JIcKqDM3sLi .icon-shape .label{text-anchor:middle;}#mermaid-svg-0BcR2JIcKqDM3sLi .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0BcR2JIcKqDM3sLi .rough-node .label,#mermaid-svg-0BcR2JIcKqDM3sLi .node .label,#mermaid-svg-0BcR2JIcKqDM3sLi .image-shape .label,#mermaid-svg-0BcR2JIcKqDM3sLi .icon-shape .label{text-align:center;}#mermaid-svg-0BcR2JIcKqDM3sLi .node.clickable{cursor:pointer;}#mermaid-svg-0BcR2JIcKqDM3sLi .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0BcR2JIcKqDM3sLi .arrowheadPath{fill:#333333;}#mermaid-svg-0BcR2JIcKqDM3sLi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0BcR2JIcKqDM3sLi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0BcR2JIcKqDM3sLi .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0BcR2JIcKqDM3sLi .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0BcR2JIcKqDM3sLi .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0BcR2JIcKqDM3sLi .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0BcR2JIcKqDM3sLi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0BcR2JIcKqDM3sLi .cluster text{fill:#333;}#mermaid-svg-0BcR2JIcKqDM3sLi .cluster span{color:#333;}#mermaid-svg-0BcR2JIcKqDM3sLi div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0BcR2JIcKqDM3sLi .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0BcR2JIcKqDM3sLi rect.text{fill:none;stroke-width:0;}#mermaid-svg-0BcR2JIcKqDM3sLi .icon-shape,#mermaid-svg-0BcR2JIcKqDM3sLi .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0BcR2JIcKqDM3sLi .icon-shape p,#mermaid-svg-0BcR2JIcKqDM3sLi .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0BcR2JIcKqDM3sLi .icon-shape .label rect,#mermaid-svg-0BcR2JIcKqDM3sLi .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0BcR2JIcKqDM3sLi .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0BcR2JIcKqDM3sLi .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0BcR2JIcKqDM3sLi :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} BCI Competition IV Dataset 2a
9个受试者
4类运动想象
250Hz采样率
左手想象
右手想象
脚想象
舌头想象
8.2 完整实现
python
import numpy as np
import tensorflow as tf
from sklearn.model_selection import train_test_split
class MI_Classifier:
def __init__(self):
self.model = None
self.augmenter = EEGDataAugmenter()
def load_data(self, path):
data = np.load(path)
X = data['X']
y = data['y']
return X, y
def preprocess(self, X):
X = (X - np.mean(X, axis=0)) / np.std(X, axis=0)
return X
def train(self, X, y):
X = self.preprocess(X)
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2)
self.model = EEG_CNN_LSTM_Model(input_shape=X_train.shape[1:], num_classes=4).build_model()
history = self.model.fit(
X_train, y_train,
epochs=50,
batch_size=32,
validation_data=(X_val, y_val),
callbacks=[tf.keras.callbacks.EarlyStopping(patience=10)]
)
return history
def predict(self, X):
X = self.preprocess(X)
return self.model.predict(X)
if __name__ == '__main__':
classifier = MI_Classifier()
X, y = classifier.load_data('mi_dataset.npz')
classifier.train(X, y)
九、模型部署与优化
9.1 模型压缩
python
def compress_model(model, save_path='compressed_model.h5'):
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()
with open(save_path, 'wb') as f:
f.write(tflite_model)
return tflite_model
9.2 实时推理
python
class RealTimeEEGClassifier:
def __init__(self, model_path, window_size=250):
self.interpreter = tf.lite.Interpreter(model_path=model_path)
self.interpreter.allocate_tensors()
self.window_size = window_size
self.data_buffer = []
self.input_details = self.interpreter.get_input_details()
self.output_details = self.interpreter.get_output_details()
def add_data(self, sample):
self.data_buffer.append(sample)
if len(self.data_buffer) > self.window_size:
self.data_buffer = self.data_buffer[-self.window_size:]
def predict(self):
if len(self.data_buffer) < self.window_size:
return None
input_data = np.array([self.data_buffer], dtype=np.float32)
self.interpreter.set_tensor(self.input_details[0]['index'], input_data)
self.interpreter.invoke()
output_data = self.interpreter.get_tensor(self.output_details[0]['index'])
return np.argmax(output_data)
十、总结
深度学习为脑电信号处理带来了前所未有的机遇:
- CNN擅长提取空间特征,适合处理电极间的空间模式
- RNN/LSTM擅长捕捉时间序列依赖,适合处理EEG的动态变化
- 混合模型结合了两者的优势,在复杂任务上表现出色
- 迁移学习解决了数据量不足的问题
未来研究方向:
- 自监督学习在EEG中的应用
- 小样本学习方法
- 可解释性深度学习
- 边缘计算部署
参考资料:
- Schirrmeister, R. T., et al. (2017). Deep learning with convolutional neural networks for EEG decoding and visualization.
- Wang, F., et al. (2020). EEG-based emotion recognition using deep learning: A review.
