Skip to content

Commit

Permalink
change fixation plot color to be default and random over plots AND ch…
Browse files Browse the repository at this point in the history
…ange the transition matrix image color(color gray --> colormap default)
  • Loading branch information
JJHu1993 committed Oct 23, 2017
1 parent d57dfd8 commit cfab067
Show file tree
Hide file tree
Showing 166 changed files with 10,894 additions and 0 deletions.
87 changes: 87 additions & 0 deletions Classif_from_HMM_descriptors_Coutrot.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
%If you use this toolbox, please cite Coutrot et al.,
%"Scanpath modeling and classification with Hidden Markov Models", Behavior
%Research Methods, 2017
% Classify tasks from Coutrot's dataset (conversational videos, 2 auditory conditions) with HMM-based gaze descriptors
clear
close all
load HMM_descriptor_Coutrot %computed with exemple_Compute_HMM_descriptors.m
all_stim=fieldnames(example_HMM_descriptor_Coutrot);

%LDA 1st Eigen Vector
%ini_stim=char(all_stim(1));
%ini_descriptor=example_HMM_descriptor_Coutrot.(ini_stim).with_os.gaze_descriptor;
%LDA_1st_Eigen_vect=NaN(size(ini_descriptor,2),length(all_stim));

%Correct classification vector
correct_classif=NaN(length(all_stim),1);

% For each stimulus, a correct classification score is computed
for istim=1:length(all_stim)

im_name=char(all_stim(istim));

%% Load HMM-based gaze descriptors from HMM_descriptor_Coutrot.mat
gaze_descriptor_ws=example_HMM_descriptor_Coutrot.(im_name).with_os.gaze_descriptor;
gaze_descriptor_wos=example_HMM_descriptor_Coutrot.(im_name).without_os.gaze_descriptor;

