代码实现
class Model(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1,6,5) #(H+2p-K)/S + 1
self.pool1 = nn.AvgPool2d(kernel_size=2,stride=2)
self.conv2 = nn.Conv2d(6,16,5)
self.pool2 = nn.AvgPool2d(2)
self.fc1 = nn.Linear(5*5*16,120)
self.fc2 = nn.Linear(120,84)
def forward(self,x):
x = F.tanh(self.conv1(x))
x = self.pool1(x)
x = F.tanh(self.conv2(x))
x = self.pool2(x)
x = x.view(-1,5*5*16) #-1,
x = F.tanh(self.fc1(x))
output = F.softmax(self.fc2(x),dim=1) #(samples, features)
class Model(nn.Module):
def __init__(self):
super().__init__()
#为了处理尺寸较大的原始图片,先使用11x11的卷积核和较大的步长来快速降低特征图的尺寸
#同时,使用比较多的通道数,来弥补降低尺寸造成的数据损失
self.conv1 = nn.Conv2d(3,96, kernel_size=11, stride=4)
self.pool1 = nn.MaxPool2d(kernel_size=3, stride=2) #overlap pooling
#已经将特征图尺寸缩小到27x27,计算量可控,可以开始进行特征提取了
#卷积核、步长恢复到业界常用的大小,进一步扩大通道来提取数据
self.conv2 = nn.Conv2d(96,256,kernel_size=5,padding=2)
self.pool2 = nn.MaxPool2d(kernel_size=3, stride=2)
#疯狂提取特征,连续用多个卷积层
#kernel 5, padding 2, kernel 3, padding 1 可以维持住特征图的大小
self.conv3 = nn.Conv2d(256,384,kernel_size=3, padding =1)
self.conv4 = nn.Conv2d(384,384,kernel_size=3, padding =1)
self.conv5 = nn.Conv2d(384,256,kernel_size=3, padding =1)
self.pool3 = nn.MaxPool2d(kernel_size=3, stride=2)
#进入全连接层,进行信息汇总
self.fc1 = nn.Linear(6*6*256,4096) #上层所有特征图上的所有像素
self.fc2 = nn.Linear(4096,4096)
self.fc3 = nn.Linear(4096,1000)
def forward(self,x):
x = F.relu(self.conv1(x))
x = self.pool1(x)
x = F.relu(self.conv2(x))
x = self.pool2(x)
x = F.relu(self.conv3(x))
x = F.relu(self.conv4(x))
x = F.relu(self.conv5(x))
x = self.pool3(x)
x = x.view(-1,6*6*256) #将数据拉平
x = F.dropout(x,p=0.5)
x = F.relu(F.dropout(self.fc1(x),p=0.5))
x = F.relu(self.fc2(x))
output = F.softmax(self.fc3(x),dim=1)
class VGG16(nn.Module):
def __init__(self):
super().__init__()
self.features_ = nn.Sequential(nn.Conv2d(3,64,3,padding=1),nn.ReLU(inplace=True)
,nn.Conv2d(64,64,3,padding=1),nn.ReLU(inplace=True)
,nn.MaxPool2d(2)
,nn.Conv2d(64,128,3,padding=1),nn.ReLU(inplace=True)
,nn.Conv2d(128,128,3,padding=1),nn.ReLU(inplace=True)
,nn.MaxPool2d(2)
,nn.Conv2d(128,256,3,padding=1),nn.ReLU(inplace=True)
,nn.Conv2d(256,256,3,padding=1),nn.ReLU(inplace=True)
,nn.Conv2d(256,256,3,padding=1),nn.ReLU(inplace=True)
,nn.MaxPool2d(2)
,nn.Conv2d(256,512,3,padding=1),nn.ReLU(inplace=True)
,nn.Conv2d(512,512,3,padding=1),nn.ReLU(inplace=True)
,nn.Conv2d(512,512,3,padding=1),nn.ReLU(inplace=True)
,nn.MaxPool2d(2)
,nn.Conv2d(512,512,3,padding=1),nn.ReLU(inplace=True)
,nn.Conv2d(512,512,3,padding=1),nn.ReLU(inplace=True)
,nn.Conv2d(512,512,3,padding=1),nn.ReLU(inplace=True)
,nn.MaxPool2d(2)
)
self.clf_ = nn.Sequential(nn.Dropout(0.5)
,nn.Linear(512*7*7,4096),nn.ReLU(inplace=True)
,nn.Dropout(0.5)
,nn.Linear(4096,4096),nn.ReLU(inplace=True)
,nn.Linear(4096,1000),nn.Softmax(dim=1)
)
def forward(self,x):
x = self.features_(x) #用特征提取的架构提取特征
x = x.view(-1,512*7*7) #调整数据结构,拉平数据
output = self.clf_(x)
return output
学习方法:
1.观看心仪脑公众号发布的脑电分析视频
2.阅读相关文献:主要精读一篇近十年DL用于EEG分析处理的综述论文file:///C:/Users/Katerina/Zotero/storage/5W6JM56Q/ab260c.html
3.进行一个简单的脑电实验
内容:通过脑电信号判断人是否是睁眼还是闭眼
数据:睁眼和闭眼静态脑电样本各2000,有60个通道
实验平台:matlab
实验方法:传统预处理方法+机器学习线性分类器
部分数据如下图:
分类结果:
学习主要内容
1.认识脑电信号
2.传统的处理方法
名称:Deep learning-based electroencephalography analysis: a systematic review
日期:2019-08-14
期刊:Journal of Neural Engineering
性质:Review
阅读所得重点:
1.为什么要使用DL?DL的效果如何?
用原始或预处理的脑电图时间序列来训练模型,在脑电图处理中使用深度学习的动机之一是自动特征学习,实现端到端的学习.
2.目前常用的DL架构有什么?
大多数论文都使用了少于5层的结构,对于脑电图数据,浅层网络目前是必要的。
3.使用DL使用的数据格式是什么?
使用完全原始的脑电图数据的近期研究优于各自的基线。
使用原始脑电图而不是手工设计的特征是一种趋势。
例如,对于癫痫发作的分类,最近提出的使用原始脑电图数据作为输入的模型比经典的基线方法(如带有频域特征的支持向量机)取得了更好的性能。
提出未来论文建议:
(1)清晰地描述架构
(2)清晰地描述使用的数据
(3)尽可能地使用现有的数据集
(4)包括最先进的baseline,理想情况下使用原始作者的代码
(5)尽可能共享内部记录
(6)共享代码
-更多细节与方法待更多的精读