123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- function evaluateIncrementalLearning ( settings )
- % compare multi-class incremental learning with Gaussian processes using
- % either efficient model updates or batch training from scratch
- %
- % Copyright (c) by Alexander Freytag, 2013-11-13.
- if ( (nargin < 1) || isempty ( settings) )
- settings = [];
- end
- %setup variables for experiments
- if ( ~isfield( settings, 'i_numDim') || isempty(settings.i_numDim) )
- settings.i_numDim = 10;
- end
- if ( ~isfield( settings, 'd_mean') || isempty(settings.d_mean) )
- settings.d_mean = 3.0;
- end
- if ( ~isfield( settings, 'd_var') || isempty(settings.d_var) )
- settings.d_var = 1.0;
- end
- if ( ~isfield( settings, 'offsetSpecific') || isempty(settings.offsetSpecific) )
- settings.offsetSpecific = [ 0.0, 2.0, 4.0 ];
- end
- if ( ~isfield( settings, 'varSpecific') || isempty(settings.varSpecific) )
- settings.varSpecific = [2.0, 0.5, 1.0];
- end
- if ( ~isfield( settings, 'dimToChange') || isempty(settings.dimToChange) )
- settings.dimToChange = [ [1,3] , [2,4] , [5] ];
- end
- if ( ~isfield( settings, 'i_numClasses') || isempty(settings.i_numClasses) )
- settings.i_numClasses = 3;
- end
-
- if ( ~isfield( settings, 'i_numSamplesPerClassTrain') || isempty(settings.i_numSamplesPerClassTrain) )
- settings.i_numSamplesPerClassTrain = 10;
- end
- if ( ~isfield( settings, 'i_numSamplesPerClassUnlabeled') || isempty(settings.i_numSamplesPerClassUnlabeled) )
- settings.i_numSamplesPerClassUnlabeled = 100;
- end
- if ( ~isfield( settings, 'i_numSamplesPerClassTest') || isempty(settings.i_numSamplesPerClassTest) )
- settings.i_numSamplesPerClassTest = 10;
- end
- % how many experiments do you want to average?
- if ( ~isfield( settings, 'i_numRepetitions') || isempty(settings.i_numRepetitions) )
- i_numRepetitions = 10;
- end
- timesBatch = zeros ( i_numRepetitions, (settings.i_numClasses*settings.i_numSamplesPerClassUnlabeled+1) );
- timesEfficient = zeros ( i_numRepetitions, (settings.i_numClasses*settings.i_numSamplesPerClassUnlabeled+1) );
-
- arrBatch = zeros ( i_numRepetitions, (settings.i_numClasses*settings.i_numSamplesPerClassUnlabeled+1) );
- arrEfficient = zeros ( i_numRepetitions, (settings.i_numClasses*settings.i_numSamplesPerClassUnlabeled+1) );
-
- for i_idxRep = 1:i_numRepetitions
-
- %% (1) sample some features for initial train set, separate test set, and additional separate set to be added incrementally
- % sample training data
- settings.i_numSamplesPerClass = settings.i_numSamplesPerClassTrain;
- labeledData = sampleData( settings );
- % sample unlabeled data
- settings.i_numSamplesPerClass = settings.i_numSamplesPerClassUnlabeled;
- unlabeledData = sampleData( settings );
- % sample test data
- settings.i_numSamplesPerClass = settings.i_numSamplesPerClassTest;
- testData = sampleData( settings );
- % in which order to we want to add the 'unlabeled' sampels?
- idxToAdd = randperm( length(unlabeledData.y) );
- %% (2) run both techniques : efficient updates versus batch training
- b_efficientUpdates = false;
- resultsBatch = simulateIncrementalLearning ( labeledData, unlabeledData, testData, b_efficientUpdates, idxToAdd );
-
- timesBatch(i_idxRep, :) = resultsBatch.times;
- arrBatch(i_idxRep, :) = resultsBatch.ARR;
- clear ( 'resultsBatch' );
-
-
-
- b_efficientUpdates = true;
- resultsEfficient = simulateIncrementalLearning ( labeledData, unlabeledData, testData, b_efficientUpdates, idxToAdd );
-
- timesEfficient(i_idxRep, :) = resultsEfficient.times;
- arrEfficient(i_idxRep, :) = resultsEfficient.ARR;
- clear ( 'resultsEfficient' );
-
-
- end
- %% (3) evaluation
-
- % compute relevant values
- timesBatch = mean ( timesBatch ) ;
- timesEfficient = mean ( timesEfficient ) ;
-
- arrBatch = mean( arrBatch );
- arrEfficient = mean ( arrEfficient );
-
- % setup variables
- if ( ( ~isfield(settings,'s_legendLocation')) || isempty(settings.s_legendLocation) )
- s_legendLocation = 'NorthEast';
- else
- s_legendLocation = settings.s_legendLocation;
- end
-
- if ( ( ~isfield(settings,'i_fontSize')) || isempty(settings.i_fontSize) )
- i_fontSize = 12;
- else
- i_fontSize = settings.i_fontSize;
- end
-
- if ( ( ~isfield(settings,'i_fontSizeAxis')) || isempty(settings.i_fontSizeAxis) )
- i_fontSizeAxis = 16;
- else
- i_fontSizeAxis = settings.i_fontSizeAxis;
- end
-
- if ( ( ~isfield(settings,'c')) || isempty(settings.c) )
- c={[0,0,1], [1,0,0]};
- else
- c = settings.c;
- end
-
- if ( ( ~isfield(settings,'lineStyle')) || isempty(settings.lineStyle) )
- lineStyle={'-', '--' };
- else
- lineStyle = settings.lineStyle;
- end
-
- if ( ( ~isfield(settings,'marker')) || isempty(settings.marker) )
- marker={'none', 'none'};
- else
- marker = settings.marker;
- end
-
- if ( ( ~isfield(settings,'linewidth')) || isempty(settings.linewidth) )
- linewidth=3;
- else
- linewidth = settings.linewidth;
- end
-
- %% plot computation times (blue should be lower than red)
- fig_timeComp = figure;
- set ( fig_timeComp, 'name', 'Computation Times for Model Updates');
- hold on;
- plot ( timesEfficient, ...
- 'Color', c{ 1 }, ...
- 'LineStyle', lineStyle{ 1 }, ...
- 'Marker', marker{ 1 }, ...
- 'LineWidth', linewidth, ...
- 'MarkerSize', 8 ...
- );
- plot ( timesBatch, ...
- 'Color', c{ 2 }, ...
- 'LineStyle', lineStyle{ 2 }, ...
- 'Marker', marker{ 2 }, ...
- 'LineWidth', linewidth, ...
- 'MarkerSize', 8 ...
- );
-
- leg=legend( {'Efficient', 'Batch'}, 'Location', s_legendLocation,'fontSize', i_fontSize,'LineWidth', 3);
- xlabel('Number of samples added');
- ylabel({'Time spent for model update [s]'});
-
- text_h=findobj(gca,'type','text');
- set(text_h,'FontSize',i_fontSize);
- set(gca, 'FontSize', i_fontSize);
- set(get(gca,'YLabel'), 'FontSize', i_fontSizeAxis);
- set(get(gca,'XLabel'), 'FontSize', i_fontSizeAxis);
- hold off;
- %% plot accuracies (blue and red should be identical)
- fig_accuracyComp = figure;
- set ( fig_accuracyComp, 'name', 'Accuracy over time');
- hold on;
- plot ( 100*arrEfficient, ...
- 'Color', c{ 1 }, ...
- 'LineStyle', lineStyle{ 1 }, ...
- 'Marker', marker{ 1 }, ...
- 'LineWidth', linewidth, ...
- 'MarkerSize', 8 ...
- );
- plot ( 100*arrBatch, ...
- 'Color', c{ 2 }, ...
- 'LineStyle', lineStyle{ 2 }, ...
- 'Marker', marker{ 2 }, ...
- 'LineWidth', linewidth, ...
- 'MarkerSize', 8 ...
- );
-
- leg=legend( {'Efficient', 'Batch'}, 'Location', s_legendLocation,'fontSize', i_fontSize,'LineWidth', 3);
- xlabel('Number of samples added');
- ylabel({'Accuracy [%]'});
-
- text_h=findobj(gca,'type','text');
- set(text_h,'FontSize',i_fontSize);
- set(gca, 'FontSize', i_fontSize);
- set(get(gca,'YLabel'), 'FontSize', i_fontSizeAxis);
- set(get(gca,'XLabel'), 'FontSize', i_fontSizeAxis);
- hold off;
- pause;
- close ( fig_timeComp );
- close ( fig_accuracyComp );
-
- end
-
- function data = sampleData( settings )
- if ( isfield( settings, 'i_numDim') && ~isempty(settings.i_numDim) )
- i_numDim = settings.i_numDim;
- else
- i_numDim = 5;
- end
-
- if ( isfield( settings, 'd_mean') && ~isempty(settings.d_mean) )
- d_mean = settings.d_mean;
- else
- d_mean = 3.0;
- end
-
- if ( isfield( settings, 'd_var') && ~isempty(settings.d_var) )
- d_var = settings.d_var;
- else
- d_var = 1.0;
- end
-
- if ( isfield( settings, 'i_numClasses') && ~isempty(settings.i_numClasses) )
- i_numClasses = settings.i_numClasses;
- else
- i_numClasses = 3;
- end
-
- if ( isfield( settings, 'offsetSpecific') && ~isempty(settings.offsetSpecific) )
- offsetSpecific = settings.offsetSpecific;
- else
- offsetSpecific = [ 0.0, 2.0, 4.0 ];
- end
-
- if ( isfield( settings, 'varSpecific') && ~isempty(settings.varSpecific) )
- varSpecific = settings.varSpecific;
- else
- varSpecific = [2.0, 0.5, 1.0];
- end
-
- if ( isfield( settings, 'dimToChange') && ~isempty(settings.dimToChange) )
- dimToChange = settings.dimToChange;
- else
- dimToChange = [ [1,3] , [2,4] , [5] ];
- end
-
-
- if ( isfield( settings, 'i_numSamplesPerClass') && ~isempty(settings.i_numSamplesPerClass) )
- i_numSamplesPerClass = settings.i_numSamplesPerClass;
- else
- i_numSamplesPerClass = 2;
- end
-
- % randomly compute some features
- data.X = abs ( d_mean + d_var.*randn(i_numDim,i_numClasses*i_numSamplesPerClass) );
- % disturbe features for specific classes
- for i_clIdx = 1:i_numClasses
- i_idxStart = (i_clIdx-1)*i_numSamplesPerClass+1;
- i_idxEnd = i_clIdx*i_numSamplesPerClass;
- data.X( dimToChange(i_clIdx), i_idxStart:i_idxEnd ) = ...
- abs ( data.X(1, i_idxStart:i_idxEnd) + ...
- offsetSpecific( i_clIdx) + ... %add class offset
- varSpecific ( i_clIdx) .*randn(1,i_numSamplesPerClass) ... % add class variance
- );
- end
- % normalize features, thereby simulate histograms, which commonly occure in
- % computer vision applications
- data.X = bsxfun(@times, data.X, 1./(sum(data.X, 1)));
- % adapt class labels
- data.y = bsxfun(@times, ones(1,i_numSamplesPerClass)', 1:i_numClasses );
- data.y = data.y(:);
- end
|