%% Normalization to zero mean and unit std
norm_gaze_descriptor_ws=zscore(gaze_descriptor_ws')';
norm_gaze_descriptor_wos=zscore(gaze_descriptor_wos')';

%% Regularization
all_task = [norm_gaze_descriptor_ws;norm_gaze_descriptor_wos];
lambda_I_all=0.00001*eye(size(all_task));
regul_gaze_descriptor_all = all_task - lambda_I_all.*all_task + lambda_I_all ;
regul_gaze_descriptor_ws=regul_gaze_descriptor_all(1:size(norm_gaze_descriptor_ws,1),:);
regul_gaze_descriptor_wos=regul_gaze_descriptor_all(size(norm_gaze_descriptor_ws,1)+1:...
size(norm_gaze_descriptor_ws,1)+size(norm_gaze_descriptor_wos,1),:);


%% Choose classes to classify
gaze_descriptors={regul_gaze_descriptor_ws, regul_gaze_descriptor_wos};
categoric_var={'with_os', 'without_os'};

%% Select type of classifier
classifier_type='LDA';
% classifier_type='diagquadratic';
% classifier_type='mahalanobis';
%classifier_type='SVMBinary';
%classifier_type='SVMMultiClass';
%classifier_type='AdaBoostBinary';
%classifier_type='AdaBoostMultiClass';
% classifier_type='RVM';%Only for 2-class problems
% classifier_type='AdaBoost';%Only for 2-class problems
% classifier_type= 'RandomForest';

%% k-fold cross-validation
cross_validation=1;
% % if cross_validation==1
% % leave-one-out
% % else
% % 'k'-cross_validation
% % end
try
[lda_stats, success_rate] = classifier(categoric_var, gaze_descriptors,classifier_type,cross_validation);

% %LDA 1st Eigen vector: absolute values and normalization
% lda_stats.eigenvec(:,1)=abs(lda_stats.eigenvec(:,1));
% LDA_1st_Eigen_vect(:,istim)=lda_stats.eigenvec(:,1)/sum(lda_stats.eigenvec(:,1));
catch
fprintf('stimuli %u could not be classified\n',istim)
success_rate=NaN;
manova_stats=NaN;
end

if ~mod(istim,1)
fprintf('stimuli %u success_rate %d\n',istim, success_rate)
end

correct_classif(istim)=success_rate;
end

fprintf('average correct classification score over %u stimuli is %3.1f %% (chance = %3.1f %%)\n',length(all_stim), 100*nanmean(correct_classif),100/length(categoric_var))
hist(correct_classif)
xlabel('Correct Classification Rate','FontSize',12,'FontWeight','bold')
ylabel('Frequency','FontSize',12,'FontWeight','bold')

% errorbar(squeeze(nanmean(abs(LDA_1st_Eigen_vect),2)),nanstd(abs(LDA_1st_Eigen_vect),0,2)/sqrt(length(all_stim)),'.')
90 changes: 90 additions & 0 deletions Classif_from_HMM_descriptors_Koehler.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
%If you use this toolbox, please cite Coutrot et al.,
%"Scanpath modeling and classification with Hidden Markov Models", Behavior
%Research Methods, 2017
% Classify tasks from Koehler's dataset (static images, 3 tasks) with HMM-based gaze descriptors
clear
close all
load HMM_descriptor_Koehler %computed with exemple_Compute_HMM_descriptors.m
all_stim=fieldnames(example_HMM_descriptor);
ini_stim=char(all_stim(1));
ini_descriptor=example_HMM_descriptor.(ini_stim).freeview.gaze_descriptor;
%LDA 1st Eigen Vector
%LDA_1st_Eigen_vect=NaN(size(ini_descriptor,2),length(all_stim));
%Correct classification vector
correct_classif=NaN(length(all_stim),1);

% For each stimulus, a correct classification score is computed
for istim=1:length(all_stim)

im_name=char(all_stim(istim));

%% Load HMM-based gaze descriptors from example_HMM_descriptor.mat
gaze_descriptor_free=example_HMM_descriptor.(im_name).freeview.gaze_descriptor;
gaze_descriptor_sal=example_HMM_descriptor.(im_name).salview.gaze_descriptor;
gaze_descriptor_obj=example_HMM_descriptor.(im_name).objsearch.gaze_descriptor;

%% Normalization to zero mean and unit std
norm_gaze_descriptor_free=zscore(gaze_descriptor_free')';
norm_gaze_descriptor_sal=zscore(gaze_descriptor_sal')';
norm_gaze_descriptor_obj=zscore(gaze_descriptor_obj')';

%% Regularization
all_task = [norm_gaze_descriptor_free;norm_gaze_descriptor_sal;norm_gaze_descriptor_obj];
lambda_I_all=0.00001*eye(size(all_task));
regul_gaze_descriptor_all = all_task - lambda_I_all.*all_task + lambda_I_all ;
regul_gaze_descriptor_free=regul_gaze_descriptor_all(1:size(norm_gaze_descriptor_free,1),:);
regul_gaze_descriptor_sal=regul_gaze_descriptor_all(size(norm_gaze_descriptor_free,1)+1:size(norm_gaze_descriptor_free,1)+size(norm_gaze_descriptor_sal,1),:);
regul_gaze_descriptor_obj=regul_gaze_descriptor_all(size(norm_gaze_descriptor_free,1)+size(norm_gaze_descriptor_sal,1)+1:size(norm_gaze_descriptor_free,1)+size(norm_gaze_descriptor_sal,1)+size(norm_gaze_descriptor_obj,1),:);


%% Choose classes to classify
% categoric_var={'free', 'sal', 'obj'};
% gaze_descriptors={regul_gaze_descriptor_free, regul_gaze_descriptor_sal, regul_gaze_descriptor_obj};

gaze_descriptors={regul_gaze_descriptor_free, regul_gaze_descriptor_sal, regul_gaze_descriptor_obj};
categoric_var={'free', 'sal', 'obj'};

%% Select type of classifier
classifier_type='LDA';
% classifier_type='diagquadratic';
% classifier_type='mahalanobis';
%classifier_type='SVMBinary';
%classifier_type='SVMMultiClass';
%classifier_type='AdaBoostBinary';
%classifier_type='AdaBoostMultiClass';
% classifier_type='RVM';%Only for 2-class problems
% classifier_type='AdaBoost';%Only for 2-class problems
% classifier_type= 'RandomForest';

%% k-fold cross-validation
cross_validation=1;
% % if cross_validation==1
% % leave-one-out
% % else
% % 'k'-cross_validation
% % end
try
[lda_stats, success_rate] = classifier(categoric_var, gaze_descriptors,classifier_type,cross_validation);

% %LDA 1st Eigen vector: absolute values and normalization
% lda_stats.eigenvec(:,1)=abs(lda_stats.eigenvec(:,1));
% LDA_1st_Eigen_vect(:,istim)=lda_stats.eigenvec(:,1)/sum(lda_stats.eigenvec(:,1));
catch
fprintf('stimuli %u could not be classified\n',istim)
success_rate=NaN;
manova_stats=NaN;
end

if ~mod(istim,10)
fprintf('stimuli %u success_rate %d\n',istim, success_rate)
end

correct_classif(istim)=success_rate;
end

fprintf('average correct classification score over %u stimuli is %3.1f %% (chance = %3.1f %%)\n',length(all_stim), 100*nanmean(correct_classif),100/length(categoric_var))
hist(correct_classif,40)
xlabel('Correct Classification Rate')
ylabel('Frequency')

% errorbar(squeeze(nanmean(abs(LDA_1st_Eigen_vect),2)),nanstd(abs(LDA_1st_Eigen_vect),0,2)/sqrt(length(all_stim)),'.')
100 changes: 100 additions & 0 deletions Compute_HMM_descriptors_Coutrot.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
%If you use this toolbox, please cite Coutrot et al.,
%"Scanpath modeling and classification with Hidden Markov Models", Behavior
%Research Methods, 2017

% Compute HMM-based gaze descriptors for Koehler's dataset (static images, 3 tasks)
clear
close all
addpath ./stimuli/Frames_Coutrot/ % where the stimuli are stored
addpath(genpath('emhmm-toolbox'))
load EyeData_Coutrot % contains eye positions from Coutrot & Guyader, JoV 2014

% variational approach: automatically selects optimal state number from K = 1 to 3
K = 1:3;
% [priors transition_matrix_coeff state_centre state_cov]
param_nb=max(K)+max(K)^2+max(K)*2+max(K)*2;
%plot the HMM states on the stimuli
isplotHMM=1;

nstim=size(example_EyeData_Coutrot.with_os.x_pos,2); %number of stimuli
for istim=1:nstim
fprintf('stim %u\n',istim)
%close all

% Read stimuli
im_name=['clip_' num2str(istim) '.jpg'];
im_name_struct=['clip__' num2str(istim)];
im= imread(im_name);

% Maximum number of observer per task
maxsub=max([size(example_EyeData_Coutrot.with_os.x_pos,1),size(example_EyeData_Coutrot.without_os.x_pos,1)]);
% Initialize gaze descriptor vector
gaze_descriptor_ws=NaN(maxsub,param_nb);
gaze_descriptor_wos=NaN(maxsub,param_nb);

% Loop on subjects
for isub=1:maxsub

%% Auditory Condition 1: With Orginal Soundtrack

% Extract current scanpath
scanpath_ws = extract_scanpath(example_EyeData_Coutrot,'with_os',isub,istim,K);
if ~isempty(scanpath_ws{1,1})
% Compute corresponding HMM
vbopt=initialize_HMM_computation(im);
[hmm_ws,~] = vbhmm_learn(scanpath_ws, K, vbopt);

% sort states from left to right
hmm_ws = sort_hmm_state(hmm_ws);

% add 'ghost states' if K < Kmax so all gaze descriptor vectors have the same dimension
hmm_ws=pad_with_ghost_states(hmm_ws,max(K),im);

%Extract gaze_descriptor vector from HMM parameters: priors, transition matrix coefficients, state centres and state covariances
gaze_descriptor_ws(isub,:) =extract_hmm_parameters(hmm_ws);

if isplotHMM
subplot(1,3,1)
plot_hmm_state(hmm_ws,scanpath_ws,im)
title WithSound
end
end
%% Auditory Condition 2: Without Orginal Soundtrack

% Extract current scanpath
scanpath_wos = extract_scanpath(example_EyeData_Coutrot,'without_os',isub,istim,K);
if ~isempty(scanpath_wos{1,1})
% Compute corresponding HMM
vbopt=initialize_HMM_computation(im);
vbopt.do_constrain_var=1;
[hmm_wos,~] = vbhmm_learn(scanpath_wos, K, vbopt);

% sort states from left to right
hmm_wos = sort_hmm_state(hmm_wos);

% add 'ghost states' if K < Kmax so all gaze descriptor vectors have the same dimension
hmm_wos=pad_with_ghost_states(hmm_wos,max(K),im);

%Extract gaze_descriptor vector from HMM parameters:
%priors, transition matrix coefficients, state centres and state covariances
gaze_descriptor_wos(isub,:) =extract_hmm_parameters(hmm_wos);

if isplotHMM
subplot(1,3,2)
plot_hmm_state(hmm_wos,scanpath_wos,im)
title WithoutSound
pause(0.1)
end
end
end

gaze_descriptor_ws(isnan(gaze_descriptor_ws(:,1)),:)=[];
gaze_descriptor_wos(isnan(gaze_descriptor_wos(:,1)),:)=[];

HMM_descriptor_Coutrot.(im_name_struct).with_os.gaze_descriptor=gaze_descriptor_ws;
HMM_descriptor_Coutrot.(im_name_struct).without_os.gaze_descriptor=gaze_descriptor_wos;

end
save('HMM_descriptor_Coutrot','HMM_descriptor_Coutrot')


Loading

0 comments on commit cfab067

Please sign in to comment.