使用CNN+LSTM进行脑电情绪识别

写了一份适合刚入门脑电情绪识别的一个可用于练手的代码讲解。

首先再进行用脑电信号进行情绪识别时会对数据进行一个处理,比如计算出微分熵,功率谱图等。

在这里我们首先采用计算出微分熵DE。

微分熵

微分熵是香农信息熵在连续变量上的推广形式,设x为脑电信号,其原始表达式为:

 其中,E(x)指的是连续的脑电信号的概率密度函数.

微分熵的代码实现

def compute_DE(signal):    #计算微分熵variance = np.var(signal, ddof=1)return math.log(2 * math.pi * math.e * variance) / 2

带通滤波

def butter_bandpass(lowcut, highcut, fs, order=5):  #带通滤波nyq = 0.5 * fslow = lowcut / nyqhigh = highcut / nyqb, a = butter(order, [low, high], btype='band')return b, adef butter_bandpass_filter(data, lowcut, highcut, fs, order=5):b, a = butter_bandpass(lowcut, highcut, fs, order=order)y = lfilter(b, a, data)return y

什么要进行带通滤波呢?

因为对于原始数据,我们的目的是提取出四个频带(αβγθ)中的微分熵,所以我们要通过带通滤波从原始的信号中分离出这四个频带。(带通滤波器主要可以使用在需要保留的波的频率在一定的范围内,用于去除周围的噪声,可以起到良好的效果。)

加下来就是求出每次实验数据的微分熵了。

具体代码如下:

    for trial in range(40):  #对于其中40次试验,  这里是计算基线的DE特征temp_base_DE = np.empty([0])       #多一个基线DEtemp_base_theta_DE = np.empty([0])   #相对于seed数据集在频带上少一个deltatemp_base_alpha_DE = np.empty([0])temp_base_beta_DE = np.empty([0])temp_base_gamma_DE = np.empty([0])temp_de = np.empty([0, 120]) #将60S的数据进行一个切分,0.5s为一个点for channel in range(32):  #对于40次试验中的每次试验中的32个通道trial_signal = data[trial, channel, 384:]   #384之后的为试验数据base_signal = data[trial, channel, :384]  #384 为3*128=384前三秒为试验前基线# ****************compute base DE****************base_theta = butter_bandpass_filter(base_signal, 4, 8, frequency, order=3) #这里是对基线信号的处理base_alpha = butter_bandpass_filter(base_signal, 8, 14, frequency, order=3)base_beta = butter_bandpass_filter(base_signal, 14, 31, frequency, order=3)base_gamma = butter_bandpass_filter(base_signal, 31, 45, frequency, order=3)base_theta_DE = (compute_DE(base_theta[:64]) + compute_DE(base_theta[64:128]) + compute_DE(base_theta[128:192]) + compute_DE(base_theta[192:256]) + compute_DE(base_theta[256:320]) + compute_DE(base_theta[320:])) / 6  #首先用0.5s将基线分成6段,然后对这六段的DE特征进行一个平均base_alpha_DE = (compute_DE(base_alpha[:64]) + compute_DE(base_alpha[64:128]) + compute_DE(base_alpha[128:192]) + compute_DE(base_theta[192:256]) + compute_DE(base_theta[256:320]) + compute_DE(base_theta[320:])) / 6base_beta_DE = (compute_DE(base_beta[:64]) + compute_DE(base_beta[64:128]) + compute_DE(base_beta[128:192]) + compute_DE(base_theta[192:256]) + compute_DE(base_theta[256:320]) + compute_DE(base_theta[320:])) / 6base_gamma_DE = (compute_DE(base_gamma[:64]) + compute_DE(base_gamma[64:128]) + compute_DE(base_gamma[128:192]) + compute_DE(base_theta[192:256]) + compute_DE(base_theta[256:320]) + compute_DE(base_theta[320:])) / 6temp_base_theta_DE = np.append(temp_base_theta_DE, base_theta_DE)temp_base_gamma_DE = np.append(temp_base_gamma_DE, base_gamma_DE)temp_base_beta_DE = np.append(temp_base_beta_DE, base_beta_DE)temp_base_alpha_DE = np.append(temp_base_alpha_DE, base_alpha_DE)theta = butter_bandpass_filter(trial_signal, 4, 8, frequency, order=3)   #这是对实验数据的处理alpha = butter_bandpass_filter(trial_signal, 8, 14, frequency, order=3)beta = butter_bandpass_filter(trial_signal, 14, 31, frequency, order=3)gamma = butter_bandpass_filter(trial_signal, 31, 45, frequency, order=3)DE_theta = np.zeros(shape=[0], dtype=float)DE_alpha = np.zeros(shape=[0], dtype=float)DE_beta = np.zeros(shape=[0], dtype=float)DE_gamma = np.zeros(shape=[0], dtype=float)for index in range(120):DE_theta = np.append(DE_theta, compute_DE(theta[index * 64:(index + 1) * 64]))DE_alpha = np.append(DE_alpha, compute_DE(alpha[index * 64:(index + 1) * 64]))DE_beta = np.append(DE_beta, compute_DE(beta[index * 64:(index + 1) * 64]))DE_gamma = np.append(DE_gamma, compute_DE(gamma[index * 64:(index + 1) * 64]))temp_de = np.vstack([temp_de, DE_theta])temp_de = np.vstack([temp_de, DE_alpha])temp_de = np.vstack([temp_de, DE_beta])temp_de = np.vstack([temp_de, DE_gamma])temp_trial_de = temp_de.reshape(-1, 4, 120)decomposed_de = np.vstack([decomposed_de, temp_trial_de])#temp_base_DE = np.append(temp_base_DE, temp_base_theta_DE)temp_base_DE = np.append(temp_base_theta_DE, temp_base_alpha_DE)temp_base_DE = np.append(temp_base_DE, temp_base_beta_DE)temp_base_DE = np.append(temp_base_DE, temp_base_gamma_DE)base_DE = np.vstack([base_DE, temp_base_DE])

