EEG-DL(GitHub项目部分学习)

GitHub - SuperBruceJia/EEG-DL:基于 TensorFlow 的用于脑电图任务(信号)分类的深度学习库.

Usage Demo

  1. (Under Any Python Environment) Download the EEG Motor Movement/Imagery Dataset via this script.

    $ python MIND_Get_EDF.py
    
  2. (Under Python 2.7 Environment) Read the .edf files (One of the raw EEG signals formats) and save them into Matlab .m files via this script. FYI, this script must be executed under the Python 2 environment (Python 2.7 is recommended) due to some Python 2 syntax. If using Python 3 environment to run the file, there might be no error, but the labels of EEG tasks would be totally messed up.

    $ python Extract-Raw-Data-Into-Matlab-Files.py
    
  3. Preprocessed the Dataset via the Matlab and save the data into the Excel files (training_set, training_label, test_set, and test_label) via these scripts with regards to different models. FYI, every lines of the Excel file is a sample, and the columns can be regarded as features, e.g., 4096 columns mean 64 channels X 64 time points. Later, the models will reshape 4096 columns into a Matrix with the shape 64 channels X 64 time points. You should can change the number of columns to fit your own needs, e.g., the real dimension of your own Dataset.

仅仅进行以上几步,python2.7环境有一些库不好弄,直接用3.6试的,虽然没报错,但是生成的标签是一样的----确实有问题,然后python提取完数据后再用matlab处理,生成的文件名衔接也对不上,实在没办法直接运行了,但是对生成的数据,几次reshape的含义完全不理解,还有与标签的对应关系更不用说,先暂停于此,日后再看。

根据代码,X和Y是通过load_raw_data函数加载得到的。
X的形状为(len(trials), NUM_TRIALS, TRIAL_LENGTH * SAMPLE_RATE, EEG_CHANNELS),在代码中,NUM_TRIALS的值为21 * num_classes,
当num_classes = 4时,NUM_TRIALS = 21 * 4 = 84。TRIAL_LENGTH * SAMPLE_RATE = 4 * 160 = 640(假设TRIAL_LENGTH = 4秒,SAMPLE_RATE = 160Hz),
EEG_CHANNELS在选择电极时被设置为1(electrodes = [i]),但在后续处理中进行了扩展,所以最终X的形状为(20, 84, 640)。
Y的形状为(len(trials), NUM_TRIALS, num_classes),同样,由于num_classes = 4,所以Y的形状为(20, 84, 4)。
因此,您得到的dataset变量(即X)形状为20 * 84 * 640,labels变量(即Y)形状为20 * 84 * 4是符合代码逻辑的。

20 表示数据来自 20 个不同的受试者。
84 表示每个受试者有 84 个试验(trials)。
640 表示每个试验(trial)包含 640 个数据点。
Y(即labels)变量的形状20 * 84 * 4的含义是:
20 表示数据来自 20 个不同的受试者。
84 表示每个受试者有 84 个试验(trials)的标签。
4 表示每个试验(trial)的标签是一个 4 维的向量,可能对应于 4 种不同的类别或状态。

labels(1, 1, 2) 表示第一个受试者的第一个试验的第二个类别的标签值。
labels(1, 2, 1) 表示第一个受试者的第二个试验的第一个类别的标签值。
labels(2, 1, 1) 表示第二个受试者的第一个试验的第一个类别的标签值。
对于 dataset 变量:
dataset(1, 1, 1) 表示第一个受试者的第一个试验的第一个数据点。
dataset(1, 2, 1) 表示第一个受试者的第二个试验的第一个数据点。
dataset(2, 1, 1) 表示第二个受试者的第一个试验的第一个数据点。
dataset(1, 1, 2) 表示第一个受试者的第一个试验的第二个数据点。

reshape(labels(1, :, :), [], 4) 的含义是将 labels 矩阵中第一个受试者的所有标签数据(这是一个三维的子矩阵)重新调整为二维矩阵。(第三个维度为4)
reshape(Labels, [], 4);查看所有受试者的所有标签数据


这个一维向量的数据含义是将特定通道的数据集按照特定的顺序展开成一个长的线性序列
具体来说,它包含了该通道对应所有受试者的所有试验的数据。在这个顺序中,先是第一个受试者的第一个试验的数据,然后是第一个受试者的第二个试验的数据,以此类推,直到最后一个受试者的最后一个试验的数据

