尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

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

DEAP情绪识别实战:从EEG信号处理到机器学习模型构建全流程

DEAP情绪识别实战:从EEG信号处理到机器学习模型构建全流程 简介本资源是面向情感计算与脑机接口方向研究者及AI初学者的DEAP情绪识别完整实践包聚焦基于多通道EEG信号的情绪分类任务解决生理数据预处理、特征工程与模型训练等核心难点。压缩包共11个文件4个.dat原始数据、3个.py核心脚本、2个.csv标签与特征表、1个LICENSE和1个README.md总大小3.85MB结构精炼py脚本涵盖load_deap.py数据加载、creating_vector.py特征向量化、svm_clas.py模型训练全流程csv文件提供预提取标签与原始特征便于快速验证dat文件含28名受试者观看40段视频后的EEG与生理信号。目前已有2998人学习下载配套代码已实现从原始DEAP数据读取、8维情绪评分映射到二/三分类任务的端到端流程并内置SVM基线模型与可视化支持显著降低EEG情绪识别入门门槛适合课程设计、科研复现与算法优化参考。1. 项目概述从零开始构建一个DEAP情绪识别系统最近在做一个关于生理信号与情绪关联的研究项目需要用到DEAP数据集。说实话刚开始接触这个领域时我完全被各种术语和复杂的流程搞懵了。什么是EEG什么是生理信号预处理DEAP数据集到底怎么用网上能找到的教程要么过于学术化要么就是零散的代码片段缺少一个从数据获取到模型跑通的完整指引。经过几周的摸索和踩坑我终于把整个流程跑通了从数据集下载、环境搭建、数据预处理到模型训练和评估形成了一套可复现的完整方案。这篇文章我就来分享一下我的实战经验希望能帮你绕过我踩过的那些坑快速上手DEAP情绪识别。简单来说DEAPDatabase for Emotion Analysis using Physiological Signals是一个在情感计算领域非常经典的多模态数据集。它记录了32位参与者在观看音乐视频时的脑电图EEG、外周生理信号如皮肤电导、心率、肌电等以及参与者自我报告的情绪维度效价、唤醒度、支配度等。我们的目标就是利用这些生理信号数据去构建一个模型预测观看者当时的情绪状态。这听起来很酷对吧但实操起来每一步都有门道。无论你是刚入门情感计算的研究生还是对生理信号分析感兴趣的开发者这篇手把手的指南都将为你提供一个清晰的路线图。2. DEAP数据集详解与高效下载策略在动手写代码之前我们必须先彻底理解我们要处理的数据。DEAP数据集的结构和内容直接决定了我们后续所有处理步骤的设计。2.1 DEAP数据集核心内容解析DEAP数据集并非一个简单的CSV文件它采用了Python的pickle格式存储这是一种二进制序列化格式能高效地保存复杂的Python对象如字典、数组。数据集主要包含两个文件data_preprocessed_python文件夹下的s01.dat到s32.dat对应32名被试以及metadata信息。每个.dat文件加载后本质上是一个字典包含以下关键键值data: 这是核心的生理信号数据。它是一个形状为(40, 40, 8064)的3D数组。第一个维度40代表实验试次Trials。每个被试观看了40段一分钟的音乐视频片段。第二个维度40代表数据通道Channels。这40个通道包括前32个通道EEG脑电信号根据国际10-20系统放置的电极采集。后8个通道外周生理信号包括皮肤电导GSR、血容量搏动BVP、呼吸幅度、皮肤温度、肌电EMG等。第三个维度8064代表每个通道的采样点数。采样频率为128Hz视频片段时长63秒去除3秒基线因此128 Hz * 63 s 8064个数据点。labels: 这是情绪标签。它是一个形状为(40, 4)的2D数组。第一个维度40对应40个试次。第二个维度4代表四个情绪维度评分效价Valence、唤醒度Arousal、支配度Dominance、喜爱度Liking。每个评分范围是1到9的整数由被试在观看视频后自我报告。理解这个数据结构至关重要。很多新手在加载数据后直接扔进模型结果维度对不上或者意义错误就是因为没搞清每个数字代表什么。2.2 避开陷阱DEAP数据集的多种下载方式官方下载渠道是 DEAP项目主页 。你需要填写一个简单的使用协议表格提交后官方会通过邮件将下载链接发给你。这是最权威的途径。然而在实际操作中你可能会遇到两个问题一是邮件可能被归入垃圾箱需要仔细查找二是官方提供的下载链接有时速度较慢对于大文件约4GB不太友好。因此社区中常有一些替代方案。但这里我必须强调一个非常重要的合规性问题数据版权与许可。DEAP数据集遵循特定的学术使用协议。在寻找其他下载源时务必确认其合法性。一些知名的学术数据镜像站或开源代码库附带的数据链接可能是经过授权的。绝对不要从来源不明、没有明确授权声明的网盘或论坛下载这不仅是版权问题更可能下载到被篡改或不完整的数据导致你的研究前功尽弃。一个更高效且合规的实践是如果你在Kaggle或某些GitHub项目例如搜索“DEAP emotion recognition pytorch”中找到了相关的代码通常作者会在README中提供数据准备脚本或指引你到合规的源。使用这些社区验证过的途径往往比盲目搜索更可靠。下载完成后你会得到一个压缩包解压后目录结构通常如下deap_dataset/ ├── data_preprocessed_python/ │ ├── s01.dat │ ├── s02.dat │ └── ... ├── data_preprocessed_matlab/ (可能包含Matlab格式数据) └── README.txt (重要包含数据格式说明)第一步请务必阅读README.txt文件。3. 开发环境搭建与核心依赖库选择工欲善其事必先利其器。情绪识别涉及信号处理和机器学习一个稳定、高效的开发环境是成功的基石。3.1 Python环境与包管理方案强烈建议使用conda或venv创建独立的Python虚拟环境。这能避免不同项目间的包版本冲突。我个人的选择是Miniconda因为它轻量且管理方便。# 创建名为deap的Python3.9环境 conda create -n deap python3.9 conda activate deap接下来是安装核心依赖库。以下是我经过多次实践验证的稳定版本组合可以直接复制使用pip install numpy1.23.5 pandas1.5.3 scipy1.10.1 pip install scikit-learn1.2.2 matplotlib3.7.1 seaborn0.12.2 pip install mne1.4.2 # 专业脑电处理库强烈推荐 pip install torch2.0.1 torchvision0.15.2 # 深度学习框架 pip install jupyterlab # 用于交互式分析和调试注意mne库对于EEG数据处理来说是个神器它提供了专业的数据结构如Raw,Epochs、滤波、重参考、伪迹检测如眼电等标准流程函数。即使你最终用其他方式处理了解MNE的流程也对理解EEG处理范式大有裨益。3.2 源码结构规划如何组织你的项目一个清晰的项目结构能极大提升开发效率和代码可维护性。不要把所有代码都堆在一个Jupyter Notebook或一个Python脚本里。我建议的目录结构如下emotion_recognition_deap/ ├── data/ │ ├── raw/ # 存放下载的原始.dat文件 │ └── processed/ # 存放预处理后的数据如.npy, .h5格式 ├── src/ │ ├── data_loader.py # 数据加载与解析模块 │ ├── preprocess.py # 信号预处理模块滤波、分段等 │ ├── feature_extraction.py # 特征提取模块时域、频域、非线性 │ ├── models.py # 模型定义CNN, LSTM, SVM等 │ ├── train.py # 训练循环脚本 │ └── utils.py # 工具函数可视化、评估指标 ├── notebooks/ │ └── exploration.ipynb # 用于数据探索和实验的Jupyter笔记本 ├── configs/ │ └── params.yaml # 超参数配置文件可选但推荐 ├── requirements.txt # 项目依赖列表 ├── README.md # 项目说明 └── main.py # 主程序入口这样的结构将数据、代码、实验记录分离符合软件工程的最佳实践。src下的每个模块功能单一便于测试和复用。4. 数据加载与预处理实战从原始信号到干净特征这是整个流程中最关键、最繁琐的一步。原始生理信号充满了噪声直接用于建模效果会很差。4.1 安全加载.dat文件并理解数据结构首先我们编写data_loader.py中的核心加载函数。由于.dat文件是Python 2格式的pickle在Python 3中加载需要指定编码。import pickle import numpy as np def load_deap_data(filepath): 加载单个被试的DEAP .dat文件。 参数: filepath: .dat文件的路径 返回: data: 生理信号数据形状 (40, 40, 8064) labels: 情绪标签形状 (40, 4) # 以二进制读取模式打开文件 with open(filepath, rb) as f: # 使用latin1编码来兼容Python 2 pickle的数据 data_dict pickle.load(f, encodinglatin1) # 根据DEAP数据集的格式字典里通常有data和labels两个键 # 但有些版本的数据直接就是(data, labels)的元组需要判断 if isinstance(data_dict, dict): data data_dict[data] labels data_dict[labels] else: # 如果是元组格式 data, labels data_dict return data, labels # 示例加载第一个被试的数据 subj_data, subj_labels load_deap_data(./data/raw/s01.dat) print(f数据形状: {subj_data.shape}) # 应输出 (40, 40, 8064) print(f标签形状: {subj_labels.shape}) # 应输出 (40, 4)加载成功后我们可以简单查看一下标签的分布例如绘制效价Valence和唤醒度Arousal的二维散点图直观感受一下数据在情感空间中的分布。4.2 信号预处理全流程拆解原始信号包含各种噪声如电源工频干扰50/60Hz、眼电EOG、肌电EMG伪迹、基线漂移等。预处理的目标就是尽可能去除这些噪声保留与情绪相关的信号成分。1. 重参考RereferencingEEG信号是相对的需要一个参考点。DEAP数据使用的是平均参考所有电极的平均值作为参考。但有时为了特定分析如减少远场噪声会转换为双耳参考或其他。使用MNE库可以轻松完成import mne def preprocess_eeg(data_eeg, sfreq128, ch_namesNone): 使用MNE预处理EEG数据单次试验。 参数: data_eeg: 单次试验的EEG数据形状 (32, 8064) sfreq: 采样频率 ch_names: 电极名称列表 返回: filtered_data: 滤波后的数据 if ch_names is None: # 标准10-20系统32导名称需与DEAP电极顺序对应 ch_names [Fp1,Fp2,F7,F3,Fz,F4,F8,FC5,FC1,FC2,FC6, T7,C3,Cz,C4,T8,CP5,CP1,CP2,CP6,P7,P3, Pz,P4,P8,PO9,O1,Oz,O2,PO10,AF7,AF8] # 创建MNE的Info对象 info mne.create_info(ch_namesch_names, sfreqsfreq, ch_typeseeg) # 创建RawArray对象 raw mne.io.RawArray(data_eeg, info) # 1. 滤波去除高频噪声和低频漂移 # 常用带通滤波4-45 Hz (保留Delta, Theta, Alpha, Beta节律) raw.filter(4., 45., fir_designfirwin) # 可选陷波滤波去除工频干扰 (如50Hz) # raw.notch_filter(np.arange(50, 251, 50), fir_designfirwin) # 2. 重参考这里演示转换为平均参考 raw.set_eeg_reference(ref_channelsaverage, projectionTrue) # 获取处理后的数据 filtered_data raw.get_data() return filtered_data2. 分段Epoching与基线校正DEAP数据已经是对应每个视频片段的63秒数据去除了3秒基线。但在一些分析中我们可能想切分成更短的时间窗例如3秒一个片段来增加样本量或进行时序分析。同时基线校正减去每个通道在刺激前一段时间的均值对于去除个体差异和缓慢漂移很重要。DEAP在发布前已做过基线校正减去了前3秒基线。3. 伪迹检测与剔除这是EEG分析中的难点。简单的方法可以通过振幅阈值如超过±100μV来标记坏段。更复杂的方法可以用独立成分分析ICA来识别并去除眼电、心电等伪迹成分。对于刚起步的项目可以先用振幅阈值法进行粗筛。def detect_bad_epochs(epochs_data, threshold_uv100): 简单的振幅阈值法检测坏段。 参数: epochs_data: 分段后的数据形状 (n_epochs, n_channels, n_times) threshold_uv: 振幅阈值微伏 返回: bad_epochs_idx: 坏段的索引列表 bad_epochs_idx [] for i, epoch in enumerate(epochs_data): # 计算每个epoch在所有通道和所有时间点上的最大绝对值 max_amp np.max(np.abs(epoch)) if max_amp threshold_uv: bad_epochs_idx.append(i) return bad_epochs_idx4. 外周生理信号预处理对于GSR、BVP等信号预处理步骤有所不同。例如GSR信号通常需要进行低通滤波以平滑并可能提取其导数皮肤电导反应。BVP信号则常用于计算心率变异性HRV需要检测R峰。这些都需要专门的算法。预处理流程需要根据你的研究问题和所选特征来定制没有一成不变的“标准流程”。我的经验是从一个相对简单的预处理流程开始如只做带通滤波和振幅阈值剔除先跑通基线模型然后再逐步加入更复杂的处理步骤如ICA来提升性能这样能有效定位问题。5. 特征工程如何从信号中提取情绪“指纹”特征工程是模式识别的灵魂。好的特征能极大简化模型的学习难度。对于生理信号特征主要从三个域提取时域、频域、非线性动力学域。5.1 时域与频域经典特征提取时域特征计算简单物理意义明确。均值、标准差信号的整体强度和波动情况。一阶差分统计量信号变化率的均值和标准差反映信号的活跃度。Hjorth参数活动性方差、移动性一阶导数的标准差与信号标准差的比值、复杂性类似移动性的高阶比常用于EEG分析。频域特征情绪与特定脑电节律如Alpha波、Beta波的功率变化密切相关。波段功率使用快速傅里叶变换FFT或带通滤波平方积分计算Delta (1-4Hz)、Theta (4-8Hz)、Alpha (8-13Hz)、Beta (13-30Hz)、Gamma (30-45Hz) 等波段的绝对功率或相对功率占全频段功率的比例。功率谱密度PSD计算信号的功率谱可以提取谱重心、谱熵等特征。下面是一个结合时域和频域特征提取的函数示例from scipy import signal, stats import numpy as np def extract_features(signal_segment, sfreq128): 从一个信号片段单通道中提取多种特征。 参数: signal_segment: 一维信号数组 sfreq: 采样频率 返回: feat_dict: 特征字典 feat_dict {} n_points len(signal_segment) # 时域特征 feat_dict[mean] np.mean(signal_segment) feat_dict[std] np.std(signal_segment) feat_dict[max] np.max(signal_segment) feat_dict[min] np.min(signal_segment) # 一阶差分 diff_signal np.diff(signal_segment) feat_dict[diff_mean] np.mean(diff_signal) feat_dict[diff_std] np.std(diff_signal) # Hjorth参数 feat_dict[activity] np.var(signal_segment) if feat_dict[activity] 0: feat_dict[mobility] np.std(diff_signal) / np.std(signal_segment) diff2 np.diff(diff_signal) feat_dict[complexity] (np.std(diff2) / np.std(diff_signal)) / feat_dict[mobility] else: feat_dict[mobility] 0 feat_dict[complexity] 0 # 频域特征 # 计算功率谱密度 freqs, psd signal.welch(signal_segment, fssfreq, npersegmin(256, n_points)) # 定义频带边界 bands {delta: (1, 4), theta: (4, 8), alpha: (8, 13), beta: (13, 30), gamma: (30, 45)} total_power np.trapz(psd, freqs) for band_name, (low, high) in bands.items(): # 找到频带内的索引 idx_band np.logical_and(freqs low, freqs high) if np.any(idx_band): band_power np.trapz(psd[idx_band], freqs[idx_band]) feat_dict[f{band_name}_abs_power] band_power feat_dict[f{band_name}_rel_power] band_power / total_power if total_power 0 else 0 else: feat_dict[f{band_name}_abs_power] 0 feat_dict[f{band_name}_rel_power] 0 return feat_dict5.2 非线性特征与高级表征学习对于更复杂的研究可以引入非线性动力学特征如熵近似熵、样本熵、排列熵来衡量信号的复杂度或规律性情绪变化往往伴随着脑电信号复杂度的改变。还有分形维数如Higuchi分形维数等。然而手动设计特征需要深厚的领域知识。近年来深度学习方法如卷积神经网络CNN、长短时记忆网络LSTM能够自动从原始信号或简单预处理后的信号中学习高层次的特征表示在很多任务上超越了手工特征。你可以将预处理后的信号如(40, 8064)的EEG片段直接输入到一个一维CNN中让网络自行学习时域和空域通道间的特征。我的建议是先从经典的手工特征传统机器学习模型如SVM、随机森林开始。这能帮你快速建立基线理解数据并且模型可解释性更强。当手工特征性能遇到瓶颈时再考虑引入深度学习模型。在feature_extraction.py中你可以实现多种特征提取器方便后续对比实验。6. 模型构建、训练与评估策略有了干净的特征我们就可以构建情绪识别模型了。这里面临两个关键决策1) 将情绪识别视为分类问题还是回归问题2) 使用什么模型6.1 问题定义与标签处理DEAP提供了四个维度的1-9分连续值。一种做法是将其视为回归问题直接预测具体的分数。另一种更常见的做法是进行二分类或三分类。例如将效价和唤醒度分别以5为分界点大于5为“高”小于等于5为“低”这样就得到了四个情感象限高唤醒高效价、高唤醒低效价等的分类任务。也可以将5分视为中性而剔除只保留两端的数据。def create_binary_labels(labels, dimension_idx0, threshold5): 将连续标签转换为二分类标签。 参数: labels: 原始标签数组 (n_trials, 4) dimension_idx: 0-效价1-唤醒度2-支配度3-喜爱度 threshold: 二值化阈值 返回: binary_labels: 二分类标签 (0或1) dimension_scores labels[:, dimension_idx] binary_labels (dimension_scores threshold).astype(int) # 可选剔除阈值附近的数据以提高分类难度和清晰度 # keep_idx np.abs(dimension_scores - threshold) 1 # binary_labels binary_labels[keep_idx] return binary_labels6.2 传统机器学习模型实战以SVM为例假设我们已经从所有通道、所有试次中提取了特征并组织成了一个特征矩阵X(形状n_samples, n_features) 和对应的标签y。from sklearn.model_selection import train_test_split, cross_val_score, GridSearchCV from sklearn.preprocessing import StandardScaler from sklearn.svm import SVC from sklearn.metrics import accuracy_score, classification_report, confusion_matrix def train_svm_model(X, y): 使用SVM训练一个情绪分类模型。 # 1. 数据标准化对SVM等基于距离的模型至关重要 scaler StandardScaler() X_scaled scaler.fit_transform(X) # 2. 划分训练集和测试集按被试划分更严谨这里简单按样本划分 X_train, X_test, y_train, y_test train_test_split( X_scaled, y, test_size0.2, random_state42, stratifyy ) # 3. 定义模型与超参数网格搜索 svm SVC(kernelrbf, random_state42, class_weightbalanced) # 处理类别不平衡 param_grid { C: [0.1, 1, 10, 100], gamma: [scale, auto, 0.001, 0.01, 0.1] } grid_search GridSearchCV(svm, param_grid, cv5, scoringaccuracy, n_jobs-1, verbose1) grid_search.fit(X_train, y_train) print(f最佳参数: {grid_search.best_params_}) print(f最佳交叉验证准确率: {grid_search.best_score_:.4f}) # 4. 在测试集上评估 best_model grid_search.best_estimator_ y_pred best_model.predict(X_test) test_accuracy accuracy_score(y_test, y_pred) print(f测试集准确率: {test_accuracy:.4f}) print(\n分类报告:) print(classification_report(y_test, y_pred)) # 5. 返回训练好的模型和标准化器用于后续预测 return best_model, scaler注意上述按样本随机划分的方式存在“数据泄露”的风险因为同一个被试的多个试次可能被分到了训练集和测试集导致模型过拟合到个体特异性而非普遍的情绪模式。更严谨的做法是按被试划分即一部分被试的数据全部用于训练另一部分被试的数据全部用于测试。这能更好地评估模型的泛化能力。6.3 深度学习模型初探一维CNN对于想尝试深度学习的同学这里提供一个使用PyTorch搭建一维CNN的简化示例。该模型将每个试次的多个通道的EEG信号视为多通道的一维时间序列。import torch import torch.nn as nn import torch.nn.functional as F class EEGCNN1D(nn.Module): def __init__(self, n_channels32, n_classes2): super(EEGCNN1D, self).__init__() # 假设输入形状: (batch_size, n_channels, time_points) self.conv1 nn.Conv1d(in_channelsn_channels, out_channels64, kernel_size3, padding1) self.bn1 nn.BatchNorm1d(64) self.pool1 nn.MaxPool1d(kernel_size2) self.conv2 nn.Conv1d(in_channels64, out_channels128, kernel_size3, padding1) self.bn2 nn.BatchNorm1d(128) self.pool2 nn.MaxPool1d(kernel_size2) self.conv3 nn.Conv1d(in_channels128, out_channels256, kernel_size3, padding1) self.bn3 nn.BatchNorm1d(256) self.pool3 nn.MaxPool1d(kernel_size2) # 需要根据输入时间长度计算全连接层的输入维度 # 这里假设 time_points 8064经过三次池化后为 8064 / 8 1008 self.fc1 nn.Linear(256 * 1008, 512) # 这个1008需要根据实际输入尺寸计算 self.dropout nn.Dropout(0.5) self.fc2 nn.Linear(512, n_classes) def forward(self, x): x self.pool1(F.relu(self.bn1(self.conv1(x)))) x self.pool2(F.relu(self.bn2(self.conv2(x)))) x self.pool3(F.relu(self.bn3(self.conv3(x)))) x x.view(x.size(0), -1) # 展平 x F.relu(self.fc1(x)) x self.dropout(x) x self.fc2(x) return x # 注意实际使用时需要根据预处理后的数据尺寸调整网络结构特别是全连接层的输入维度。深度学习模型需要更多的数据、更仔细的调参学习率、优化器、正则化和可能更长的训练时间。建议先在小规模数据上验证管道是否通畅。7. 项目整合、常见陷阱与性能优化思路将以上所有模块整合到一个可运行的管道中是最后的临门一脚。同时回顾整个流程有几个常见的陷阱需要特别注意。7.1 构建端到端训练管道在main.py或train.py中我们需要串联整个流程# 伪代码示意 def main_pipeline(): # 1. 配置参数 config load_config(configs/params.yaml) # 2. 加载所有被试数据 all_features [] all_labels [] for subj_file in list_subject_files(data/raw/): data, labels load_deap_data(subj_file) # 3. 预处理 (例如只取EEG通道滤波) eeg_data data[:, :32, :] # 取前32个EEG通道 processed_data [] for trial in eeg_data: processed_trial preprocess_eeg_single_trial(trial) # 你的预处理函数 processed_data.append(processed_trial) processed_data np.array(processed_data) # 4. 特征提取 (例如计算每个通道的波段功率) for trial in processed_data: trial_features extract_features_for_trial(trial) # 你的特征提取函数 all_features.append(trial_features) # 创建二分类标签例如高效价 vs 低效价 binary_labels create_binary_labels(labels, dimension_idx0) all_labels.extend(binary_labels) # 转换为numpy数组 X np.array(all_features) y np.array(all_labels) # 5. 处理类别不平衡可选 # 6. 划分数据集建议按被试划分 # 7. 训练模型SVM/CNN等 # 8. 评估并保存模型7.2 避坑指南与经验分享数据泄露这是新手最容易犯的错误。务必确保来自同一个被试的数据不会同时出现在训练集和测试集中。请使用“留一被试交叉验证”或按一定比例划分被试。类别不平衡情绪标签的分布可能不均衡例如高效价的样本可能多于低效价。在训练时使用class_weight参数如SVM或对损失函数进行加权如深度学习并采用精确率、召回率、F1分数等指标而非单纯准确率来评估模型。特征标准化必须在训练集上计算标准化参数均值和标准差然后将其应用于测试集。绝对不能在合并所有数据后再标准化这也会导致数据泄露。过拟合特别是当特征维度高而样本量相对较少时。务必使用正则化L1/L2、Dropout对于深度学习和交叉验证来监控模型在验证集上的表现。生理信号的个体差异性不同被试的生理信号基线水平和反应模式差异巨大。一种改进思路是进行被试归一化如Z-score标准化针对每个被试单独进行或者使用跨被试学习、域自适应等更高级的技术。7.3 性能提升与进阶方向如果你的基线模型表现不佳比如准确率只比随机猜测高一点不要气馁这很正常。可以从以下方向尝试优化特征层面尝试不同的特征组合引入通道间的功能连接特征如相干性、相位锁定值这些特征能反映大脑不同区域间的协同工作与情绪密切相关。模型层面从SVM切换到随机森林、XGBoost等集成方法或者尝试更复杂的深度学习架构如结合CNN提取空间特征和LSTM提取时序依赖的混合模型。数据层面尝试更多的数据增强技术如对EEG信号进行小幅度的加噪、缩放、时间扭曲以增加数据的多样性。任务层面考虑多任务学习同时预测效价和唤醒度或者将问题定义为维度回归而非分类。情绪识别是一个充满挑战但极具价值的领域。DEAP数据集是一个绝佳的起点。通过这个项目你不仅能学会处理多模态生理信号还能掌握从数据准备到模型部署的完整机器学习流程。最重要的是保持耐心多实验多分析错误案例理解模型为什么错这比盲目调参更有意义。本文还有配套的精品资源点击获取
返回列表