赞
踩
目录
1.1了解DEAP数据集的格式
1.2 熟悉深度深度神经网络DNN和卷积神经网络CNN
1.3 通过统计实验对获得的模型进行测试,以比较不同的模型
本部分首先将介绍本次实验采用的DEAP数据集,另外由于本次实验采用了两种不同的神经网络架构:具有完全连接层的深度神经网络(DNN)和卷积神经网络(CNN),只做了一些小的修改,本部分也将详细解释该模型的基本框架及这些模型中的训练技术。
本次实验采用的是DEAP数据集。DEAP是2014年发布的一个用于情绪分析的数据集。它是情感计算领域最大的公开数据集之一,还包含各种不同的生理和视频信号。
DEAP数据集由两部分组成:
(1)一个由120个一分钟音乐视频组成的数据库,每一个视频由14-16名志愿者根据效价、唤醒度和主导度进行评分。
(2)40个以上音乐视频的子集,每个视频具有32个参与者中每个参与者的相应EEG和生理信号。与第一部分一样,每个视频都是根据效价、唤醒和支配维度进行评分的。
由于完成时间有限,本次实验只使用了DEAP数据集的第二部分,其中包含EEG信号。
脑电信号是使用Biosemi ActiveTwo设备收集的,该设备记录了32个具有可配置采样率的脑电通道。
DEAP是在512Hz下收集的,但数据集的创建者也提供了EEG信号的预处理版本,下采样到128Hz,并应用了频率滤波器和其他有用的预处理步骤。
特别地,对于32个参与者中的每一个,存在以下预处理的信息:
•数据:一个40 x 40 x 8064的阵列,包含40个频道中每个频道和40个音乐视频中每个频道的8064个录音。每个视频每个频道有8064个录音,因为试验时间为63秒(3秒预审基线+60秒试验),采样率为128Hz(63 x 128=8064)。
•标签:一个40 x 4的数组,包含40个音乐视频中每个视频的效价、唤醒、支配和链接的注释。
下面展示的是准备DEAP数据集相关的部分代码。
DNN神经网络是一个具有3个隐藏层的深度神经网络。该体系结构的近似图形方案如图2所示,而每一层的确切细节如下图所示。
上图所描绘的神经元的数量仅用于表示,每层下方都报告了神经元的真实数量。表1展示的是深度神经网络架构,表2中报告了对于DEAP数据集用于训练的超参数、优化器和损失函数。
表1:深度神经网络架构
Layer type | Layer params | Output shape |
Flatten | - | 3168 |
Dropout | p=0.25 | 3168 |
Dense | in=3168,out=5000 | 5000 |
Dropout | p=0.50 | 5000 |
Dense | in=5000,out=500 | 500 |
Dropout | p=0.50 | 500 |
Dense | in=500,out=100 | 1000 |
Dropout | p=0.50 | 1000 |
Dense | in=1000,out=1 | 1 |
Number of parameters=18'847'501 |
表2:DEAP数据集用于训练的超参数、优化器和损失函数等指标(DNN)
metric | DEAP |
Batch size | 310 |
Epochs | 250 |
Loss function | BCE |
Optimizer | RMSProp |
Learning rate | 0.0001 |
Momentum | 0 |
上述设计的是一个简单的深度神经网络(DNN)模型类,继承自 PyTorch 的 Module 类。该模型由几个线性层(全连接层)和一些激活函数、Dropout 层组成。
模型的主要组件是四个线性层(self.linear1, self.linear2, self.linear3, self.linear4),分别将输入特征映射到不同的维度。其中,self.linear4 是二元分类任务的最后一层,输出一个值,用于区分高价值和低价值情绪状态。
模型还包括三个 Dropout 层(self.dropout1, self.dropout2),用于随机丢弃部分神经元,以减少过拟合风险。激活函数 ReLU(self.relu)被应用于线性层之后,以增加模型的非线性能力。最后,使用 Flatten 层(self.flatten)将输入张量展平,并通过 forward 方法来定义前向传播过程。在前向传播中,输入首先经过 Flatten 层,然后通过每个线性层、激活函数和 Dropout 层的序列。
最终,模型返回最后一个线性层的输出张量,用于进行二元分类任务的预测。
卷积神经网络 (CNN) 是一种用于处理图像和声音等网格结构数据的前馈神经网络。它利用卷积运算提取输入数据的特征,使用池化操作来压缩特征图的尺寸。CNN 可以通过改变卷积核的参数来调整特征的维度。在卷积层后通常会应用非线性激活函数,如 ReLU,并可使用批量归一化、Dropout 等技术来提高模型性能。最后一层通常是全连接层,将特征转换为向量表示以进行分类或回归等任务。下图是CNN的架构:
CNN模型利用卷积层,将数据视为形状为32 x 99的二维输入。
简而言之,该模型由两个卷积层组成,然后是最大池化层,最后是两个完全连接的层。卷积层将输入视为2D图像,通过卷积操作应用3x3滤波器。这种类型的层主要用于涉及图像的任务中。最大池化层用于减少数据的空间维度,在图像上滑动一个2x2的窗口,该窗口被减少到一个值:具有最高激活的神经元的值。最大池化减少了图像的空间维度,从而减少了最终完全连接层中所需的参数数量,并有助于网络避免过度拟合。
与DNN模型一样,CNN权重使用Xavier的正常技术进行初始化,偏差设置为0。表3中中报告了对于DEAP数据集用于训练的超参数、优化器和损失函数等。
表3:DEAP数据集用于训练的超参数、优化器和损失函数等指标(CNN)
metric | DEAP |
Batch size | 50 |
Epochs | 250 |
Loss function | BCE |
Optimizer | SGD |
Learning rate | 0.0001 |
Momentum | 0.9 |
在代码中我定义了一个名为CNN的类,继承自Module。该类实现了一个简单的卷积神经网络模型。在初始化方法中,首先定义了4个卷积层。其中,self.conv1是一个输入通道数为1,输出通道数为20的卷积层,卷积核大小为3x3,填充为1。self.conv2是一个输入通道数为20,输出通道数为40的卷积层,同样使用3x3的卷积核和1的填充。
接下来定义了一个最大池化层nn.MaxPool2d,使用2x2的窗口进行池化操作。
然后定义了两个全连接层self.linear1和self.linear2。self.linear1将输入的特征展平成一维向量,并将其映射到128维向量空间。self.linear2将128维向量映射为1维,用于二分类任务。在网络的前向传播方法forward中,首先对输入数据添加一个维度作为通道维度。然后通过self.dropout0对输入进行随机失活操作。
接下来通过卷积层self.conv1进行卷积操作,并通过ReLU激活函数进行非线性变换。随后再次应用self.dropout1进行随机失活,然后通过self.conv2进行卷积操作、ReLU激活函数和最大池化操作。之后通过self.flatten将特征图展平成一维向量,并通过self.dropout2进行随机失活。然后通过全连接层self.linear1进行线性变换和ReLU激活函数,并再次应用self.dropout3进行随机失活。
最后通过self.linear2进行线性变换,得到模型的输出。该模型总体上适用于二分类任务。
在进行模型训练和测试前,对DEAP数据集进行处理。由于本次实验只使用了DEAP数据集中包含EEG信号的第二部分,数据维度已经降低。40个通道已被削减至32个,仅保留EEG信号,每个通道的8064个读数已减少至99个值。
预处理的具体过程如下:首先,通过循环遍历每位参与者(participant),并加载其数据。对每个参与者的数据进行以下操作:
①从原始数据中提取出32个EEG通道的数据,去除非EEG通道。
如图所示,已去除非EEG通道
②对通道数据进行全局标准化,即减去全局均值并除以全局标准差。
③使用reduce_dim函数对数据进行降维处理,将每个通道的数据从n_recordings维降至99维。
数据降维主要通过函数reduce_dim实现。下面是降维操作主要步骤:
·首先,根据输入数据的形状,确定分批处理的大小和总样本数。
·对每个通道的数据进行以下操作: a. 将8064个记录划分为10个批次(每个批次807个记录,第10个批次为801个记录)。 b. 针对每个批次,计算9个统计值,并将它们存储在处理后的数据中。这些统计值包括:平均值、中位数、最大值、最小值、标准差、方差、范围、偏度和峰度。 c. 对整个通道的数据也计算这9个统计值,并将它们存储在处理后的数据中的最后9个位置。
·最后,确保处理后的数据形状为(32, 99),并返回处理后的数据。
④对降维后的数据进行独立通道标准化,即分别将每个通道的数据减去该通道的均值并除以该通道的标准差。
⑤对所有通道的数据进行全局标准化,即减去总体均值并除以总体标准差。
即使用以下公式,在示例的基础上对这些汇总值进行标准化,得到0的平均值和1的标准偏差:
⑥提取情感标签(valence和arousal)。
关于情感标签:在情感分析中,valence和arousal通常用来描述情感状态的两个主要维度。Valence表示情感的好坏程度,范围通常从负面到正面,例如,沮丧、愤怒、快乐、满足等。Arousal表示情感的强度或活跃程度,范围通常从低到高,例如,冷静、放松、兴奋、惊恐等。
⑦将处理后的数据和标签保存为.dat文件。
⑧输出保存成功的信息。
经过数据预处理后,DEAP数据集的大小为1280,数据集形状为32*99。数据包含32个通道,每个通道有99个记录,而标签包含2个值(效价和唤醒)。
执行以上数据预处理处理步骤的文件在项目中以prepare deap.py的名称提供。
(1)配置文件读取
with open('deap_dnn_arousal.yml') as yaml_file:
config = yaml.load(yaml_file, Loader=yaml.FullLoader)
使用 PyYAML 库读取并解析名为 'deap_dnn_arousal.yml' 的配置文件,将配置信息存储在 config 字典中供后续使用。
配置文件常用于训练一个基于CNN模型的情感分类器来对DEAP数据集中的情感进行分类。其中包括使用dropout技术防止过拟合,设置随机种子,将数据集分为训练集和测试集,设定批量大小、学习率、动量、训练轮数和导出模型的路径等。此处给出配置文件 'deap_dnn_arousal.yml' 内容
从该配置文件中还可以看出此部分数据集中,训练集与测试集比例为(1180:100)
(2)超参数设置
从配置文件中获取训练相关的超参数,包括训练轮数、批量大小、学习率和动量。
(3)模型类型选择
model_type = config['MODEL']['model']
从配置文件中获取模型的类型,可以是 'dnn' 或 'cnn'。
(4)训练目标选择
classification_of = config['TRAIN']['classification_of']
获取训练目标的类型,例如 'arousal' 或 'valence'。
(5)数据集加载与划分
根据DEAP数据集的路径,使用自定义的 DEAP类加载数据集。
获取随机种子和训练集、测试集的划分比例。然后使用 PyTorch 的 random_split 函数将数据集划分为训练集和测试集,并设置相应的随机种子。
(6)模型初始化
根据模型类型选择并初始化相应的模型和优化器。如果是 'dnn',则使用自定义的 DNN 类创建模型,并使用 RMSprop 优化器;如果是 'cnn',则使用自定义的 CNN 类创建模型,并使用 SGD 优化器。
(7)模型权重初始化
此部分定义了一个函数 init_weights,用于初始化模型的权重。它会遍历模型的所有线性层(Linear)并使用 Xavier 正态分布初始化权重,同时将偏置项(bias)设置为零。
这个函数用于训练模型。它接受一个模型、训练集数据加载器、损失函数、优化器等参数,并可选地进行准确率检查和测试集评估。
在函数内部,首先将模型设置为训练模式,并初始化最佳测试集准确率为 0.0。然后,创建空列表以记录每个 epoch 的平均损失值和准确率。
接下来,开始循环训练。对于每个 epoch,初始化当前 epoch 的损失列表。
然后,对于训练集中的每个批次,使用模型进行预测,并根据分类目标选择正确的标签列。计算损失并将其添加到当前 epoch 的损失列表中。
清零优化器的梯度,进行反向传播和参数更新。在训练过程中,还会打印当前 epoch 和批次的信息。每个 epoch 结束后,计算平均损失值,并将其添加到列表中。如果设置了准确率检查,且达到检查的间隔,则进行训练集和测试集的准确率检查。
如果测试集的准确率超过了之前的最佳准确率,则保存当前模型。
循环结束后,输出换行符以美化输出,并根据是否存在最佳准确率来输出最佳的测试集准确率。如果有最佳准确率,则返回该准确率。
2.关于准确率的计算
上部分的准确率计算依据的是函数check_accuracy
该函数用于计算模型在给定数据集上的准确率。它接受一个模型、数据加载器和一些可选参数(如分类目标、样本数量限制),并返回准确率。
在函数内部,首先初始化正确预测数目为 0,并根据需要设置样本数量限制。然后进入无梯度计算的上下文(torch.no_grad()),将模型设置为评估模式。
接下来,对于每个数据批次,使用模型进行预测,并将预测结果转换为二进制分类结果。根据分类目标选择正确的标签列,并确保预测结果和标签形状相同。
通过计算预测结果和标签相等的元素数量,累加得到正确预测的数目。最后,将模型设置回训练模式,并返回准确率。
3.关于测试集的准确度评估
在每个 epoch 的训练过程中,当满足 do_check_accuracy 为 True 并且当前 epoch 是检查准确率的间隔(根据 check_accuracy_every 参数指定)时,会执行准确率评估的代码块。
首先,会对训练集进行准确率评估,并打印出结果。接着,会对测试集进行准确率评估,并打印出结果。最后,会将测试集的准确率添加到 accuracy_per_epoch 列表中,并判断是否超过之前的最佳准确率。如果是,则保存当前模型。因此,测试集的准确率结果会在每个 epoch 的训练过程中输出,并保存在 accuracy_per_epoch 列表中供后续使用。
在本次实验中,每个数据集被分为两个子集:训练部分和测试部分。对于这个实验,模型已经在数据集的训练部分上进行了训练,并在相应数据集的测试集上进行了测试。
本次实验结果是采用固定训练集/测试集分割样本后的结果。
DNN和CNN模型在DEAP数据集上进行价值分类的结果,随着epoch的增加,测试的准确率变化如下图所示:
从上图可以看出,DNN模型在DEAP数据集上的分类结果似乎都优于CNN模型。
使用DNN模型分类的准确率在62%~79%之间,而使用CNN模型的分类准确率在56%~75%之间。
4.2 使用K折交叉验证对模型进行评估
此技术的主要思想是将数据集划分为相同大小的K个折叠(如果可能的话),然后,依次将每个折叠用作测试集,而数据集的其余部分用作训练集。对K个模型进行训练并评估其准确性,最后K次交叉验证的最终报告准确性是这些准确性的平均值。DEAP的32倍交叉验证结果如下图所示:
使用K-fold交叉验证发现的准确性远低于使用固定训练/测试分割发现的准确性。因此,可以说,模型存在高方差误差,即其性能与特定的训练和提供给它们的测试集高度相关。对于上图的结果,在数据集上操作的训练/测试分割很可能是“幸运”的分割,偶然产生了高精度。
在K折叠交叉验证过程中获得的特定折叠精度也证实了高方差猜想。例如,在DEAP上DNN模型的K-fold运行中,fold准确率从43%到78%不等,这表明不同的数据集分割如何从根本上改变准确率结果。
K-fold结果也证实了之前的结果,即CNN模型在两个数据集上都略优于DNN模型,而当在单个训练/测试分割上进行评估时,DNN模型能够达到更高的最大精度。
本次实验我们基于DEAP数据集进行二分类脑电信号识别,采用的网络模型是深度神经网络和卷积神经网络。由于之前未接触过这方面的训练,我在最开始做本次实验时有种无从下手的感觉。因此本次实验的很多思路都是借鉴于期刊论文中的做法,例如对数据的处理思路,对模型的训练方式等。但完成本次实验后,还是得到了不少的收获。首先,我对深度神经网络和卷积神经网络有了更深的理解,理论课上只是学习了关于CNN的一些知识和运算,而通过本次实践,真正感受到了神经网络的强大和奇妙;其次,我对科研的严谨性有了更深的体会。对于每一个问题,都尝试运用不同的模型去得到结果,然后进行对比和考量,选择最优的方法。又或者将几种模型集成,得到一个更优的模型,这与理论课上学习的集成学习思想很类似。最后,本次实验也让我深知科研训练的必要性。不仅是在知识的融会贯通上,还是能力的提升上,进行相关科研训练都是十分有益的。在今后,我也将花更多的时间去锻炼自己的科研能力,努力提高自己的科研素养!
写于2024-1-17
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。