这段代码输入的是 64 个 `mat` 文件中的数据,每个文件中的数据维度为 `num_subject * num_trial * num_data`,即 `20 * 84 * 640


首先,已知:
`num_subject = 20`
`num_trial = 84`
`num_channel = 64`
`num_data = 640`
`Time_consider = 4 / 10`
`Data_points = Time_consider * 160 = (4 / 10) * 160 = 64`

在循环中,对每个通道加载数据并处理:
`Dataset = reshape(Dataset, num_subject*num_trial, num_data)` ,此时矩阵维度为 `(20 * 84) × 640` 。

`Dataset = reshape(Dataset', 1, row*column)` ,经过转置和重塑后变成一维向量。

`Stack_Dataset = [Stack_Dataset; Dataset]` ,最终 `Stack_Dataset` 是一个二维矩阵。

`Stack_Dataset = reshape(Stack_Dataset, [num_channel, num_subject*num_trial, num_data])` ,此时变成三维矩阵,维度为 `64 × (20 * 84) × 640` 。

然后,进行标准化处理后,再次重塑:
`Stack_Dataset = reshape(Stack_Dataset, [num_channel, num_subject*num_trial*num_data])` ,此时维度为 `64 × (20 * 84 * 640)` 。

`[~, columns] = size(Dataset)` ,这里的 `columns` 等于 `20 * 84 * 640` 。

`Dataset = reshape(Stack_Dataset, [num_channel*Data_points, columns/Data_points])` ,维度为 `(64 * 64) × (20 * 84 * 640 / (20 * 84 * 640 / 64)) = 4096 × 64` 。
`Dataset = Dataset'` ,转置后维度为 `64 × 4096` 。

对于标签部分的处理,最终得到的 `Labels` 维度取决于具体的数据内容和处理过程中的变化。

在划分训练集和测试集时:
`training_set = ALL_Dataset(1:fix(row/10*9), 1:4096)` ,其维度取决于 `row` 的值,即 `ALL_Dataset` 的行数,假设为 `M` ,则维度为 `(fix(M/10*9)) × 4096` 。
`test_set = ALL_Dataset(fix(row/10*9)+1:end, 1:4096)` ,维度为 `(M - fix(M/10*9)) × 4096` 。

`training_label = ALL_Dataset(1:fix(row/10*9), end)` 和 `test_label = ALL_Dataset(fix(row/10*9)+1:end, end)` ,维度分别为 `fix(M/10*9)` 和 `(M - fix(M/10*9))` 。

`all_data = ALL_Dataset(:, 1:4096)` ,维度为 `M × 4096` 。
`all_labels = ALL_Dataset(:, end)` ,维度为 `M` 。

最终,代码将这些数据分别保存到 Excel 文件中。 

假设原始的三维矩阵 Dataset 的形状为 num_subject * num_trial * num_data ,可以将其想象成由 num_subject * num_trial 个“小长方体”组成,每个“小长方体”的维度是 1×num_data 。
reshape(Dataset, num_subject*num_trial, num_data) 操作会按照以下方式将三维矩阵转换为二维矩阵:
从原始的三维矩阵开始,先沿着第一个维度(num_subject 方向)遍历,然后在每个 num_subject 内部沿着第二个维度(num_trial 方向)遍历。对于遍历到的每个元素,将其对应的 num_data 个元素依次放入新的二维矩阵的一行中。
例如,假设 num_subject = 2 , num_trial = 3 , num_data = 4 ,原始的三维矩阵可能像这样(为了简单,数值较小):

[
  [
    [1, 2, 3, 4],第一个受试者的第一次试验的数据
    [5, 6, 7, 8],第一个受试者的第二次试验的数据
    [9, 10, 11, 12]第一个受试者的第三次试验的数据
  ],
  [
    [13, 14, 15, 16],第二个受试者的第一次试验的数据
    [17, 18, 19, 20],第二个受试者的第二次试验的数据
    [21, 22, 23, 24]第二个受试者的第三次试验的数据
  ]
]

对于这个示例矩阵,reshape 操作取出元素并放入新矩阵的顺序如下:
首先,取出第一个子矩阵中的第一个子数组 [1, 2, 3, 4] 放入新矩阵的第一行。
然后,取出第一个子矩阵中的第二个子数组 [5, 6, 7, 8] 放入新矩阵的第二行。
接着,取出第一个子矩阵中的第三个子数组 [9, 10, 11, 12] 放入新矩阵的第三行。
再取出第二个子矩阵中的第一个子数组 [13, 14, 15, 16] 放入新矩阵的第四行。
以此类推,最终得到的新二维矩阵为:
[
  [1, 2, 3, 4],第一个受试者的第一次试验的数据
  [5, 6, 7, 8],第一个受试者的第二次试验的数据
  [9, 10, 11, 12],第一个受试者的第三次试验的数据
  [13, 14, 15, 16],第二个受试者的第一次试验的数据
  [17, 18, 19, 20],第二个受试者的第二次试验的数据
  [21, 22, 23, 24]第二个受试者的第三次试验的数据
]
转置之后:
[
  [1, 5, 9, 13, 17, 21],
  [2, 6, 10, 14, 18, 22],
  [3, 7, 11, 15, 19, 23],
  [4, 8, 12, 16, 20, 24]

]

要将其重塑为 `num_subject * num_trial * num_data` 的一维向量,假设 仍然还是`num_subject = 2`, `num_trial = 3` , `num_data = 4` ,步骤如下:

首先将转置后的矩阵按行展开为一维数组:
[1, 5, 9, 13, 17, 21, 2, 6, 10, 14, 18, 22, 3, 7, 11, 15, 19, 23, 4, 8, 12, 16, 20, 24]一通道的所有数据


经过以下代码:
for i = 1:num_channel
%     Dataset = ['Dataset_', num2str(i), '.mat'];
    Dataset = ['20-SubjectsDataset_', num2str(i), '.mat'];%改
    Dataset = load(Dataset);
    Dataset = Dataset.Dataset;
    Dataset = reshape(Dataset, num_subject*num_trial, num_data);
    
    [row, column] = size(Dataset);
    Dataset = reshape(Dataset', 1, row*column);
    Stack_Dataset = [Stack_Dataset; Dataset];
end

假设通道数是2,且每个通道的数据一样
逻辑上应该得到:
[1, 5, 9, 13, 17, 21, 2, 6, 10, 14, 18, 22, 3, 7, 11, 15, 19, 23, 4, 8, 12, 16, 20, 24]一通道的所有数据
[1, 5, 9, 13, 17, 21, 2, 6, 10, 14, 18, 22, 3, 7, 11, 15, 19, 23, 4, 8, 12, 16, 20, 24]二通道的所有数据


Stack_Dataset = reshape(Stack_Dataset, [num_channel, num_subject*num_trial, num_data]);
得到三维矩阵

对于给定的原始二维矩阵:
```
[
  [1, 5, 9, 13, 17, 21, 2, 6, 10, 14, 18, 22, 3, 7, 11, 15, 19, 23, 4, 8, 12, 16, 20, 24], 
  [1, 5, 9, 13, 17, 21, 2, 6, 10, 14, 18, 22, 3, 7, 11, 15, 19, 23, 4, 8, 12, 16, 20, 24]
]
```

并且已知 `num_subject = 2` , `num_trial = 3` , `num_data = 4` 。

元素的取放顺序如下:

对于第一个通道(即第一行数据):

首先,取出前 4 个元素 `[1, 5, 9, 13]` ,

接着,再取出接下来的 4 个元素 `[17, 21, 18, 22]` ,

然后,取出接下来的 4 个元素 `[3, 7, 11, 15]` ,

继续,取出接下来的 4 个元素 `[19, 23, 20, 24]` ,

再接着,取出接下来的 4 个元素 `[4, 8, 12, 16]` ,

最后,取出最后的 4 个元素 `[2, 6, 10, 14]` ,

对于第二个通道(即第二行数据),按照同样的顺序进行取放。

这样就得到了最终的三维矩阵:
```
[
  [
    [1, 5, 9, 13],
    [17, 21, 18, 22],
    [3, 7, 11, 15],
    [19, 23, 20, 24],
    [4, 8, 12, 16],
    [2, 6, 10, 14]
  ],
  [
    [1, 5, 9, 13],
    [17, 21, 18, 22],
    [3, 7, 11, 15],
    [19, 23, 20, 24],
    [4, 8, 12, 16],
    [2, 6, 10, 14]
  ]
]
```

Stack_Dataset = reshape(Stack_Dataset, [num_channel, num_subject*num_trial*num_data]);


并且已知 num_channel = 2,num_subject = 2,num_trial = 3,num_data = 4 。
经过 Stack_Dataset = reshape(Stack_Dataset, [num_channel, num_subject*num_trial*num_data]) 操作后,会得到一个新的二维矩阵:

[
  [1, 5, 9, 13, 17, 21, 18, 22, 3, 7, 11, 15, 19, 23, 20, 24, 4, 8, 12, 16, 2, 6, 10, 14],
  [1, 5, 9, 13, 17, 21, 18, 22, 3, 7, 11, 15, 19, 23, 20, 24, 4, 8, 12, 16, 2, 6, 10, 14]
]
即每个通道的数据被展平为一个长度为 num_subject*num_trial*num_data 的一维向量,然后两个通道的向量组成一个二维矩阵。


[~, columns] = size(Dataset) ,这里的 columns 等于 20 * 84 * 640 。我这里的示例数据是columns是24
Dataset = reshape(Stack_Dataset, [num_channel*Data_points, columns/Data_points])


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值