├── calculate_DE.m ├── README.md ├── interpolate_grid.m ├── stopIfAccuracyNotImproving.m ├── split_sets_5_fold.m ├── make_eeg_image.m ├── main_project.m └── load_data.m /calculate_DE.m: -------------------------------------------------------------------------------- 1 | function diff_entropy = calculate_DE(signals) 2 | % Author: Kris van Noord 3 | % Eindhoven University of Technology 4 | % 3D-CNN for EEG emotion classification 5 | % Openly available framework 6 | % Scripts verified on Matlab R2019b 7 | 8 | variances = var(signals,1); 9 | diff_entropy = 0.5 * log(2*pi*exp(1)*variances); 10 | end 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 3D-CNN-EEG-Emotion-Classification 2 | Openly available framework for EEG-based emotion classification 3 | 4 | Author: Kris van Noord 5 | Institute: Eindhoven University of Technology 6 | 7 | 3D-CNN for EEG emotion classification 8 | 9 | Openly available framework for research purposes 10 | 11 | 12 | ## Database for Emotion Analysis using Physiological signals 13 | The current framework is applicable to the DEAP dataset. 14 | http://www.eecs.qmul.ac.uk/mmv/datasets/deap/ 15 | 16 | 17 | ## Environment setup 18 | The framework runs on Matlab (verified on R2019B) with the following toolboxes: 19 | 20 | 1. EEGLab 21 | 1. Deep Learning Toolbox 22 | 2. Parallel Computing Toolbox 23 | 24 | To run the full framework, make sure the dataset is in the same folder as the files and run the 'main_project.m' file. 25 | In this file, options (DE/PSD, normalization, etc) can be changed in the first section. 26 | 27 | -------------------------------------------------------------------------------- /interpolate_grid.m: -------------------------------------------------------------------------------- 1 | function interpolated_matrix = interpolate_grid(matrix, steps) 2 | % Author: Kris van Noord 3 | % Eindhoven University of Technology 4 | % 3D-CNN for EEG emotion classification 5 | % Openly available framework 6 | % Scripts verified on Matlab R2019b 7 | 8 | 9 | 10 | % input size should be [subject, trial, segment, width, height, time/frequency] 11 | interpolated_matrix = zeros(size(matrix,1),size(matrix,2),size(matrix, 3), steps,steps,size(matrix, 6)); 12 | [xq, yq] = meshgrid(linspace(1,9,steps)); 13 | for i = 1:size(matrix, 1) 14 | for j = 1:size(matrix, 2) 15 | for n = 1:size(matrix, 3) 16 | for k = 1:size(matrix, 6) 17 | image = reshape(matrix(i,j,n,:,:,k), 9, 9); 18 | [y,x] = find(image ~= 0, 32); 19 | z = reshape(image(image ~= 0), size(x,1), 1); 20 | interpolated_matrix(i,j,n,:,:,k) = griddata(x,y,z,xq,yq); 21 | end 22 | end 23 | end 24 | end 25 | interpolated_matrix(isnan(interpolated_matrix)) = 0; 26 | end 27 | -------------------------------------------------------------------------------- /stopIfAccuracyNotImproving.m: -------------------------------------------------------------------------------- 1 | function stop = stopIfAccuracyNotImproving(info,N) 2 | 3 | stop = false; 4 | 5 | % Keep track of the best validation accuracy and the number of validations for which 6 | % there has not been an improvement of the accuracy. 7 | persistent bestValAccuracy 8 | persistent valLag 9 | 10 | % Clear the variables when training starts. 11 | if info.State == "start" 12 | bestValAccuracy = 0; 13 | valLag = 0; 14 | 15 | elseif ~isempty(info.ValidationLoss) && info.Epoch > 4 16 | 17 | % Compare the current validation accuracy to the best accuracy so far, 18 | % and either set the best accuracy to the current accuracy, or increase 19 | % the number of validations for which there has not been an improvement. 20 | if info.ValidationAccuracy > bestValAccuracy 21 | valLag = 0; 22 | bestValAccuracy = info.ValidationAccuracy; 23 | else 24 | valLag = valLag + 1; 25 | end 26 | 27 | % If the validation lag is at least N, that is, the validation accuracy 28 | % has not improved for at least N validations, then return true and 29 | % stop training. 30 | if valLag >= N 31 | stop = true; 32 | end 33 | 34 | end -------------------------------------------------------------------------------- /split_sets_5_fold.m: -------------------------------------------------------------------------------- 1 | function [training_data, test_data, training_labels, test_labels] = split_sets_5_fold(E_images, labels) 2 | % Author: Kris van Noord 3 | % Eindhoven University of Technology 4 | % 3D-CNN for EEG emotion classification 5 | % Openly available framework 6 | % Scripts verified on Matlab R2019b 7 | 8 | 9 | % Set trials in random order 10 | sequence = randperm(40); 11 | E_images = E_images(sequence,:,:,:,:); 12 | labels = labels(sequence,:); 13 | 14 | % Calculate number of trials 15 | number_of_trials = size(E_images, 1); 16 | 17 | data = zeros(size(E_images,1)*size(E_images,2), size(E_images, 3), size(E_images, 4), size(E_images, 5)); 18 | for i = 1:number_of_trials 19 | data((i-1)*size(E_images,2)+1:i*size(E_images,2),:,:,:) = E_images(i,:,:,:,:); 20 | labels_subject((i-1)*size(E_images,2)+1:i*size(E_images,2),:) = labels(i,:).* ones(size(E_images,2), 4); 21 | end 22 | data = permute(data, [2 3 4 1]); 23 | 24 | 25 | number_of_data_points = number_of_trials * size(E_images,2); 26 | 27 | % Split in 5 sets for 5-fold classification 28 | test_data(:,:,:,:,1) = data(:,:,:,1:0.2*number_of_data_points); 29 | training_data(:,:,:,:,1) = data(:,:,:,0.2*number_of_data_points+1:end); 30 | test_labels(:,:,1) = labels_subject(1:0.2*number_of_data_points,:); 31 | training_labels(:,:,1) = labels_subject(0.2*number_of_data_points+1:end,:); 32 | 33 | test_data(:,:,:,:,2) = data(:,:,:,0.2*number_of_data_points+1:0.4*number_of_data_points); 34 | training_data(:,:,:,:,2) = data(:,:,:,[1:0.2*number_of_data_points, 0.4*number_of_data_points+1:number_of_data_points]); 35 | test_labels(:,:,2) = labels_subject(0.2*number_of_data_points+1:0.4*number_of_data_points,:); 36 | training_labels(:,:,2) = labels_subject([1:0.2*number_of_data_points, 0.4*number_of_data_points+1:number_of_data_points],:); 37 | 38 | test_data(:,:,:,:,3) = data(:,:,:,0.4*number_of_data_points+1:0.6*number_of_data_points); 39 | training_data(:,:,:,:,3) = data(:,:,:,[1:0.4*number_of_data_points, 0.6*number_of_data_points+1:number_of_data_points]); 40 | test_labels(:,:,3) = labels_subject(0.4*number_of_data_points+1:0.6*number_of_data_points,:); 41 | training_labels(:,:,3) = labels_subject([1:0.4*number_of_data_points, 0.6*number_of_data_points+1:number_of_data_points],:); 42 | 43 | test_data(:,:,:,:,4) = data(:,:,:,0.6*number_of_data_points+1:0.8*number_of_data_points); 44 | training_data(:,:,:,:,4) = data(:,:,:,[1:0.6*number_of_data_points, 0.8*number_of_data_points+1:number_of_data_points]); 45 | test_labels(:,:,4) = labels_subject(0.6*number_of_data_points+1:0.8*number_of_data_points,:); 46 | training_labels(:,:,4) = labels_subject([1:0.6*number_of_data_points, 0.8*number_of_data_points+1:number_of_data_points],:); 47 | 48 | test_data(:,:,:,:,5) = data(:,:,:,0.8*number_of_data_points+1:number_of_data_points); 49 | training_data(:,:,:,:,5) = data(:,:,:,1:0.8*number_of_data_points); 50 | test_labels(:,:,5) = labels_subject(0.8*number_of_data_points+1:number_of_data_points,:); 51 | training_labels(:,:,5) = labels_subject(1:0.8*number_of_data_points,:); 52 | end -------------------------------------------------------------------------------- /make_eeg_image.m: -------------------------------------------------------------------------------- 1 | function eeg_image = make_eeg_image(eeg_data) 2 | % Author: Kris van Noord 3 | % Eindhoven University of Technology 4 | % 3D-CNN for EEG emotion classification 5 | % Openly available framework 6 | % Scripts verified on Matlab R2019b 7 | 8 | 9 | % input size should be [subject, trial, segment, CHANNEL, time/frequency] 10 | matrix_size = size(eeg_data); 11 | matrix = zeros(matrix_size(1), matrix_size(2), matrix_size(3), 9, 9, 4); 12 | for subject = 1:matrix_size(1) 13 | for trial = 1:matrix_size(2) 14 | for segment = 1:matrix_size(3) 15 | matrix(subject, trial, segment, 1, 4, :) = eeg_data(subject, trial, segment, 1, :); 16 | matrix(subject, trial, segment, 2, 4, :) = eeg_data(subject, trial, segment, 2, :); 17 | matrix(subject, trial, segment, 3, 3, :) = eeg_data(subject, trial, segment, 3, :); 18 | matrix(subject, trial, segment, 3, 1, :) = eeg_data(subject, trial, segment, 4, :); 19 | matrix(subject, trial, segment, 4, 4, :) = eeg_data(subject, trial, segment, 5, :); 20 | matrix(subject, trial, segment, 4, 2, :) = eeg_data(subject, trial, segment, 6, :); 21 | matrix(subject, trial, segment, 5, 3, :) = eeg_data(subject, trial, segment, 7, :); 22 | matrix(subject, trial, segment, 5, 1, :) = eeg_data(subject, trial, segment, 8, :); 23 | matrix(subject, trial, segment, 6, 2, :) = eeg_data(subject, trial, segment, 9, :); 24 | matrix(subject, trial, segment, 6, 4, :) = eeg_data(subject, trial, segment, 10, :); 25 | matrix(subject, trial, segment, 7, 3, :) = eeg_data(subject, trial, segment, 11, :); 26 | matrix(subject, trial, segment, 7, 1, :) = eeg_data(subject, trial, segment, 12, :); 27 | matrix(subject, trial, segment, 8, 4, :) = eeg_data(subject, trial, segment, 13, :); 28 | matrix(subject, trial, segment, 9, 4, :) = eeg_data(subject, trial, segment, 14, :); 29 | matrix(subject, trial, segment, 9, 5, :) = eeg_data(subject, trial, segment, 15, :); 30 | matrix(subject, trial, segment, 7, 5, :) = eeg_data(subject, trial, segment, 16, :); 31 | matrix(subject, trial, segment, 1, 6, :) = eeg_data(subject, trial, segment, 17, :); 32 | matrix(subject, trial, segment, 2, 6, :) = eeg_data(subject, trial, segment, 18, :); 33 | matrix(subject, trial, segment, 3, 5, :) = eeg_data(subject, trial, segment, 19, :); 34 | matrix(subject, trial, segment, 3, 7, :) = eeg_data(subject, trial, segment, 20, :); 35 | matrix(subject, trial, segment, 3, 9, :) = eeg_data(subject, trial, segment, 21, :); 36 | matrix(subject, trial, segment, 4, 8, :) = eeg_data(subject, trial, segment, 22, :); 37 | matrix(subject, trial, segment, 4, 6, :) = eeg_data(subject, trial, segment, 23, :); 38 | matrix(subject, trial, segment, 5, 5, :) = eeg_data(subject, trial, segment, 24, :); 39 | matrix(subject, trial, segment, 5, 7, :) = eeg_data(subject, trial, segment, 25, :); 40 | matrix(subject, trial, segment, 5, 9, :) = eeg_data(subject, trial, segment, 26, :); 41 | matrix(subject, trial, segment, 6, 8, :) = eeg_data(subject, trial, segment, 27, :); 42 | matrix(subject, trial, segment, 6, 6, :) = eeg_data(subject, trial, segment, 28, :); 43 | matrix(subject, trial, segment, 7, 7, :) = eeg_data(subject, trial, segment, 29, :); 44 | matrix(subject, trial, segment, 7, 9, :) = eeg_data(subject, trial, segment, 30, :); 45 | matrix(subject, trial, segment, 8, 6, :) = eeg_data(subject, trial, segment, 31, :); 46 | matrix(subject, trial, segment, 9, 6, :) = eeg_data(subject, trial, segment, 32, :); 47 | end 48 | end 49 | end 50 | 51 | eeg_image = matrix; 52 | 53 | end 54 | -------------------------------------------------------------------------------- /main_project.m: -------------------------------------------------------------------------------- 1 | % Author: Kris van Noord 2 | % Eindhoven University of Technology 3 | % 3D-CNN for EEG emotion classification 4 | % Openly available framework 5 | % Scripts verified on Matlab R2019b 6 | 7 | 8 | %% Clear workspace 9 | clear all 10 | close all 11 | 12 | 13 | %% Read in data 14 | % Function input parameters 15 | window_length = 128; % window length of sliding window approach (in samples) 16 | step_size = 128; % stride or step size of sliding window approach (in samples) 17 | normalization = "Self"; % Normalization type: No, Self or PreTrial 18 | normalization_operation = "divide" ; % Normalization operater: divide or subtract 19 | z_score_normalization = "Y"; % Apply Z-Score normalization on final feature vector? (Y/N) 20 | 21 | % The following data is loaded: 22 | % - Differential Entropy of full dataset as [subject, trial, segment, channel, frequency_band] 23 | % - Labels as [subject, trial, emotion] 24 | 25 | % Load Differential Entropy 26 | [DE, labels] = load_data(window_length, step_size, normalization, normalization_operation, z_score_normalization); 27 | 28 | % Change labels to classification 0 / 1; 29 | labels = double(labels > 5); 30 | 31 | %% Make EEG images with the spatial information of electrodes 32 | % The data is converted to [subject, trial, segment, 9, 9, frequency_band] 33 | DE = make_eeg_image(DE); 34 | 35 | %% Interpolate to 'steps x steps' grid (optional) 36 | % The data is converted to [subject, trial, segment, steps, steps, frequency_band] 37 | steps = 20; 38 | DE = interpolate_grid(DE, steps); 39 | 40 | %% 41 | figure() 42 | subplot(2,2,1) 43 | imagesc(reshape(DE(14,32,5,:,:,1), 20, 20)) 44 | colorbar 45 | axis off 46 | title("\theta") 47 | caxis([-1, 1]) 48 | subplot(2,2,2) 49 | imagesc(reshape(DE(14,32,5,:,:,2), 20, 20)) 50 | colorbar 51 | axis off 52 | title("\alpha") 53 | caxis([-1, 1]) 54 | subplot(2,2,3) 55 | imagesc(reshape(DE(14,32,5,:,:,3), 20, 20)) 56 | colorbar 57 | title("\beta") 58 | axis off 59 | caxis([-1, 1]) 60 | subplot(2,2,4) 61 | imagesc(reshape(DE(14,32,5,:,:,4), 20, 20)) 62 | colorbar 63 | title("\gamma") 64 | axis off 65 | caxis([-1, 1]) 66 | 67 | %% Make training / test sets and train CNN per subject 68 | 69 | % Loop over subjects 70 | for subject_no = 1:32 71 | DE_subject = reshape(DE(subject_no,:,:,:,:,:), size(DE, [2 3 4 5 6])); 72 | labels_subject = reshape(labels(subject_no, :, :), 40, 4); 73 | 74 | % Use 5-fold cross validation 75 | [training_data, test_data, training_labels, test_labels] = split_sets_5_fold(DE_subject, labels_subject); 76 | 77 | for fold_no = 1:5 78 | % TrainingOptions 79 | label_number = 1; % choose 1 for valence, 2 for arousal, 3 for dominance and 4 for liking 80 | miniBatchSize = 64; 81 | validationFrequency = floor(numel(training_labels(:,1))/(1*miniBatchSize)); 82 | options = trainingOptions('adam', ... 83 | 'MiniBatchSize',miniBatchSize, ... 84 | 'MaxEpochs',50, ... 85 | 'InitialLearnRate',1e-4, ... 86 | 'LearnRateSchedule','none', ... 87 | 'Shuffle','every-epoch', ... 88 | 'ValidationData',{test_data(:,:,:,:,fold_no),categorical(test_labels(:,label_number, fold_no), [0,1])}, ... 89 | 'ValidationFrequency',validationFrequency, ... 90 | 'VerboseFrequency', 10000, ... 91 | 'ExecutionEnvironment','gpu', ... 92 | 'Plots','training-progress', ... 93 | 'OutputFcn',@(info)stopIfAccuracyNotImproving(info,10), ... 94 | 'L2Regularization', 0.001); 95 | 96 | 97 | % Make model (Yang, 2018) 98 | layers = [ 99 | imageInputLayer([size(training_data, 1) size(training_data, 2) size(training_data, 3)]) 100 | convolution2dLayer(4,64,'Padding','Same','WeightsInitializer', 'he') 101 | dropoutLayer(0.5) 102 | reluLayer 103 | convolution2dLayer(4,128,'Padding','Same','WeightsInitializer', 'he') 104 | dropoutLayer(0.5) 105 | reluLayer 106 | convolution2dLayer(4,256,'Padding','Same','WeightsInitializer', 'he') 107 | dropoutLayer(0.5) 108 | reluLayer 109 | convolution2dLayer(1,64,'Padding','Same','WeightsInitializer', 'he') 110 | dropoutLayer(0.5) 111 | reluLayer 112 | fullyConnectedLayer(1024,'WeightsInitializer', 'he') 113 | dropoutLayer(0.5) 114 | reluLayer 115 | fullyConnectedLayer(2,'WeightsInitializer', 'he') 116 | softmaxLayer 117 | classificationLayer]; 118 | 119 | [yang2018net, training_info(subject_no,fold_no)] = trainNetwork(training_data(:,:,:,:,fold_no),categorical(training_labels(:,label_number, fold_no), [0,1]),layers,options); 120 | 121 | accuracy(subject_no,fold_no) = max(training_info(subject_no,fold_no).ValidationAccuracy(2:end)); 122 | 123 | end 124 | end 125 | 126 | -------------------------------------------------------------------------------- /load_data.m: -------------------------------------------------------------------------------- 1 | function [x_data, EEG_labels] = load_data(window_length, step_size, normalization, normalization_operation, z_score_normalization) 2 | % Author: Kris van Noord 3 | % Eindhoven University of Technology 4 | % 3D-CNN for EEG emotion classification 5 | % Openly available framework 6 | % Scripts verified on Matlab R2019b 7 | 8 | 9 | % Load raw data 10 | % Datafile should have size [32, 40, 32, 8064] !! 11 | EEG_data = load('EEG_data.mat'); 12 | EEG_data = EEG_data.new_data; 13 | 14 | % Load labels 15 | EEG_labels = load('EEG_labels'); 16 | EEG_labels = EEG_labels.EEG_labels; 17 | 18 | % Calculate filter coefficients for bandpass filter 19 | [b1, a1] = butter(6,[4 8]./64,'bandpass'); 20 | [b2, a2] = butter(6,[8 12]./64,'bandpass'); 21 | [b3, a3] = butter(6,[12 30]./64,'bandpass'); 22 | [b4, a4] = butter(6,[30 63]./64,'bandpass'); 23 | 24 | % Calculate number of segments with current window_size & step_size 25 | number_of_segments = round(7680/step_size - (window_length / step_size - 1)); 26 | 27 | % Calculate Differential Entropy for all trials 28 | x_data = zeros(32,40,number_of_segments,32,4); 29 | for subject = 1 : 32 30 | for trial = 1 : 40 31 | % Filter the signal into 4 different signals 32 | S_bp_1 = filter(b1, a1, reshape(EEG_data(subject, trial, :, :), 32, 8064).').'; 33 | S_bp_2 = filter(b2, a2, reshape(EEG_data(subject, trial, :, :), 32, 8064).').'; 34 | S_bp_3 = filter(b3, a3, reshape(EEG_data(subject, trial, :, :), 32, 8064).').'; 35 | S_bp_4 = filter(b4, a4, reshape(EEG_data(subject, trial, :, :), 32, 8064).').'; 36 | 37 | % Define baseline signals (first 384 samples / 3 seconds) 38 | baseline_1 = S_bp_1(:, 1:384); 39 | baseline_2 = S_bp_2(:, 1:384); 40 | baseline_3 = S_bp_3(:, 1:384); 41 | baseline_4 = S_bp_4(:, 1:384); 42 | 43 | % Calculate DE of every segment in baseline 44 | DE_baseline_1 = calculate_DE(baseline_1.'); 45 | DE_baseline_2 = calculate_DE(baseline_2.'); 46 | DE_baseline_3 = calculate_DE(baseline_3.'); 47 | DE_baseline_4 = calculate_DE(baseline_4.'); 48 | 49 | % Calculate average DE in baseline 50 | baseline_DE(1,:) = mean(DE_baseline_1, 1); 51 | baseline_DE(2,:) = mean(DE_baseline_2, 1); 52 | baseline_DE(3,:) = mean(DE_baseline_3, 1); 53 | baseline_DE(4,:) = mean(DE_baseline_4, 1); 54 | 55 | % Calculate DE for all segments and (if desired) normalize 56 | for i = 1:number_of_segments 57 | if normalization == "PreTrial" 58 | signal_1 = calculate_DE(S_bp_1(:, (i-1)*step_size+385:(i-1)*step_size + window_length + 384).'); 59 | signal_2 = calculate_DE(S_bp_2(:, (i-1)*step_size+385:(i-1)*step_size + window_length + 384).'); 60 | signal_3 = calculate_DE(S_bp_3(:, (i-1)*step_size+385:(i-1)*step_size + window_length + 384).'); 61 | signal_4 = calculate_DE(S_bp_4(:, (i-1)*step_size+385:(i-1)*step_size + window_length + 384).'); 62 | 63 | if normalization_operation == "divide" 64 | x_data(subject,trial,i,:,1) = signal_1 ./ DE_baseline_1; 65 | x_data(subject,trial,i,:,2) = signal_2 ./ DE_baseline_2; 66 | x_data(subject,trial,i,:,3) = signal_3 ./ DE_baseline_3; 67 | x_data(subject,trial,i,:,4) = signal_4 ./ DE_baseline_4; 68 | elseif normalization_operation == "subtract" 69 | x_data(subject,trial,i,:,1) = signal_1 - DE_baseline_1; 70 | x_data(subject,trial,i,:,2) = signal_2 - DE_baseline_2; 71 | x_data(subject,trial,i,:,3) = signal_3 - DE_baseline_3; 72 | x_data(subject,trial,i,:,4) = signal_4 - DE_baseline_4; 73 | else 74 | disp("Error: wrong normalization_operation") 75 | end 76 | elseif normalization == "Self" 77 | x_data(subject,trial,i,:,1) = calculate_DE(S_bp_1(:, (i-1)*step_size+385:(i-1)*step_size + window_length + 384).'); 78 | x_data(subject,trial,i,:,2) = calculate_DE(S_bp_2(:, (i-1)*step_size+385:(i-1)*step_size + window_length + 384).'); 79 | x_data(subject,trial,i,:,3) = calculate_DE(S_bp_3(:, (i-1)*step_size+385:(i-1)*step_size + window_length + 384).'); 80 | x_data(subject,trial,i,:,4) = calculate_DE(S_bp_4(:, (i-1)*step_size+385:(i-1)*step_size + window_length + 384).'); 81 | if normalization_operation == "divide" 82 | x_data(subject,trial,i,:,:) = x_data(subject,trial,i,:,:) ./ mean(x_data(subject,trial,i,:,:), 5); 83 | elseif normalization_operation == "subtract" 84 | x_data(subject,trial,i,:,:) = x_data(subject,trial,i,:,:) - mean(x_data(subject,trial,i,:,:), 5); 85 | else 86 | disp("Error: wrong normalization_operation") 87 | end 88 | 89 | elseif normalization == "No" 90 | x_data(subject,trial,i,:,1) = calculate_DE(S_bp_1(:, (i-1)*step_size+385:(i-1)*step_size + window_length + 384).'); 91 | x_data(subject,trial,i,:,2) = calculate_DE(S_bp_2(:, (i-1)*step_size+385:(i-1)*step_size + window_length + 384).'); 92 | x_data(subject,trial,i,:,3) = calculate_DE(S_bp_3(:, (i-1)*step_size+385:(i-1)*step_size + window_length + 384).'); 93 | x_data(subject,trial,i,:,4) = calculate_DE(S_bp_4(:, (i-1)*step_size+385:(i-1)*step_size + window_length + 384).'); 94 | else 95 | disp("Error: wrong normalization") 96 | end 97 | % Apply Z-Score normalization (ref: Yang et al, 2018) (OPTION) 98 | if z_score_normalization == "Y" 99 | x_data(subject,trial,i,:,1) = (x_data(subject,trial,i,:,1) - mean(x_data(subject,trial,i,:,1))) ./ std(x_data(subject,trial,i,:,1)); 100 | x_data(subject,trial,i,:,2) = (x_data(subject,trial,i,:,2) - mean(x_data(subject,trial,i,:,2))) ./ std(x_data(subject,trial,i,:,2)); 101 | x_data(subject,trial,i,:,3) = (x_data(subject,trial,i,:,3) - mean(x_data(subject,trial,i,:,3))) ./ std(x_data(subject,trial,i,:,3)); 102 | x_data(subject,trial,i,:,4) = (x_data(subject,trial,i,:,4) - mean(x_data(subject,trial,i,:,4))) ./ std(x_data(subject,trial,i,:,4)); 103 | end 104 | end 105 | end 106 | end 107 | end 108 | --------------------------------------------------------------------------------