deap dataset的不同分类模型的实现(2)-认识数据

9 篇文章 13 订阅

在本系列教程中,我们将使用python mne + pyTorch进行基本的EEG分析。案例研究将在脑电情绪识别的基准数据集DEAP上进行。在第1部分中,我们将重点关注数据集。

本教程假设:

1、您已经对Python有了基本的了解
2、你有一些scikit-learn的经验,也有一些机器学习的知识
3、你有一些使用pyTorch的经验,也有一些关于深度学习的知识

在这个数据集中,共有32个参与者,每个参与者观看40个1分钟的视频。因此s01.dat持有40批。总样品40*32=1280批。
查看每个dat文件(例如,s01),它包含数据和标签。

  • 数据---- 40 x 40 x 8064[视频/批次x通道x样品]
  • 标签---- 40x4

在40个通道中,32个通道是EEG,其余8个通道来自其他传感器,如EOG(见原文6.1节)。我们将只提取前32个通道。对于8064,由于数据被降采样到128Hz,因此一秒大约包含128个样本,因此一分钟也就是60秒,大约包含7680个样本。这篇论文并没有讲太多,但很可能在前后还有1.5秒,总共8064个样本(128 Hz * 63秒)。

这四个标签对应valence, arousal, liking, and dominance,按这个顺序排列。我们将只使用valence and arousal,因此将提取索引0和1的标签。

import torch

import os
import pickle
import numpy as np
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print("Configured device: ", device)

#加载数据
class Dataset(torch.utils.data.Dataset):
    
    def __init__(self, path, stim):
        _, _, filenames = next(os.walk(path))
        filenames = sorted(filenames)
        all_data = []
        all_label = []
        for dat in filenames:
            temp = pickle.load(open(os.path.join(path,dat), 'rb'), encoding='latin1')
            all_data.append(temp['data'])
            
            if stim == "Valence":
                all_label.append(temp['labels'][:,:1])   #the first index is valence
            elif stim == "Arousal":
                all_label.append(temp['labels'][:,1:2]) # Arousal  #the second index is arousal
                
        self.data = np.vstack(all_data)   #shape: (1280, 40, 8064) ==> 1280 samples / 40 samples = 32 participants
        self.label = np.vstack(all_label) #(1280, )  ==> 1280 samples, each with a unique label (depend on the param "stim")
        
        del temp, all_data, all_label

    def __len__(self):
        return self.data.shape[0]

    def __getitem__(self, idx):
        single_data  = self.data[idx]
        single_label = (self.label[idx] > 5).astype(float)   #convert the scale to either 0 or 1 (to classification problem)
        
        batch = {
            'data': torch.Tensor(single_data),
            'label': torch.Tensor(single_label)
        }
        
        return batch
#create a folder "data", and inside put s01.dat,....,s32.dat inside from the preprocessed folder from the DEAP dataset
path = "data"    

#我们可以尝试使用索引查看一个样本。这将自动映射到<code>__getitem__</code>函数在<code>Dataset</code>类。
dataset_valence = Dataset(path, "Valence")
dataset_arousal = Dataset(path, "Arousal")


dataset_valence[0]


print("Shape of data: ", dataset_valence[0]['data'].shape)  #40 channels of data, 8064 samples in 1 minute
print("Shape of label: ", dataset_valence[0]['label'].shape) #just 1 single label; 0 or 1

#让我们看看我们的数据和标签分布。
data = dataset_valence[:]['data']
label = dataset_valence[:]['label']

#所以我们得到了1280次trial(40个视频* 32个参与者= 1280,每个视频有40个数据通道,每个视频包含8064个脑电图样本)

data.shape  

#所以我们得到了1280个标签,也就是说,每个视频一个标签
label.shape  
#让我们数一下valence dataset里有多少个0和1,看看是否存在不平衡。
cond_1 = label == 1
cond_0 = label == 0

print("Labels 1 in valence dataset: ", len(label[cond_1]))
print("Labels 0 in valence dataset: ", len(label[cond_0]))
#Labels 1 in valence dataset:  708
#Labels 0 in valence dataset:  572

#为了确认前32个通道为EEG,其余8个通道为其他通道,我们检查每个通道的中值,看是否有模式。
for i in range(40):
    print(f"Median of {i} data: {torch.median(data[:, i, :])}")
#我们可以看到,0到31的数据索引是明显的EEG,而32之后的数据则不是。

# #总结

我们处理数据集的方式有三个重要的观察结果需要修正:

  1. 首先,确保我们只采集32通道的脑电图。当然,您也可以随意使用其他数据通道,但本教程主要关注的是EEG。
  2. 数据分割是创建更多数据段的过程。例如,在一个1分钟的视频中,我们可以分成12个5秒的片段,这样可以大大增加样本的数量,从而大大增加更好的预测的机会。步骤是:
  • a.重塑使(1280,32 8064)变成(1280,32,672,12)
  • b.然后置换(1280,32,672,12)为(1280,12,32,672)
  • c.然后重塑至(1280* 12,32,672)

请注意,由于作者已经对数据进行了预处理,所以我们不需要再做任何事情,但我们很自然地就会进行预处理,例如min-max归一化、陷波滤波器、带通滤波器等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大大U

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值