最后我们得到的数据形式为【4800,128】

接下来我们要把数据规模改变为对应频带,电极二维映射的形式,也就是【4800,4,9,9】

也就是这种形式:

 当我们把数据处理工作完成后,我们就可以把数据集划分为训练集以及测试集,(一般采用K折交叉验证。)然后把分好的数据放到网络里进行训练与测试 。

class ConvLSTM(nn.Module):def __init__(self, embedding_size, batch_size, num_classes, hidden_size=8, num_directions=1, num_layers=1):super(ConvLSTM, self).__init__()self.conv1 = nn.Conv2d(4, 24, 5)self.conv2 = nn.Conv2d(24, 128, 2)self.fc1 = nn.Linear(128 * 2 * 2, 96)self.fc2 = nn.Linear(96, embedding_size)self.lstm = nn.LSTM(embedding_size, hidden_size, num_layers, batch_first=True)self.hidden = Noneself.init_hidden(batch_size, hidden_size, num_directions, num_layers)self.fc3 = nn.Linear(hidden_size, num_classes)

 最后的结果为:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/67678.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

神经元激活函数

神经元激活函数 激活函数(Activation functions),将非线性特性引入到网络中。如下图,在神经元中,输入的 inputs 通过加权,求和后,还被作用了一个函数,这个函数就是激活函数。 引入激活函数是为了增加神经…

独家 | 人工神经网络中发现了人类大脑拥有的多模态神经元(附链接)

作者:Gabriel Goh, Chelsea Voss, Daniela Amodei, Shan Carter, Michael Petrov, Justin Jay Wang, Nick Cammarata, and Chris Olah 翻译:欧阳锦 校对:王可汗本文约4000字,建议阅读12分钟本文探讨了OpenAI在CLIP模型中发现人类大…

神经网络(三)—— 神经元多输出

本系列为慕课网《深度学习之神经网络(CNN/RNN/GAN)算法原理实战》视频笔记,希望自己能通过分享笔记的形式更好的掌握该部分内容。 往期回顾: 神经网络(一)—— 机器学习、深度学习简介 神经网络(二)—— 神…

3D U-Net脑胶质瘤分割BraTs + Pytorch实现

原论文地址: 连接 一、网络模型的分析和对比 原始2D-Unet网络模型 我的2D-Unet网络模型 1、和原来的2D-Unet网络不同的是,我输入通道为4,我这里应该改为4个通道,对应四个模态图像,而输出通道为3,我对应的是三个嵌套子区域标签(WT、TC、ET) 2、另外,最大不同的是我的3X3卷积…

深度学习(一)——MP神经元模型, BP算法, 神经元激活函数, Dropout

https://antkillerfarm.github.io/ 前言 神经网络本质上不是什么新东西。十年前,我还在上学的时候,就接触过皮毛。然而那时这玩意更多的还是学术界的屠龙之术,工业界几乎没有涉及。 及至近日重新拾起,方才发现,这十…

单个人工神经元模型示意图,人体神经元模型制作

人工神经元的基本构成 人脑的神经元模型如图8.6所示。图中一个神经元由细胞核、一个轴突、多个树突、突触组成。生物电信号从树突传入,经过细胞核处理,从轴突输出一个电脉冲信号。 神经元通过树突与轴突之间的突触与其他神经元相连构成一个复杂的大规模…

神经元的细胞体内有什么,神经元的细胞体在哪里

