IRootLab
An Open-Source MATLAB toolbox for vibrational biospectroscopy
reptt_incr.m
Go to the documentation of this file.
1 %> @file
2 %> @ingroup parallelgroup
3 %
4 %> @brief Incremental learning curve - to test incremental classifiers
5 %>
6 %> This Analysis Session aims to raise "Incremental learning curves" (ILC) for one or more classifiers. This aims at testing incremental
7 %> classifiers such as eClass
8 %>
9 %> ILC's are are direcly stored in a dataset. Each class of the dataset corresponds to a different classifier in the block_mold property.
10 %>
11 %> When using the reptt_incr::use() method, you need to pass two datasets to it: <code>[train, test]</code>. The @c test element will be always used as-is.
12 %> The @ref train dataset will have its rows permuted using the @ref reptt_incr::sgs. If an SGS is not provided, the @ref train dataset
13 %> will be used only once.
14 %>
15 %> The block_mold objects must be of class @ref clssr_incr
16 %>
17 %> The reptt_incr::use() method outputs one dataset per log in the @ref reptt_incr::log_mold property.
18 %>
19 %> @sa demo_reptt_incr.m
20 classdef reptt_incr < reptt
21  properties
22  %> SGS object. Needs to be a @ref sgs_randsub_base; bites will be ignored and overwritten with "[1]"; type will be overwritten with "simple"
23  %> The following properties make a difference: no_reps; flag_group; flag_perclass; randomseed
24  sgs;
25  %> =0. Whether to parallelize the outer "reps" loop
26  flag_parallel = 0;
27  %> =1. Recording periodicity
28  record_every = 1;
29  end;
30 
31  properties(SetAccess=protected)
32  obsidxs;
33  ests;
34 
35  %> Cell of datasets: each corresponding to one element in reptt_incr::log_mold
36  results;
37  end;
38 
39  methods
40  function o = reptt_incr()
41  o.classtitle = 'Incremental';
42  o.moreactions = [o.moreactions, {'extract_datasets'}];
43  o.flag_ui = 0; % Not published in GUI
44  end;
45  end;
46 
47  methods(Access=protected)
48  %> Returns number of recordings based on internal setup
49  %>
50  %> Asks the first element in block_mold
51  function nr = get_no_recordings(o, data)
52  bl = o.block_mold{1};
53  bl.record_every = o.record_every;
54  nr = bl.get_no_recordings(data(1).no);
55  end;
56 
57  %> Allocates result datasets
58  %>
59  %> Allocates datasets rather than logs. The datasets are sized with zeroes in their @c X and @c classes
60  %>
61  %> Dimensions are:
62  %> @arg results: cell of datasets: (1)X(no_logs)
63  %> @arg each dataset: X: (no_blocks*no_reps)X(number of recordings)
64  %>
65  %> The number of recordings is currently the number of elements in the training set (one recording is taken after one row is passed
66  %> to the incremental-training classifier)
67  function o = allocate_results(o, data)
68  no_reps = size(o.obsidxs, 1);
69  nb = numel(o.block_mold);
70  nl = numel(o.log_mold);
71 
72  if ~iscell(o.block_mold)
73  bmold = {o.block_mold};
74  else
75  bmold = o.block_mold;
76  end;
77 
78  if ~iscell(o.log_mold)
79  lmold = {o.log_mold};
80  else
81  lmold = o.log_mold;
82  end;
83 
84  nr = o.get_no_recordings(data);
85 
86  % model dataset
87  d = irdata();
88  d.fea_x = [(1:nr-1)*o.record_every data(1).no];
89  d.xname = 'Number of training observations';
90  d.xunit = '';
91  d.yname = 'Performance';
92  d.yunit = '';
93  d.X(nb*no_reps, nr) = 0;
94  d.classes(nb*no_reps, 1) = 0;
95 
96  d.classlabels = cell(1, nb);
97  for i = 1:nb
98  d.classlabels{i} = bmold{i}.get_description();
99  d.classes((1:no_reps)+(i-1)*no_reps) = i-1;
100  end;
101 
102  o.results = irdata.empty();
103 
104  for i = 1:nl
105  o.results(i) = d;
106  o.results(i).title = ['Based on ', lmold{i}.get_description()];
107  o.results(i).yunit = iif(o.log_mold{i}.get_flag_perc(), '%', '');
108  end;
109  end;
110 
111  %> Asserts that the SGS object is a randsub one
112  function o = assert_randsub(o)
113  if ~isempty(o.sgs) && ~isa(o.sgs, 'sgs_randsub_base')
114  irerror('sgs property needs to be a sgs_randsub_base!');
115  end;
116  end;
117 
118  %> Asserts that the blocks in @ref block_mold are all clssr_incr
119  function o = assert_clssr_incr(o)
120  for i = 1:numel(o.block_mold)
121  if ~isa(o.block_mold{i}, 'clssr_incr')
122  irerror('All classifiers must be of class "clssr_incr"!');
123  end;
124  end;
125  end;
126 
127 
128  %> Output is an array of datasets
129  function out = do_use(o, data)
130  o.assert_clssr_incr();
131 
132  flag_sgs = ~isempty(o.sgs);
133  if flag_sgs
134  o.assert_randsub();
135  sgs_ = o.sgs;
136  sgs_.bites = 1;
137  sgs_.type = 'simple';
138  o.obsidxs = o.sgs.get_obsidxs(data(1));
139  no_reps = size(o.obsidxs, 1);
140 % nt = size(o.obsidxs, 2)-1; % Number of test datasets
141  else
142  no_reps = 1;
143 % nt = numel(data)-1;
144  end;
145 
146  o = o.allocate_results(data);
147 % o = o.allocate_blocks();
148 
149  nb = numel(o.block_mold);
150  nl = numel(o.results);
151 % no_recordings = o.get_no_recordings();
152 
153 
154  % Will have to split the dataset before the parfor!
155  if ~flag_sgs
156  dd = data(1);
157  else
158  dd = data(1).split_map(o.obsidxs);
159  end;
160 
161  % Have to extrude everything from "o" that will be used by the workers
162  o_blocks = o.block_mold;
163  o_data2 = data(2);
164  o_postpr_est = o.postpr_est;
165  o_postpr_test = o.postpr_test;
166  o_logs = o.log_mold;
167  o_record_every = o.record_every;
168 
169 
170  % Results assigned during the parallel loop
171  tempresult = cell(1, no_reps*nb);
172 
173  if o.flag_parallel
174  parallel_assert();
175  parallel_open();
176  end;
177 
178  try
179  t = tic();
180 
181  parfor i_par = 1:no_reps*nb
182 
183  i_rep = ceil(i_par/nb);
184  i_blk = mod(i_par-1, nb)+1;
185 
186 % tempx = zeros(nl, no_recordings, nb);
187 
188 % ipro = progress2_open('REPTT_INCR BLOCKS', [], 0, nb);
189 % for i_blk = 1:nb
190  bl = o_blocks{i_blk};
191 
192  bl.data_test = o_data2;
193  bl.postpr_test = o_postpr_test;
194  bl.postpr_est = o_postpr_est;
195  bl.log_mold = o_logs;
196  bl.flag_rtrecord = 1;
197  bl.record_every = o_record_every;
198 
199  bl = bl.boot();
200 % bl = bl.allocate(dd(i_rep).no); % dd(i_rep).no for all i_rep should be the same
201 
202  bl = bl.train(dd(i_rep));
203 
204  tempresult{i_par} = bl.rates;
205 % ipro = progress2_change(ipro, [], [], i_blk);
206 % end;
207 % progress2_close(ipro);
208 
209 
210 % tempresult{i_par} = tempx;
211  end;
212 
213  irverbose(sprintf('TOTAL REPTT_INCR ELLAPSED TIME: %g\n', toc(t)));
214 
215  if o.flag_parallel
216  parallel_close();
217  end;
218  catch ME
219  if o.flag_parallel
220  parallel_close();
221  end;
222  rethrow(ME);
223  end;
224 
225 
226 
227  % Places results inside the right slots
228  for il = 1:nl
229  for i_par = 1:no_reps*nb
230  i_rep = ceil(i_par/nb);
231  i_blk = mod(i_par-1, nb)+1;
232  o.results(il).X(i_rep+(i_blk-1)*no_reps, :) = tempresult{i_par}(il, :);
233  end;
234  end;
235 
236  out = o.results;
237  o.results = [];
238  end;
239  end;
240 end
Base Sub-dataset Generation Specification (SGS) class.
Definition: sgs.m:6
Random Sub-sampling base class.
Base class for Incremental Classifiers.
Definition: clssr_incr.m:10
Analysis Session (AS) base class.
Definition: as.m:6