├── README.md ├── tCNN ├── net.py ├── data_generator.py ├── tcnn_test.py └── tcnn_train.py └── FB-tCNN ├── data_generator.py ├── net.py ├── FB-tCNN_test.py └── FB-tCNN_train.py /README.md: -------------------------------------------------------------------------------- 1 | # FB-tCNN for SSVEP Classification 2 | Here are the codes of the tCNN and FB-tCNN in the paper "[Filter Bank Convolutional Neural Network for Short Time-Window Steady-State Visual Evoked Potential Classification](https://ieeexplore.ieee.org/document/9632600)"(DOI:10.1109/TNSRE.2021.3132162). 3 | ## The related version information 4 | 1. Python == 3.7.0 5 | 2. Keras-gpu == 2.3.1 6 | 3. tensorflow-gpu == 2.1.0 7 | 4. scipy == 1.5.2 8 | 5. numpy == 1.19.2 9 | ## Training FB-tCNN for the public dataset 10 | 1. Download the code. 11 | 2. Download the [public dataset](http://gigadb.org/dataset/100542) and its [paper](https://academic.oup.com/gigascience/article/8/5/giz002/5304369). 12 | 3. Create a model folder to save the model. 13 | 4. Change the data and model folder paths in train and test files to your data and model folder paths. 14 | ## Training FB-tCNN for your own dataset 15 | 1. You need to design a new filter bank according to your dataset (Fundamental range of the SSVEP-EEG data). The filter bank details can refer to our paper. 16 | 2. The number of the sub-filters in the codes may be changed according to your own dataset. 17 | 3. The frequency of the target in the codes should be changed according to your own dataset. 18 | 4. The program that reads the data needs to be modified according to your own dataset. 19 | -------------------------------------------------------------------------------- /tCNN/net.py: -------------------------------------------------------------------------------- 1 | from keras import regularizers 2 | from keras.layers import Conv2D,BatchNormalization,Dense,Activation,Dropout,Flatten 3 | 4 | # Setting hyper-parameters 5 | k = 4 6 | L=regularizers.l2(0.01) 7 | drop_out = 0.4 8 | out_channel = 16 9 | activation = 'elu' 10 | 11 | # the network of the tCNN 12 | def tcnn_net(inputs): 13 | # the first convolution layer 14 | x = Conv2D(out_channel,kernel_size = (9, 1),strides = 1,padding = 'valid',kernel_regularizer = L)(inputs) 15 | x = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x) 16 | x = Activation(activation)(x) 17 | # the second convolution layer 18 | x = Dropout(drop_out)(x) 19 | x = Conv2D(out_channel,kernel_size = (1, inputs.shape[2]),strides = 5,padding = 'same', kernel_regularizer = L)(x) 20 | x = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x) 21 | x = Activation(activation)(x) 22 | # the third convolution layer 23 | x = Dropout(drop_out)(x) 24 | x = Conv2D(out_channel,kernel_size = (1, 5),strides = 1,padding = 'valid', kernel_regularizer = L)(x)#(None, 1, 25, 8) dtype=float32> 25 | x = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x) 26 | x = Activation(activation)(x) 27 | # the fourth convolution layer 28 | x = Dropout(drop_out)(x) 29 | x = Conv2D(32,kernel_size = (1, x.shape[2]),strides = 1,padding = 'valid', kernel_regularizer = L)(x) 30 | x = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x) 31 | x = Activation(activation)(x) 32 | # flentten used to reduce the dimension of the features 33 | x = Flatten()(x) 34 | 35 | x = Dropout(drop_out)(x) 36 | # the fully connected layer and "softmax" 37 | x = Dense(k,activation='softmax')(x) 38 | 39 | return x 40 | -------------------------------------------------------------------------------- /tCNN/data_generator.py: -------------------------------------------------------------------------------- 1 | from random import sample 2 | import random 3 | import numpy as np 4 | import keras 5 | 6 | # get the training sampels 7 | def train_datagenerator(batchsize,train_data,win_train,y_label, start_time, down_sample,train_list, channel): 8 | while True: 9 | x_train, y_train = list(range(batchsize)), list(range(batchsize)) 10 | # get training samples of batchsize trials 11 | for i in range(batchsize): 12 | # randomly selecting the single-trial 13 | k = sample(train_list, 1)[0] 14 | # get the label of the single-trial 15 | y_data = y_label[k]-1 16 | # randomly selecting a single-sample in the single-trial, 35 is the frames of the delay-time, 1000 frames is the data range we used 17 | time_start = random.randint(35,int(1000+35-win_train)) 18 | x1 = int(start_time[k]/down_sample)+time_start 19 | x2 = int(start_time[k]/down_sample)+time_start+win_train 20 | x_1 = train_data[:,x1:x2] 21 | x_2 = np.reshape(x_1,(channel, win_train, 1)) 22 | x_train[i]=x_2 23 | y_train[i] = keras.utils.to_categorical(y_data, num_classes=4, dtype='float32') 24 | x_train = np.reshape(x_train,(batchsize,channel, win_train, 1)) 25 | y_train = np.reshape(y_train,(batchsize,4)) 26 | 27 | yield x_train, y_train 28 | 29 | # get the validation samples 30 | def val_datagenerator(batchsize,train_data,win_train,y_label, start_time, down_sample,val_list, channel): 31 | while True: 32 | x_train, y_train = list(range(batchsize)), list(range(batchsize)) 33 | for i in range(batchsize): 34 | k = sample(val_list, 1)[0] 35 | y_data = y_label[k]-1 36 | time_start = random.randint(35,int(1000+35-win_train)) 37 | x1 = int(start_time[k]/down_sample)+time_start 38 | x2 = int(start_time[k]/down_sample)+time_start+win_train 39 | x_1 = train_data[:,x1:x2] 40 | x_2 = np.reshape(x_1,(channel, win_train, 1)) 41 | x_train[i]=x_2 42 | y_train[i] = keras.utils.to_categorical(y_data, num_classes=4, dtype='float32') 43 | x_train = np.reshape(x_train,(batchsize,channel, win_train, 1)) 44 | y_train = np.reshape(y_train,(batchsize,4)) 45 | 46 | yield x_train, y_train 47 | 48 | -------------------------------------------------------------------------------- /FB-tCNN/data_generator.py: -------------------------------------------------------------------------------- 1 | from random import sample 2 | import random 3 | import numpy as np 4 | import keras 5 | 6 | # get the training sampels 7 | def train_datagenerator(batchsize,train_data1,train_data2,train_data3,train_data4,win_train,y_label, start_time, down_sample,tran_list, channel): 8 | while True: 9 | x_train1, x_train2, x_train3, x_train4, y_train = list(range(batchsize)), list(range(batchsize)), list(range(batchsize)), list(range(batchsize)), list(range(batchsize)) 10 | # get training samples of batchsize trials 11 | for i in range(batchsize): 12 | # randomly selecting the single-trial 13 | k = sample(tran_list, 1)[0] 14 | y_data = y_label[k]-1 15 | # randomly selecting a single-sample in the single-trial, 35 is the frames of the delay-time, 1000 frames is data range we used 16 | time_start = random.randint(35,int(1000+35-win_train)) 17 | x1 = int(start_time[k]/down_sample)+time_start 18 | x2 = int(start_time[k]/down_sample)+time_start+win_train 19 | # get four sub-inputs 20 | x_11 = train_data1[:,x1:x2] 21 | x_21 = np.reshape(x_11,(channel, win_train, 1)) 22 | x_train1[i]=x_21 23 | 24 | x_12 = train_data2[:,x1:x2] 25 | x_22 = np.reshape(x_12,(channel, win_train, 1)) 26 | x_train2[i]=x_22 27 | 28 | x_13 = train_data3[:,x1:x2] 29 | x_23 = np.reshape(x_13,(channel, win_train, 1)) 30 | x_train3[i]=x_23 31 | 32 | x_14 = train_data4[:,x1:x2] 33 | x_24 = np.reshape(x_14,(channel, win_train, 1)) 34 | x_train4[i]=x_24 35 | 36 | y_train[i] = keras.utils.to_categorical(y_data, num_classes=4, dtype='float32') 37 | 38 | x_train1 = np.reshape(x_train1,(batchsize,channel, win_train, 1)) 39 | x_train2 = np.reshape(x_train2,(batchsize,channel, win_train, 1)) 40 | x_train3 = np.reshape(x_train3,(batchsize,channel, win_train, 1)) 41 | x_train4 = np.reshape(x_train4,(batchsize,channel, win_train, 1)) 42 | # concatenate the four sub-inputs into one input to make it can be as the input of the FB-tCNN's network 43 | x_train = np.concatenate((x_train1, x_train2, x_train3, x_train4), axis=-1) 44 | y_train = np.reshape(y_train,(batchsize,4)) 45 | 46 | yield x_train, y_train 47 | 48 | # get the validation samples 49 | def val_datagenerator(batchsize,train_data1,train_data2,train_data3,train_data4,win_train,y_label, start_time, down_sample,val_list, channel): 50 | while True: 51 | x_train1, x_train2, x_train3, x_train4, y_train = list(range(batchsize)), list(range(batchsize)), list(range(batchsize)), list(range(batchsize)), list(range(batchsize)) 52 | for i in range(batchsize): 53 | k = sample(val_list, 1)[0] 54 | y_data = y_label[k]-1 55 | time_start = random.randint(35,int(1000+35-win_train)) 56 | x1 = int(start_time[k]/down_sample)+time_start 57 | x2 = int(start_time[k]/down_sample)+time_start+win_train 58 | 59 | x_11 = train_data1[:,x1:x2] 60 | x_21 = np.reshape(x_11,(channel, win_train, 1)) 61 | x_train1[i]=x_21 62 | 63 | x_12 = train_data2[:,x1:x2] 64 | x_22 = np.reshape(x_12,(channel, win_train, 1)) 65 | x_train2[i]=x_22 66 | 67 | x_13 = train_data3[:,x1:x2] 68 | x_23 = np.reshape(x_13,(channel, win_train, 1)) 69 | x_train3[i]=x_23 70 | 71 | x_14 = train_data4[:,x1:x2] 72 | x_24 = np.reshape(x_14,(channel, win_train, 1)) 73 | x_train4[i]=x_24 74 | 75 | y_train[i] = keras.utils.to_categorical(y_data, num_classes=4, dtype='float32') 76 | x_train1 = np.reshape(x_train1,(batchsize,channel, win_train, 1)) 77 | x_train2 = np.reshape(x_train2,(batchsize,channel, win_train, 1)) 78 | x_train3 = np.reshape(x_train3,(batchsize,channel, win_train, 1)) 79 | x_train4 = np.reshape(x_train4,(batchsize,channel, win_train, 1)) 80 | x_train = np.concatenate((x_train1, x_train2, x_train3, x_train4), axis=-1) 81 | y_train = np.reshape(y_train,(batchsize,4)) 82 | 83 | yield x_train, y_train 84 | 85 | 86 | -------------------------------------------------------------------------------- /FB-tCNN/net.py: -------------------------------------------------------------------------------- 1 | from keras import regularizers 2 | import keras 3 | from keras.layers import Conv2D,BatchNormalization,Dense,Activation,Dropout,Flatten,GlobalMaxPooling2D,Lambda#,regularizers#GlobalMaxPooling2D 4 | 5 | # Setting hyper-parameters 6 | k = 4 7 | L=regularizers.l2(0.01) 8 | channel =9 9 | lenth = 5 10 | drop_out = 0.4 11 | out_channel = 16 12 | 13 | # Slice the input concatenated in data_generator to restore it to four sub-inputs 14 | def slice_(x,index): 15 | return x[:,:,:,index] 16 | 17 | activation = 'elu' 18 | def fbtcnn_net(inputs): 19 | # Slice the input concatenated in data_generator to restore it to four sub-inputs 20 | inputs1 = Lambda(slice_,arguments={'index':0})(inputs) 21 | inputs1 = keras.layers.core.Reshape((inputs1.shape[1],inputs1.shape[2],1))(inputs1) 22 | inputs2 = Lambda(slice_,arguments={'index':1})(inputs) 23 | inputs2 = keras.layers.core.Reshape((inputs2.shape[1],inputs2.shape[2],1))(inputs2) 24 | inputs3 = Lambda(slice_,arguments={'index':2})(inputs) 25 | inputs3 = keras.layers.core.Reshape((inputs3.shape[1],inputs3.shape[2],1))(inputs3) 26 | inputs4 = Lambda(slice_,arguments={'index':3})(inputs) 27 | inputs4 = keras.layers.core.Reshape((inputs4.shape[1],inputs4.shape[2],1))(inputs4) 28 | #%% share the weights of the sub-inputs' three convolution layers 29 | conv_1 = Conv2D(out_channel,kernel_size = (channel, 1),strides = 1,padding = 'valid',kernel_regularizer = L) 30 | conv_2 = Conv2D(out_channel,kernel_size = (1, inputs.shape[2]),strides = 5,padding = 'same', kernel_regularizer = L) 31 | conv_3 = Conv2D(out_channel,kernel_size = (1, lenth),strides = 1,padding = 'valid', kernel_regularizer = L) 32 | #%% one sub-branch 33 | # the first shared convolution layer 34 | x1 = conv_1(inputs1) 35 | x1 = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x1) 36 | x1 = Activation(activation)(x1) 37 | # the second shared convolution layer 38 | x1 = Dropout(drop_out)(x1) 39 | x1 = conv_2(x1) 40 | x1 = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x1) 41 | x1 = Activation(activation)(x1) 42 | # the third shared convolution layer 43 | x1 = Dropout(drop_out)(x1) 44 | x1 = conv_3(x1) 45 | x1 = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x1) 46 | x1 = Activation(activation)(x1) 47 | #%% one sub-branch 48 | x2 = conv_1(inputs2) 49 | x2 = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x2) 50 | x2 = Activation(activation)(x2) 51 | 52 | x2 = Dropout(drop_out)(x2) 53 | x2 = conv_2(x2) 54 | x2 = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x2) 55 | x2 = Activation(activation)(x2) 56 | 57 | x2 = Dropout(drop_out)(x2) 58 | x2 = conv_3(x2) 59 | x2 = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x2) 60 | x2 = Activation(activation)(x2) 61 | #%% one sub-branch 62 | x3 = conv_1(inputs3) 63 | x3 = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x3) 64 | x3 = Activation(activation)(x3) 65 | 66 | x3 = Dropout(drop_out)(x3) 67 | x3 = conv_2(x3) 68 | x3 = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x3) 69 | x3 = Activation(activation)(x3) 70 | 71 | x3 = Dropout(drop_out)(x3) 72 | x3 = conv_3(x3) 73 | x3 = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x3) 74 | x3 = Activation(activation)(x3) 75 | #%% one sub-branch 76 | x4 = conv_1(inputs4) 77 | x4 = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x4) 78 | x4 = Activation(activation)(x4) 79 | 80 | x4 = Dropout(drop_out)(x4) 81 | x4 = conv_2(x4) 82 | x4 = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x4) 83 | x4 = Activation(activation)(x4) 84 | 85 | x4 = Dropout(drop_out)(x4) 86 | x4 = conv_3(x4) 87 | x4 = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x4) 88 | x4 = Activation(activation)(x4) 89 | #%% the four sub-features are fused (added) 90 | x = keras.layers.add([x1, x2, x3, x4]) 91 | # the fourth convolution layer 92 | x = Dropout(drop_out)(x) 93 | x = Conv2D(32,kernel_size = (1, x.shape[2]),strides = 1,padding = 'valid', kernel_regularizer = L)(x) 94 | x = BatchNormalization(axis = -1,momentum = 0.99,epsilon=0.001)(x) 95 | x = Activation(activation)(x) 96 | # flentten used to reduce the dimension of the features 97 | x = Flatten()(x) 98 | # the fully connected layer and "softmax" 99 | x = Dropout(drop_out)(x) 100 | x = Dense(k,activation='softmax')(x)#shape=(None, 1, 1, 4) 101 | 102 | return x 103 | -------------------------------------------------------------------------------- /tCNN/tcnn_test.py: -------------------------------------------------------------------------------- 1 | import keras 2 | from keras.models import load_model 3 | import scipy.io as scio 4 | import random 5 | import numpy as np 6 | from scipy import signal 7 | import os 8 | 9 | # generating the test samples, more details refer to data_generator 10 | def datagenerator(batchsize,train_data,win_train,y_lable, start_time,down_sample, channel): 11 | x_train, y_train = list(range(batchsize)), list(range(batchsize)) 12 | for i in range(batchsize): 13 | k = random.randint(0,(y_lable.shape[0]-1)) 14 | y_data = y_lable[k]-1 15 | time_start = random.randint(35,int(1000+35-win_train)) 16 | x1 = int(start_time[k]/down_sample)+time_start 17 | x2 = int(start_time[k]/down_sample)+time_start+win_train 18 | x_1 = train_data[:,x1:x2] 19 | x_2 = np.reshape(x_1,(channel, win_train, 1)) 20 | x_train[i]=x_2 21 | y_train[i] = keras.utils.to_categorical(y_data, num_classes=4, dtype='float32') 22 | x_train = np.reshape(x_train,(batchsize,channel, win_train, 1)) 23 | y_train = np.reshape(y_train,(batchsize,4)) 24 | return x_train, y_train 25 | 26 | # get the filtered EEG-data, label and the start time of each trial of the dataset (test set), more details refer to the "get_train_data" in "tCNN_train" 27 | def get_test_data(wn1,wn2,path='D:/dwl/data/SSVEP_5.6/sess01_subj02_EEG_SSVEP.mat', down_sample=4): 28 | data = scio.loadmat(path) 29 | x_data = data['EEG_SSVEP_test']['x'][0][0][::down_sample,] 30 | c = [24, 28, 29, 30, 41, 42, 43, 60, 61] 31 | train_data = x_data[:,c] 32 | train_label = data['EEG_SSVEP_test']['y_dec'][0][0][0] 33 | train_start_time = data['EEG_SSVEP_test']['t'][0][0][0] 34 | 35 | channel_data_list = [] 36 | for i in range(train_data.shape[1]): 37 | b, a = signal.butter(6, [wn1,wn2], 'bandpass') 38 | filtedData = signal.filtfilt(b, a, train_data[:,i]) 39 | channel_data_list.append(filtedData) 40 | channel_data_list = np.array(channel_data_list) 41 | return channel_data_list, train_label, train_start_time 42 | 43 | if __name__ == '__main__': 44 | os.environ['CUDA_VISIBLE_DEVICES'] = "0,1" 45 | # Setting hyper-parameters, more details refer to "tCNN_train" 46 | down_sample = 4 47 | fs = 1000/down_sample 48 | channel = 9 49 | train_epoch = 100 50 | batchsize = 1000 51 | f_down = 3 52 | f_up = 50 53 | wn1 = 2*f_down/fs 54 | wn2 = 2*f_up/fs 55 | 56 | total_av_acc_list = [] 57 | t_train_list = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0] 58 | for sub_selelct in range(1, 10): 59 | # the path of the dataset and you need to change it for your test 60 | path = 'D:/dwl/data/SSVEP_5.6/sess01/sess01_subj0%d_EEG_SSVEP.mat'%sub_selelct 61 | # get the filtered EEG-data, label and the start time of all trials of the test data 62 | test_data, test_label, test_start_time = get_test_data(wn1, wn2, path, down_sample) 63 | av_acc_list = [] 64 | for t_train in t_train_list: 65 | win_train = int(fs*t_train) 66 | # the path of the tCNN's model and you need to change it 67 | model_path = 'D:/dwl/github_code/FB-tCNN_and_tCNN_code/tCNN/model/model_0.1_%3.1fs_0%d.h5'%(t_train, sub_selelct) 68 | # load the model 69 | model = load_model(model_path) 70 | print("load successed") 71 | print(t_train, sub_selelct) 72 | acc_list = [] 73 | # test 5 times and get the average accrucy of the 5 times as the test result, here you can only test once 74 | for j in range(5): 75 | # get the filtered EEG-data, label and the start time of the test samples, and the number of the samples is "batchsize" 76 | x_train,y_train = datagenerator(batchsize, test_data, win_train, test_label, test_start_time, down_sample, channel) 77 | a, b = 0, 0 78 | # get the predicted results of the batchsize test samples 79 | y_pred = model.predict(np.array(x_train)) 80 | true, pred = [], [] 81 | y_true = y_train 82 | # Calculating the accuracy of current time 83 | for i in range (batchsize-1): 84 | y_pred_ = np.argmax(y_pred[i]) 85 | pred.append(y_pred_) 86 | y_true1 = np.argmax(y_train[i]) 87 | true.append(y_true1) 88 | if y_true1 == y_pred_: 89 | a += 1 90 | else: 91 | b += 1 92 | acc = a/(a+b) 93 | acc_list.append(acc) 94 | av_acc = np.mean(acc_list) 95 | print(av_acc) 96 | av_acc_list.append(av_acc) 97 | total_av_acc_list.append(av_acc_list) 98 | 99 | # the rest of the test subjects, you maybe not need this part for your own dataset 100 | for sub_selelct in range(10, 55): 101 | path = 'D:/dwl/data/SSVEP_5.6/sess01/sess01_subj%d_EEG_SSVEP.mat'%sub_selelct 102 | test_data, test_label, test_start_time = get_test_data(wn1, wn2, path, down_sample) 103 | av_acc_list = [] 104 | for t_train in t_train_list: 105 | win_train = int(fs*t_train) 106 | model_path = 'D:/dwl/github_code/FB-tCNN_and_tCNN_code/tCNN/model/model_0.1_%3.1fs_%d.h5'%(t_train, sub_selelct) 107 | model = load_model(model_path) 108 | print("load successed") 109 | print(t_train, sub_selelct) 110 | acc_list = [] 111 | for j in range(5): 112 | x_train,y_train = datagenerator(batchsize, test_data, win_train, test_label, test_start_time, down_sample, channel)#, t_train) 113 | a, b = 0, 0 114 | y_pred = model.predict(np.array(x_train)) 115 | true, pred = [], [] 116 | y_true = y_train 117 | for i in range (batchsize-1): 118 | y_pred_ = np.argmax(y_pred[i]) 119 | pred.append(y_pred_) 120 | y_true1 = np.argmax(y_train[i]) 121 | true.append(y_true1) 122 | if y_true1 == y_pred_: 123 | a += 1 124 | else: 125 | b+= 1 126 | acc = a/(a+b) 127 | acc_list.append(acc) 128 | av_acc = np.mean(acc_list) 129 | print(av_acc) 130 | av_acc_list.append(av_acc) 131 | total_av_acc_list.append(av_acc_list) 132 | 133 | 134 | # # save the results 135 | # print(total_av_acc_list) 136 | # company_name_list = total_av_acc_list 137 | # df = pd.DataFrame(company_name_list) 138 | # df.to_excel("D:/dwl/results_0.1/public/tcnn/sess01_to_02/tcnn_9channel_sess01_to_02.xlsx", index=False) 139 | -------------------------------------------------------------------------------- /tCNN/tcnn_train.py: -------------------------------------------------------------------------------- 1 | from keras.callbacks import ModelCheckpoint 2 | from net import tcnn_net 3 | import data_generator 4 | import scipy.io as scio 5 | from scipy import signal 6 | from keras.models import Model 7 | from keras.layers import Input 8 | import numpy as np 9 | from random import sample 10 | import os 11 | 12 | # get the filtered EEG-data, label and the start time of each trial of the dataset 13 | def get_train_data(wn1, wn2, path, down_sample): 14 | # read the data 15 | data = scio.loadmat(path) 16 | # get the EEG-data of the selected electrodes and downsampling it 17 | x_data = data['EEG_SSVEP_train']['x'][0][0][::down_sample,] 18 | c = [24, 28, 29, 30, 41, 42, 43, 60, 61] 19 | train_data = x_data[:,c] 20 | # get the label and onset time of each trial 21 | train_label = data['EEG_SSVEP_train']['y_dec'][0][0][0] 22 | train_start_time = data['EEG_SSVEP_train']['t'][0][0][0] 23 | # filtering the EEG-data with six-order Butterworth filter 24 | channel_data_list = [] 25 | for i in range(train_data.shape[1]): 26 | b, a = signal.butter(6, [wn1,wn2], 'bandpass') 27 | filtedData = signal.filtfilt(b, a, train_data[:,i]) 28 | channel_data_list.append(filtedData) 29 | channel_data_list = np.array(channel_data_list) 30 | 31 | return channel_data_list, train_label, train_start_time 32 | 33 | if __name__ == '__main__': 34 | # open the GPU 35 | os.environ['CUDA_VISIBLE_DEVICES'] = "0,1" 36 | #%% Setting hyper-parameters 37 | # downsampling coefficient and sampling frequency after downsampling 38 | down_sample = 4 39 | fs = 1000/down_sample 40 | # the number of the electrode channels 41 | channel = 9 42 | # the hyper-parameters of the training process 43 | train_epoch = 400 44 | batchsize = 256 45 | # the filter range 46 | f_down = 3 47 | f_up = 50 48 | wn1 = 2*f_down/fs 49 | wn2 = 2*f_up/fs 50 | #%% Training the models of multi-subjects and multi-time-window 51 | # the list of the time-window 52 | t_train_list = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0] 53 | # selecting the training subject 54 | for sub_selelct in range(1, 10): 55 | # the path of the dataset and you need to change it for your training 56 | path='D:/dwl/data/SSVEP_5.6/sess01/sess01_subj0%d_EEG_SSVEP.mat'%sub_selelct 57 | # get the filtered EEG-data, label and the start time of all trials of the training data 58 | data, label, start_time = get_train_data(wn1,wn2,path,down_sample) 59 | # selecting the training time-window 60 | for t_train in t_train_list: 61 | # transfer time to frame 62 | win_train = int(fs*t_train) 63 | # the traing data is randomly divided in the traning dataset and validation set according to the radio of 9:1 64 | train_list = list(range(100)) 65 | val_list = sample(train_list, 10) 66 | train_list = [train_list[i] for i in range(len(train_list)) if (i not in val_list)] 67 | # data generator (generate the training and validation samples of batchsize trials) 68 | train_gen = data_generator.train_datagenerator(batchsize,data,win_train,label, start_time, down_sample,train_list, channel) 69 | val_gen = data_generator.val_datagenerator(batchsize,data,win_train,label, start_time, down_sample,val_list, channel) 70 | #%% setting the input of the network 71 | input_shape = (channel, win_train, 1) 72 | input_tensor = Input(shape=input_shape) 73 | preds = tcnn_net(input_tensor) 74 | model = Model(input_tensor, preds) 75 | # the path of the saved model and you need to change it 76 | model_path = 'D:/dwl/github_code/FB-tCNN_and_tCNN_code/tCNN/model/model_0.1_%3.1fs_0%d.h5'%(t_train, sub_selelct) 77 | # some hyper-parameters in the training process 78 | model_checkpoint = ModelCheckpoint(model_path, monitor='val_loss',verbose=1, save_best_only=True,mode='auto') 79 | model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) 80 | # training 81 | history = model.fit_generator( 82 | train_gen, 83 | steps_per_epoch= 10, 84 | epochs=train_epoch, 85 | validation_data=val_gen, 86 | validation_steps=1, 87 | callbacks=[model_checkpoint] 88 | ) 89 | print(t_train,sub_selelct) 90 | 91 | #%% the rest of the training subjects, you maybe not need this part for your own dataset 92 | for sub_selelct in range(10, 55): 93 | path='D:/dwl/data/SSVEP_5.6/sess01/sess01_subj%d_EEG_SSVEP.mat'%sub_selelct 94 | data, label, start_time = get_train_data(wn1,wn2,path,down_sample) 95 | 96 | for t_train in t_train_list: 97 | win_train = int(fs*t_train) 98 | train_list = list(range(100)) 99 | val_list = sample(train_list, 10) 100 | train_list = [train_list[i] for i in range(len(train_list)) if (train_list[i] not in val_list)] 101 | train_gen = data_generator.train_datagenerator(batchsize,data,win_train,label, start_time, down_sample,train_list, channel) 102 | val_gen = data_generator.val_datagenerator(batchsize,data,win_train,label, start_time, down_sample,val_list, channel) 103 | input_shape = (channel, win_train, 1) 104 | input_tensor = Input(shape=input_shape) 105 | preds = tcnn_net(input_tensor) 106 | model = Model(input_tensor, preds) 107 | model_path = 'D:/dwl/github_code/FB-tCNN_and_tCNN_code/tCNN/model/model_0.1_%3.1fs_%d.h5'%(t_train, sub_selelct) 108 | model_checkpoint = ModelCheckpoint(model_path, monitor='val_loss',verbose=1, save_best_only=True,mode='auto') 109 | model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) 110 | history = model.fit_generator( 111 | train_gen, 112 | steps_per_epoch= 10, 113 | epochs=train_epoch, 114 | validation_data=val_gen, 115 | validation_steps=1, 116 | callbacks=[model_checkpoint] 117 | ) 118 | print(t_train,sub_selelct) 119 | 120 | 121 | 122 | # # show the process of the training 123 | # epochs=range(len(history.history['loss'])) 124 | # plt.subplot(221) 125 | # plt.plot(epochs,history.history['accuracy'],'b',label='Training acc') 126 | # plt.plot(epochs,history.history['val_accuracy'],'r',label='Validation acc') 127 | # plt.title('Traing and Validation accuracy') 128 | # plt.legend() 129 | # # plt.savefig('D:/dwl/code_ssvep/DL/cross_session/m_coyy/photo/model_V3.1_acc1.jpg') 130 | 131 | # plt.subplot(222) 132 | # plt.plot(epochs,history.history['loss'],'b',label='Training loss') 133 | # plt.plot(epochs,history.history['val_loss'],'r',label='Validation val_loss') 134 | # plt.title('Traing and Validation loss') 135 | # plt.legend() 136 | # # plt.savefig('D:/dwl/code_ssvep/DL/cross_session/m_coyy/photo/model_2.5s_loss0%d.jpg'%sub_selelct) 137 | 138 | # plt.show() 139 | 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /FB-tCNN/FB-tCNN_test.py: -------------------------------------------------------------------------------- 1 | import keras 2 | from keras.models import load_model 3 | import scipy.io as scio 4 | import random 5 | import numpy as np 6 | from scipy import signal 7 | import os 8 | os.environ['CUDA_VISIBLE_DEVICES'] = "0,1" 9 | 10 | # generating the test samples, more details refer to data_generator 11 | def datagenerator(batchsize,train_data1,train_data2,train_data3,train_data4,win_train,y_lable, start_time, down_sample, channel): 12 | x_train1, x_train2, x_train3, x_train4, y_train = list(range(batchsize)), list(range(batchsize)), list(range(batchsize)), list(range(batchsize)), list(range(batchsize)) 13 | for i in range(batchsize): 14 | k = random.randint(0,(y_lable.shape[0]-1)) 15 | y_data = y_lable[k]-1 16 | time_start = random.randint(35,int(1000+35-win_train)) 17 | x1 = int(start_time[k]/down_sample)+time_start 18 | x2 = int(start_time[k]/down_sample)+time_start+win_train 19 | 20 | x_11 = train_data1[:,x1:x2] 21 | x_21 = np.reshape(x_11,(channel, win_train, 1)) 22 | x_train1[i]=x_21 23 | 24 | x_12 = train_data2[:,x1:x2] 25 | x_22 = np.reshape(x_12,(channel, win_train, 1)) 26 | x_train2[i]=x_22 27 | 28 | x_13 = train_data3[:,x1:x2] 29 | x_23 = np.reshape(x_13,(channel, win_train, 1)) 30 | x_train3[i]=x_23 31 | 32 | x_14 = train_data4[:,x1:x2] 33 | x_24 = np.reshape(x_14,(channel, win_train, 1)) 34 | x_train4[i]=x_24 35 | 36 | y_train[i] = keras.utils.to_categorical(y_data, num_classes=4, dtype='float32') 37 | x_train1 = np.reshape(x_train1,(batchsize,channel, win_train, 1)) 38 | x_train2 = np.reshape(x_train2,(batchsize,channel, win_train, 1)) 39 | x_train3 = np.reshape(x_train3,(batchsize,channel, win_train, 1)) 40 | x_train4 = np.reshape(x_train4,(batchsize,channel, win_train, 1)) 41 | x_train = np.concatenate((x_train1, x_train2, x_train3, x_train4), axis=-1) 42 | y_train = np.reshape(y_train,(batchsize,4)) 43 | return x_train, y_train 44 | 45 | # get the filtered EEG-data, label and the start time of each trial of the dataset (test set), more details refer to the "get_train_data" in "FB-tCNN_train" 46 | def get_test_data(wn11,wn21,wn12,wn22,wn13,wn23,wn14,wn24,path='D:/dwl/data/SSVEP_5.6/sess01_subj02_EEG_SSVEP.mat', down_sample=4): 47 | data = scio.loadmat(path) 48 | x_data = data['EEG_SSVEP_test']['x'][0][0][::down_sample,] 49 | c = [24, 28, 29, 30, 41, 42, 43, 60, 61] 50 | train_data = x_data[:,c] 51 | train_label = data['EEG_SSVEP_test']['y_dec'][0][0][0] 52 | train_start_time = data['EEG_SSVEP_test']['t'][0][0][0] 53 | 54 | channel_data_list1 = [] 55 | for i in range(train_data.shape[1]): 56 | b, a = signal.butter(6, [wn11,wn21], 'bandpass') 57 | filtedData = signal.filtfilt(b, a, train_data[:,i]) 58 | channel_data_list1.append(filtedData) 59 | channel_data_list1 = np.array(channel_data_list1) 60 | 61 | channel_data_list2 = [] 62 | for i in range(train_data.shape[1]): 63 | b, a = signal.butter(6, [wn12,wn22], 'bandpass') 64 | filtedData = signal.filtfilt(b, a, train_data[:,i]) 65 | channel_data_list2.append(filtedData) 66 | channel_data_list2 = np.array(channel_data_list2) 67 | 68 | channel_data_list3 = [] 69 | for i in range(train_data.shape[1]): 70 | b, a = signal.butter(6, [wn13,wn23], 'bandpass') 71 | filtedData = signal.filtfilt(b, a, train_data[:,i]) 72 | channel_data_list3.append(filtedData) 73 | channel_data_list3 = np.array(channel_data_list3) 74 | 75 | channel_data_list4 = [] 76 | for i in range(train_data.shape[1]): 77 | b, a = signal.butter(6, [wn14,wn24], 'bandpass') 78 | filtedData = signal.filtfilt(b, a, train_data[:,i]) 79 | channel_data_list4.append(filtedData) 80 | channel_data_list4 = np.array(channel_data_list4) 81 | 82 | return channel_data_list1, channel_data_list2, channel_data_list3, channel_data_list4, train_label, train_start_time 83 | 84 | if __name__ == '__main__': 85 | os.environ['CUDA_VISIBLE_DEVICES'] = "0,1" 86 | # Setting hyper-parameters, more details refer to "FB-tCNN_train" 87 | down_sample = 4 88 | fs = 1000/down_sample 89 | channel = 9 90 | 91 | batchsize = 1000 92 | f_down1 = 3 93 | f_up1 = 14 94 | wn11 = 2*f_down1/fs 95 | wn21 = 2*f_up1/fs 96 | 97 | f_down2 = 9 98 | f_up2 = 26 99 | wn12 = 2*f_down2/fs 100 | wn22 = 2*f_up2/fs 101 | 102 | f_down3 = 14 103 | f_up3 = 38 104 | wn13 = 2*f_down3/fs 105 | wn23 = 2*f_up3/fs 106 | 107 | f_down4 = 19 108 | f_up4 = 50 109 | wn14 = 2*f_down4/fs 110 | wn24 = 2*f_up4/fs 111 | 112 | total_av_acc_list = [] 113 | t_train_list = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0] 114 | for sub_selelct in range(1, 10): 115 | # the path of the dataset and you need to change it for your test 116 | path = 'D:/dwl/data/SSVEP_5.6/sess01/sess01_subj0%d_EEG_SSVEP.mat'%sub_selelct 117 | # get the filtered EEG-data of the four sub-filters, label and the start time of all trials of the test data 118 | data1, data2, data3, data4, label, start_time = get_test_data(wn11,wn21,wn12,wn22,wn13,wn23,wn14,wn24,path,down_sample) 119 | av_acc_list = [] 120 | for t_train in t_train_list: 121 | win_train = int(fs*t_train) 122 | # the path of the FB-tCNN's model and you need to change it 123 | model_path = 'D:/dwl/github_code/FB-tCNN_and_tCNN_code/FB-tCNN/model/model_%3.1fs_0%d.h5'%(t_train, sub_selelct) 124 | model = load_model(model_path) 125 | print("load successed") 126 | print(t_train, sub_selelct) 127 | acc_list = [] 128 | # test 5 times and get the average accrucy of the 5 times as the test result, here you can only test once 129 | for j in range(5): 130 | # get the filtered EEG-data, label and the start time of the test samples, and the number of the samples is "batchsize" 131 | x_train,y_train = datagenerator(batchsize,data1, data2, data3, data4,win_train,label, start_time, down_sample, channel) 132 | a, b = 0, 0 133 | y_pred = model.predict(np.array(x_train)) 134 | true, pred = [], [] 135 | y_true = y_train 136 | # Calculating the accuracy of current time 137 | for i in range (batchsize-1): 138 | y_pred_ = np.argmax(y_pred[i]) 139 | pred.append(y_pred_) 140 | y_true1 = np.argmax(y_train[i]) 141 | true.append(y_true1) 142 | if y_true1 == y_pred_: 143 | a += 1 144 | else: 145 | b+= 1 146 | acc = a/(a+b) 147 | acc_list.append(acc) 148 | av_acc = np.mean(acc_list) 149 | print(av_acc) 150 | av_acc_list.append(av_acc) 151 | total_av_acc_list.append(av_acc_list) 152 | 153 | # the rest of the test subjects, you maybe not need this part for your own dataset 154 | for sub_selelct in range(10, 55): 155 | path = 'D:/dwl/data/SSVEP_5.6/sess01/sess01_subj%d_EEG_SSVEP.mat'%sub_selelct 156 | data1, data2, data3, data4, label, start_time = get_test_data(wn11,wn21,wn12,wn22,wn13,wn23,wn14,wn24,path,down_sample) 157 | av_acc_list = [] 158 | for t_train in t_train_list: 159 | win_train = int(fs*t_train) 160 | model_path = 'D:/dwl/github_code/FB-tCNN_and_tCNN_code/FB-tCNN/model/model_%3.1fs_%d.h5'%(t_train, sub_selelct) 161 | model = load_model(model_path) 162 | print("load successed") 163 | print(t_train, sub_selelct) 164 | acc_list = [] 165 | for j in range(5): 166 | x_train,y_train = datagenerator(batchsize,data1, data2, data3, data4,win_train,label, start_time, down_sample, channel) 167 | a, b = 0, 0 168 | y_pred = model.predict(np.array(x_train)) 169 | true, pred = [], [] 170 | y_true = y_train 171 | for i in range (batchsize-1): 172 | y_pred_ = np.argmax(y_pred[i]) 173 | pred.append(y_pred_) 174 | y_true1 = np.argmax(y_train[i]) 175 | true.append(y_true1) 176 | if y_true1 == y_pred_: 177 | a += 1 178 | else: 179 | b+= 1 180 | acc = a/(a+b) 181 | acc_list.append(acc) 182 | av_acc = np.mean(acc_list) 183 | print(av_acc) 184 | av_acc_list.append(av_acc) 185 | total_av_acc_list.append(av_acc_list) 186 | 187 | 188 | 189 | # save the results 190 | # print(total_av_acc_list) 191 | # company_name_list = total_av_acc_list 192 | # df = pd.DataFrame(company_name_list) 193 | # df.to_excel("D:/dwl/results_0.1/public/FB-tcnn/sess01_to_02/fbtcnn_9channel_sess01_to_02_try.xlsx", index=False) 194 | -------------------------------------------------------------------------------- /FB-tCNN/FB-tCNN_train.py: -------------------------------------------------------------------------------- 1 | from keras.callbacks import ModelCheckpoint 2 | from net import fbtcnn_net 3 | import data_generator 4 | import scipy.io as scio 5 | from scipy import signal 6 | from keras.models import Model 7 | from keras.layers import Input 8 | import numpy as np 9 | from random import sample 10 | import os 11 | 12 | # get the filtered EEG-data, label and the start time of each trial of the dataset 13 | def get_train_data(wn11,wn21,wn12,wn22,wn13,wn23,wn14,wn24,path='D:/dwl/data/SSVEP_5.6/sess01_subj02_EEG_SSVEP.mat', down_sample=4): 14 | # read the data 15 | data = scio.loadmat(path) 16 | # get the EEG-data of the selected electrodes and downsampling it 17 | x_data = data['EEG_SSVEP_train']['x'][0][0][::down_sample,] 18 | c = [24, 28, 29, 30, 41, 42, 43, 60, 61] 19 | train_data = x_data[:,c] 20 | # get the label and onset time of each trial 21 | train_label = data['EEG_SSVEP_train']['y_dec'][0][0][0] 22 | train_start_time = data['EEG_SSVEP_train']['t'][0][0][0] 23 | # get the filtered EEG-data with six-order Butterworth filter of the first sub-filter 24 | channel_data_list1 = [] 25 | for i in range(train_data.shape[1]): 26 | b, a = signal.butter(6, [wn11,wn21], 'bandpass') 27 | filtedData = signal.filtfilt(b, a, train_data[:,i]) 28 | channel_data_list1.append(filtedData) 29 | channel_data_list1 = np.array(channel_data_list1) 30 | # get the filtered EEG-data with six-order Butterworth filter of the second sub-filter 31 | channel_data_list2 = [] 32 | for i in range(train_data.shape[1]): 33 | b, a = signal.butter(6, [wn12,wn22], 'bandpass') 34 | filtedData = signal.filtfilt(b, a, train_data[:,i]) 35 | channel_data_list2.append(filtedData) 36 | channel_data_list2 = np.array(channel_data_list2) 37 | # get the filtered EEG-data with six-order Butterworth filter of the third sub-filter 38 | channel_data_list3 = [] 39 | for i in range(train_data.shape[1]): 40 | b, a = signal.butter(6, [wn13,wn23], 'bandpass') 41 | filtedData = signal.filtfilt(b, a, train_data[:,i]) 42 | channel_data_list3.append(filtedData) 43 | channel_data_list3 = np.array(channel_data_list3) 44 | # get the filtered EEG-data with six-order Butterworth filter of the fourth sub-filter 45 | channel_data_list4 = [] 46 | for i in range(train_data.shape[1]): 47 | b, a = signal.butter(6, [wn14,wn24], 'bandpass') 48 | filtedData = signal.filtfilt(b, a, train_data[:,i]) 49 | channel_data_list4.append(filtedData) 50 | channel_data_list4 = np.array(channel_data_list4) 51 | 52 | return channel_data_list1, channel_data_list2, channel_data_list3, channel_data_list4, train_label, train_start_time 53 | 54 | if __name__ == '__main__': 55 | # open the GPU 56 | os.environ['CUDA_VISIBLE_DEVICES'] = "0,1" 57 | #%% Setting hyper-parameters 58 | # downsampling coefficient and sampling frequency after downsampling 59 | down_sample=4 60 | fs = 1000/down_sample 61 | # the number of the electrode channels 62 | channel = 9 63 | # the hyper-parameters of the training process 64 | train_epoch = 400 65 | batchsize = 256 66 | 67 | # the filter ranges of the four sub-filters in the filter bank 68 | f_down1 = 3 69 | f_up1 = 14 70 | wn11 = 2*f_down1/fs 71 | wn21 = 2*f_up1/fs 72 | 73 | f_down2 = 9 74 | f_up2 = 26 75 | wn12 = 2*f_down2/fs 76 | wn22 = 2*f_up2/fs 77 | 78 | f_down3 = 14 79 | f_up3 = 38 80 | wn13 = 2*f_down3/fs 81 | wn23 = 2*f_up3/fs 82 | 83 | f_down4 = 19 84 | f_up4 = 50 85 | wn14 = 2*f_down4/fs 86 | wn24 = 2*f_up4/fs 87 | #%% Training the models of multi-subjects and multi-time-window 88 | # the list of the time-window 89 | t_train_list = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0] 90 | # selecting the training subject 91 | for sub_selelct in range(1, 10): 92 | # the path of the dataset and you need change it for your training 93 | path = 'D:/dwl/data/SSVEP_5.6/sess01/sess01_subj0%d_EEG_SSVEP.mat'%sub_selelct 94 | # get the filtered EEG-data of four sub-input, label and the start time of all trials of the training data 95 | data1, data2, data3, data4, label, start_time = get_train_data(wn11,wn21,wn12,wn22,wn13,wn23,wn14,wn24,path,down_sample) 96 | # selecting the training time-window 97 | for t_train in t_train_list: 98 | # transfer time to frame 99 | win_train = int(fs*t_train) 100 | # the traing data is randomly divided in the traning dataset and validation set according to the radio of 9:1 101 | train_list = list(range(100)) 102 | val_list = sample(train_list, 10) 103 | train_list = [train_list[i] for i in range(len(train_list)) if (i not in val_list)] 104 | # data generator (generate the taining and validation samples of batchsize trials) 105 | train_gen = data_generator.train_datagenerator(batchsize,data1, data2, data3, data4,win_train,label, start_time, down_sample,train_list, channel)#, t_train) 106 | val_gen = data_generator.val_datagenerator(batchsize,data1, data2, data3, data4,win_train,label, start_time, down_sample,val_list, channel)#, t_train) 107 | #%% setting the input of the network 108 | input_shape = (channel, win_train, 4) 109 | input_tensor = Input(shape=input_shape) 110 | preds = fbtcnn_net(input_tensor) 111 | model = Model(input_tensor, preds) 112 | # the path of the saved model and you need to change it 113 | model_path = 'D:/dwl/github_code/FB-tCNN_and_tCNN_code/FB-tCNN/model/model_%3.1fs_0%d.h5'%(t_train, sub_selelct) 114 | # some hyper-parameters in the training process 115 | model_checkpoint = ModelCheckpoint(model_path, monitor='val_loss',verbose=1, save_best_only=True,mode='auto') 116 | model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) 117 | # training 118 | history = model.fit_generator( 119 | train_gen, 120 | steps_per_epoch= 10, 121 | epochs=train_epoch, 122 | validation_data=val_gen, 123 | validation_steps=1, 124 | callbacks=[model_checkpoint] 125 | ) 126 | 127 | #%% the rest of the training subjects, you maybe not need this part for your own dataset 128 | for sub_selelct in range(10, 55): 129 | 130 | path = 'D:/dwl/data/SSVEP_5.6/sess01/sess01_subj%d_EEG_SSVEP.mat'%sub_selelct 131 | data1, data2, data3, data4, label, start_time = get_train_data(wn11,wn21,wn12,wn22,wn13,wn23,wn14,wn24,path,down_sample) 132 | 133 | for t_train in t_train_list: 134 | win_train = int(fs*t_train) 135 | train_list = list(range(100)) 136 | val_list = sample(train_list, 10) 137 | train_list = [train_list[i] for i in range(len(train_list)) if (i not in val_list)] 138 | 139 | train_gen = data_generator.train_datagenerator(batchsize,data1, data2, data3, data4,win_train,label, start_time, down_sample,train_list, channel)#, t_train) 140 | val_gen = data_generator.val_datagenerator(batchsize,data1, data2, data3, data4,win_train,label, start_time, down_sample,val_list, channel)#, t_train) 141 | #%% 142 | input_shape = (channel, win_train, 4) 143 | input_tensor = Input(shape=input_shape) 144 | preds = fbtcnn_net(input_tensor) 145 | model = Model(input_tensor, preds) 146 | 147 | model_path = 'D:/dwl/github_code/FB-tCNN_and_tCNN_code/FB-tCNN/model/model_%3.1fs_%d.h5'%(t_train, sub_selelct) 148 | model_checkpoint = ModelCheckpoint(model_path, monitor='val_loss',verbose=1, save_best_only=True,mode='auto') 149 | model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) 150 | 151 | history = model.fit_generator( 152 | train_gen, 153 | steps_per_epoch= 10, 154 | epochs=train_epoch, 155 | validation_data=val_gen, 156 | validation_steps=1, 157 | callbacks=[model_checkpoint] 158 | ) 159 | 160 | 161 | 162 | 163 | 164 | # # show the process of the taining 165 | # epochs=range(len(history.history['loss'])) 166 | # plt.subplot(221) 167 | # plt.plot(epochs,history.history['accuracy'],'b',label='Training acc') 168 | # plt.plot(epochs,history.history['val_accuracy'],'r',label='Validation acc') 169 | # plt.title('Traing and Validation accuracy') 170 | # plt.legend() 171 | # # plt.savefig('D:/dwl/code_ssvep/DL/cross_session/m_coyy/photo/model_V3.1_acc1.jpg') 172 | 173 | # plt.subplot(222) 174 | # plt.plot(epochs,history.history['loss'],'b',label='Training loss') 175 | # plt.plot(epochs,history.history['val_loss'],'r',label='Validation val_loss') 176 | # plt.title('Traing and Validation loss') 177 | # plt.legend() 178 | # # plt.savefig('D:/dwl/code_ssvep/DL/cross_session/m_coyy/photo/model_2.5s_loss0%d.jpg'%sub_selelct) 179 | 180 | # plt.show() 181 | 182 | 183 | 184 | 185 | 186 | --------------------------------------------------------------------------------