神经元细胞体位于哪里? 谷歌人工智能写作项目:神经网络伪原创 你知道神经元在我们身体的哪个部位吗? 神经元的基本结构包括细胞体和突起.神经元的突起一般包括一条长而分枝少的轴突和数条 短而呈树状分枝的树突.轴突以及套在外面的髓鞘,叫做神经纤维.…

03 神经元多输入

神经元多输入 上一篇博客介绍了二分类的逻辑回归模型。如果我们想要多分类的逻辑回归模型,我们该怎么做呢? 很显然,我们在只有一个神经元的时候可以做二分类的问题。如果我们想要多分类的话,直接加神经元的个数就好了,…

人脑部神经网络分布特点,人脑部神经网络分布图

人的大脑的怎么分配的 大脑(Brain)包括左、右两个半球及连接两个半球的中间部分,即第三脑室前端的终板。大脑半球被覆灰质,称大脑皮质,其深方为白质,称为髓质。髓质内的灰质核团为基底神经节。在大脑两半球间由巨束纤维—相连。 …

人体内数量最多的神经元,人体内有多少个神经元

人体内平均有多少神经元? 。 约含有140亿个神经元胞体虽然神经元形态与功能多种多样,但结构上大致都可分成胞体(cellbody,orsoma)和突起(neurite)两部分.突起又分树突(dendrite)和…

【计量经济学】【高教版】第二次作业

第二次作业: 教材:伍德里奇。计量经济学导论:现代观点(第五版)。 第三章习题:必做 1,2,5,6,11,选做13 第四章习题:必做2,3,4,5,8,选做9,10,11 第三章 1.多元线性回归模型的基本假设是什么?在证明最小二乘估计量的无偏性和有效性的过程中,哪些基本假设起…

【计量经济学】【高教版】第一次作业(7、8、10)

第二次 7.假设有人做了如下的回归: y i = β 0 ^ + β 1 ^ x i + e i y_i=\widehat{\beta_0}+\widehat{\beta_1}x_i+e_i yi​=β0​ ​+β1​ ​xi​+ei​ 其中, y i , x i y_i,x_i yi​,xi​分别为 Y i , X i Y_i,X_i Yi​,Xi​关于各自均值的离差。问 β 0 ^ 和 β 1 ^ \…

软件工程经济学作业5-7

1.什么是生产函数? 其主要特征是什么? 答:生 产函数是指一定时期内生产要素的数量与某种组合同其所能出产的最大产量之间存在的函数关系。 生产函数通常满足以下三个特征: (1 ) 资本 与劳动力的边际产出总是为正值, 在…

2020年12月程序员工资统计,平均14222元(转载)

2020年12月全国招收程序员394699人。2020年12月全国程序员平均工资14222元,工资中位数12500元,其中96%的人的工资介于3250元到62500元。 从图上看,工资是真的降了,吓得我瑟瑟发抖。希望明年涨回来。 城市 排名city平均工资最低工资…

每日一题-13(员工薪水中位数)

题13: 根据下表,在不使用任何内置的SQL函数的情况下编写SQL查询来查找每个公司的薪水中位数。 解题思路:题目要求是不使用任何内置的SQL函数,因此使用HAVING的妙用。 (1)先做自连接,之后根据ID…

《2020年全球程序员收入报告》字节跳动高居全球第七,年薪中位数高达40万美元!

速读2分钟,今天看到一份特别有意思的报告,是 《2020 年全球程序员收入报告》 。 大家谨慎观看,我感觉大家看完这份报告,在感受到拖后腿之后,容易丧心病狂,产生病态的嫉妒心理。 日前,Levels.f…

上半年薪资统计,数据岗中位数接近20K!

大家应该都和我一样,经常看到类似于《XXX入职大厂数据分析师,年薪50W》之类的标题。 数据分析师的薪资真的有这么夸张吗?我特意去查了下数据: (数据来源:职友集) 最近的数据显示,全国…

2021年3月程序员工资统计,平均15189元,又涨了

2021年3月采集数据124176条。2021年3月全国程序员平均工资15189元,工资中位数12500元,其中95%的人的工资介于5250元到37500元。 工资K线图: 这个月涨了一点点,一点点也是涨呀。 程序员的工资虽然不高,但是涨幅还是超…

2019年一线城市程序员工资大调查

转载声明:转载不得篡改文章内容。必须注明出处,必须注明Github源代码地址。 保留要求转载者删除文章的权力。 欢迎转载,提供本文markdown: https://github.com/juwikuang/china_job_survey/blob/master/articles/2019年一线城市…

2020年1月全国程序员工资统计,平均工资13632元。

趋势 2020年1月,中国大陆程序员平均工资13632员,比上个月增加。具体趋势如图: 各主要程序员城市工资变化 城市 北京,上海,深圳,杭州,广州四地的工资最高。 city平均工资最低工资中位数最高…