0.前言:
好久没写博客了,看了看上一篇距今也要两个月了,写完第6篇博客后通过工作补充了不少自己的短板,比如EEG特征提取的代码撰写,自己之前只接触过PSD和WTD的提取方式,其他的没做过,还有深度刨析了其他的模型比如EEGNex和Q-EEGNET等。两个月转瞬即逝,自己工作转正了,对象养了只猫叫狗蛋,自己也有猫了,此处给狗蛋贴个帅照!
1.站在新的高度上看新的问题:
言归正传,此篇不说具体项目,说一下我的一些疑惑和近期看的论文的总结
1.1 浅谈特征输入和神经网络卷积核设置
我之前做的都是原始EEG信号直接输入到模型中,只做了预处理,在卷积层中通过设置卷积核来自动的提取原始数据中的时域或频域的特征,下面给出常用的卷积处理原始信号的Kernel_size设置方式:
时间卷积核:kernel_size = (H=1,W)
空间卷积核:kernel_size = (H,W=1)
时间空间卷积核: kernel_size = (H,W)
而最常用的提取方式是先时间后空间卷积层的搭配,这样模型提取特征的效果最好,这方面有很多论文,可自行查看。
近期工作遇到一个问题,起初我们先把原始EEG信号切段,然后提取了数十种特征,送到机器学习的模型中训练结果并不理想,现在是把提取好的特征扔到深度学习模型中训练,于是问题来了:
1. 提的特征是时域、空间域、频域的特征
2. DL模型卷积层可自动提取时间、空间特征(就看你怎样设置卷积核)
问题:提的时间空间等的特征再用时间\空间卷积核再提取时间、空间信息,扔到模型中训练,有人这样做过吗?靠谱吗?
工程嘛,扔进去看看就知道了,但我知道这样是不可行的,因CNN本身最大的优势就是避免了繁杂的人工特征提取,你用CNN模型再费劲提这些特征进去,何苦呢。所以改变了思路,还是要原始数据切片输入,去训练模型。对此看到这篇博客的大佬,若有高见,欢迎评论。
1.2 开源的EEGNet代码错误问题
使用EEGNet去处理原始EEG信号,对着原论文结构我又重写了一遍模型,但通过同事提醒,我发现了我犯了很多人复写这模型犯的错误:第二个block的DepthwiseConv2D代码写错了。然后我搜了一些其他人写的这个模型,发现都错了,下面贴出原论文模型结构:
红框内是第二层深度卷积层部分,该层kernel_size=(C,1)是空间卷积核,滤波器数量 D*F1,注意参数中是 C*D*F1 ,很多人包括我,没注意到的就是这个D,它指的是:F1个滤波器滤波的次数。所以有的人把这一层代码错误的写成了下面这个样子:
class DepthwiseConv(nn.Module):
def __init__(self, inp, oup):
super(DepthwiseConv, self).__init__()
self.depth_conv = nn.Sequential(
# dw
nn.Conv2d(inp, inp, kernel_size=3, stride=1, padding=1, groups=inp, bias=False),
nn.BatchNorm2d(inp),
nn.ReLU6(inplace=True),
# pw
nn.Conv2d(inp, oup, kernel_size=1, stride=1, padding=0, bias=False),
nn.BatchNorm2d(oup),
nn.ReLU6(inplace=True)
)
def forward(self, x):
return self.depth_conv(x)
这是错误的,他把这个D理解成了做了两层卷积的深度卷积层,而且他还把深度卷积和深度可分离卷积混为一谈了,正确的应该是一层Conv2D卷积出来后的D次结果做数据拼接,正确的代码是同事写的,此处不贴,贴个狗蛋帅照。
1.3 浅谈神经网络在BCI中的“黑暗森林”
我看论文有时一直在想一件事,神经网络处理BCI数据并不像传统CV那样处理图片似的,有很多问题和数据输入、建模技巧只能通过自己的工程实践所得,大部分论文此方面技巧只提一言两语,因为这是宝贵的工程经验,他们也不想说,直到我找到一篇论文,里面大段大段的详细讲述了CNN处理EEG信号的技巧,我用一两句话概括如下:
1.Conv2D > Conv1D
二维卷积处理EEG信号更优秀,这是因为二维卷积不需要将多通道EEG信号压缩成顺序格式,并可以跨通道进行学习,这也是EEG信号需要升维的一个原因。
2.组合模型>单个模型
典型的CNN-LSTM>CNN\LSTM,也就是1+1>2的现象会发生在深度学习中,此论文的解释是:“适当的空间过滤\学习后提取的额外的时间信息有利于进一步提高模型性能。”
3.CNN>RNN
论文解释:“rnn和Conv1D等序列处理方法不能有效的提取和表示隐式脑电信息”,虽然EEG信号也是时序信号,但RNN处理脑电信号属实不行,并且最近查看的SCI论文EEG|自动驾驶方面有很多都提及了时序信息中的隐式信息。
4.空间信息>时间信息
也就是跨通道提取空间信息比在片段中提取时间信息做分类要好。
1.4 浅谈信号切片的维度归属
注:通道写错了,是32个channel,在同学提问下已修正。
我拿到一个100s的脑电原始信号,做切片,窗w=1s,窗移frame=0.5,采样率sample_rate=256,channels=32:
原始信号.shape=(32,25600)
a = w * sample_rate = 1 * 256
b = frame * sample_rate = 0.5 * 256
切片后.shape = (int(data.shape[1]/b), channels, a) = (200,32,256)
对于这个3维数据的解释如下:
200是100s做1s的窗,0.5窗移后的切段数量,可以作为样本量,供模型中超参数batch_size调用
16还是通道数,死活不能变
256是1s的窗口中包含的数据量
所以,切片后共有200个数据片段,每个片段有32个通道,每个通道有256个数据点,训练的就是每个片段中的每个通道中的256个数据点的和。但这样跑模型出bug,想要二维卷积处理要升维,变成(200,32,16,16),那为何是把256变成16*16呢,而不是8*32或者别的公因数,这个问题我之前探讨过,但是没贴总结,总结最后让狗蛋贴出。
狗蛋来啦!!!
狗蛋走啦!!!