|
37 | 37 | arg({'patterns','PatternPairs'},uint32(3),[],'CSP patterns per frequency (times two).'), ... |
38 | 38 | arg({'whycsp','SkipCSP','WhyCSP'},false,[],'Classify cross-spectrum directly. This results in much higher-dimensional features, but can be approached with appropriately regularized classifiers (see ml_trainproximal).'), ... |
39 | 39 | arg({'normalize_spectrum','NormalizeSpectrum'},false,[],'Normalize the spectrum. Recommended if using sophisticated regularized classifiers.'), ... |
| 40 | + arg({'logtransform','LogTransform'},false,[],'Log-transform output. Log-transformed spectra are more likely to be separable by a linear classifier.'), ... |
40 | 41 | arg({'vectorize_features','VectorizeFeatures'},true,[],'Vectorize the features. For compatibility with basic classifiers.')); |
41 | 42 |
|
42 | 43 | if args.signal.nbchan == 1 |
|
45 | 46 | error('Multi-taper CSP prefers to work on at least as many channels as you request output patterns. Please reduce the number of pattern pairs.'); end |
46 | 47 | if isempty(args.timewnds) |
47 | 48 | args.timewnds = struct(); end |
| 49 | + [C,dummy,T] = size(args.signal.data); %#ok<NASGU,ASGLU> |
48 | 50 | if args.whycsp |
49 | 51 | % shortcut |
50 | 52 | for w = size(args.timewnds,1):-1:1 |
|
62 | 64 | mean_covar{w}(~isfinite(mean_covar{w})) = 0; weighted_covar{w}(~isfinite(weighted_covar{w})) = 0; |
63 | 65 | % calculate spatial filters for each frequency |
64 | 66 | for f=size(mean_covar{w},1):-1:1 |
65 | | - [V,D] = eig(squeeze(weighted_covar{w}(f,:,:)),squeeze(mean_covar{w,1}(f,:,:))); %#ok<NASGU> |
| 67 | + [V,D] = eig(reshape(weighted_covar{w}(f,:,:),C,C),reshape(mean_covar{w,1}(f,:,:),C,C)); %#ok<NASGU> |
66 | 68 | P = inv(V); |
67 | 69 | % retain k best filters/patterns at both ends of the eigenvalue spectrum |
68 | 70 | filters(w,f,:,:) = real(V(:,[1:args.patterns end-args.patterns+1:end])); |
|
80 | 82 | end |
81 | 83 | % solve a CSP instance for each frequency |
82 | 84 | for f=size(covar{w,1},1):-1:1 |
83 | | - [V,D] = eig(squeeze(covar{w,1}(f,:,:)),squeeze(covar{w,1}(f,:,:)+covar{w,2}(f,:,:))); %#ok<NASGU> |
| 85 | + [V,D] = eig(reshape(covar{w,1}(f,:,:),C,C),reshape(covar{w,1}(f,:,:),C,C)+reshape(covar{w,2}(f,:,:),C,C)); %#ok<NASGU> |
84 | 86 | P = inv(V); |
85 | 87 | filters(w,f,:,:) = real(V(:,[1:args.patterns end-args.patterns+1:end])); |
86 | 88 | patterns(w,f,:,:) = real(P([1:args.patterns end-args.patterns+1:end],:))'; |
87 | 89 | end |
88 | 90 | end |
89 | 91 | end |
90 | | - model = struct('filters',{filters},'patterns',{patterns},'time_args',{time_args},'spec_args',{args.spectral_estimation}, 'covar',{covar}, 'mean_covar',{mean_covar}, 'weighted_covar',{weighted_covar}, 'chanlocs',{args.signal.chanlocs},'vectorize_features',{args.vectorize_features},'whycsp',{args.whycsp},'normalize_spectrum',{args.normalize_spectrum}); |
| 92 | + model = struct('filters',{filters},'patterns',{patterns},'time_args',{time_args},'spec_args',{args.spectral_estimation}, 'covar',{covar}, 'mean_covar',{mean_covar}, 'weighted_covar',{weighted_covar}, 'chanlocs',{args.signal.chanlocs},'vectorize_features',{args.vectorize_features},'whycsp',{args.whycsp},'normalize_spectrum',{args.normalize_spectrum},'logtransform',{args.logtransform}); |
91 | 93 | end |
92 | 94 | global tracking; %#ok<TLEV> |
93 | 95 | tracking.inspection.signal = args.signal; |
|
121 | 123 | freqs = freqs(1):(freqs(2)-freqs(1))/(nfreqs-1):freqs(2); |
122 | 124 | features = bsxfun(@times,features,max(1,1./freqs')); |
123 | 125 | end |
| 126 | + if featuremodel.logtransform |
| 127 | + features = log(features); end |
124 | 128 | end |
125 | 129 | end |
126 | 130 | % apply minimal conditioning to features |
|
0 commit comments