3 %> Grid search is an simple iterative way of optimization that avoids
using the gradient of the objective
function (F(.)). Instead, it
4 %> evaluates F(.) at all points within a point grid and finds to find the maximum value. A
new, finer grid is then formed
5 %> around the point that corresponds to
this maximum and the process follows.
7 %> The idea came from the guide that comes with LibSVM [1].
9 %> Rather than passing a vector from the domain to the objective
function,
this grid search assigns values to fields
10 %> within a structure (
'.obj') and calls the objective function ('.f_get_rate()') passing '.obj'
as a parameter.
12 %> Grid search is of course not restricted to SVM neither to classifiers.
14 %> Not published in the GUI at the moment.
16 %> <h3>References:</h3>
22 %> SGS. If not supplied, the @ref data property will be expected to
23 %> have at least two elements. Another option is to use obsidxs
28 %> =(automatic). Cell array. Molds for the recording.
30 %> Automatic logs are rates, time_train, and time_use.
32 %> If passed, make sure that first log is rate, and second is time
34 %> log titles will become fields inside the sovaluess.values
37 %> (Optional) Block to post-process the test data. For example, a @ref
grag_classes_first.
39 %> Block to post-process the estimation issued by the classifier. Examples:
42 %> There isn't a default, this must be provided
45 %> Number of times to zoom close to best point
47 %> =3. Maximum number of tries per iteration. A try counts when the chosen item was on any edge. In this case, the search space will
48 %> be shifted to have the chosen in the middle, without refinements
50 %> Array of gridsearchparam objects
51 params = gridsearchparam.empty;
52 %> Parameters specifications in a cell
56 %> =0. Whether to run in parallel mode!
66 o.classtitle = 'Grid Search';
71 %> Adds parameter using @ref gridsearchparam constructor with varargin
72 function o = add_param(o, varargin)
73 if numel(o.params) >= 3
74 irerror('Grid search can handle a maximum of 3 variables!');
76 o.params(end+1) = gridsearchparam(varargin{:});
79 function o = assert(o)
80 no_dims = length(o.params);
85 if o.no_refinements > 0 && ~all([o.params.flag_numeric])
86 irerror('In order to refine search, all parameters must be numeric!');
90 function o = make_defaults(o, data)
91 if isempty(o.log_mold)
92 ott = ttlogprovider();
93 o.log_mold = ott.get_ttlogs(data);
97 ch = chooser(); %
#ok<*CPROP,*PROP>
98 ch.rate_maxloss = 0.001;
99 ch.time_mingain = 0.4500;
101 idx = find(cellfun(@(x) strcmp(x.title,
'rates'), o.log_mold)); %#ok<*EFIND>
103 ch.ratesname = o.log_mold{1}.title;
104 %
else assumes chooser_base
default, which is
'rates'
106 idx = find(cellfun(@(x) strcmp(x.title,
'times3'), o.log_mold));
108 ch.timesname = o.log_mold{2}.title;
109 %
else assumes chooser_base
default, which is
'times3'
114 if ~isempty(o.paramspecs)
116 for i = 1:size(o.paramspecs, 1)
121 % Won
't make default post-processors anymore
122 % if isempty(o.postpr_est)
123 % o.postpr_est = def_postpr_est();
124 % o.postpr_test = def_postpr_test(); % Overrides pospr_test because need a harmonic pair
129 methods(Access=protected)
130 function log = do_use(o, data)
131 o = o.make_defaults(data);
134 u = reptt_blockcube();
135 u.log_mold = o.log_mold;
137 u.flag_parallel = o.flag_parallel;
138 u.postpr_test = o.postpr_test;
139 u.postpr_est = o.postpr_est;
148 nvv(j) = numel(params(j).values);
150 ticklabelss{j} = params(j).get_ticklabels();
153 log = log_gridsearch();
163 nExpected = o.no_refinements+1; % Expected iterations
164 ipro = progress2_open('GRIDSEARCH
', [], 0, nExpected);
166 s_it = sprintf('Iteration: %d (refinement: %d; move: %d)
', iiter, irefin, imove);
168 irverbose ('**************
', 2);
169 irverbose(['************** Grid search
', s_it], 2);
170 irverbose ('**************
', 2);
175 sov.chooser = o.chooser;
179 ax.label = p.get_label();
180 ax.values = p.get_values_numeric();
181 ax.ticks = p.get_ticklabels();
182 ax.legends = p.get_legends();
196 idx = mod(r-1, nvv(j))+1;
197 r = floor((r-1)/nvv(j))+1;
199 eval(sprintf('blk.%s = p.
get_value(idx);
', p.name)); % Sets block value
200 s_spec = cat(2, s_spec, iif(j > 1, ',
', ''), p.name, '=
', p.get_value_string(idx)); %ticklabelss{j}{idx});
204 % fprintf('%05d %s\n
', q, s_spec);
210 % populate the block_cube
211 molds{idxs{:}} = blk;
212 specs{idxs{:}} = s_spec;
213 idxss{idxs{:}} = idxs;
218 cube.block_mold = molds;
219 cubelog = cube.use(data);
223 sov = sov.read_log_cube(cubelog, []);
224 sov = sov.set_field('spec
', specs);
225 sov = sov.set_field('mold
', molds);
226 sov = sov.set_field('idxs
', idxss);
229 sov.ax(2) = raxisdata_singleton();
232 log.sovaluess(iiter) = sov;
236 [item, idxs] = sov.choose_one();
238 idxs = cell2mat(idxs);
239 flag_edge = any(idxs == 1) || any(idxs == nvv); % Whether any value was on the edge
243 if imove >= o.maxmoves
244 irverbose(sprintf('Still hit the edge after %d moves
', imove));
247 irverbose('Hit the edge, will move to have best point in the centre
', 1);
249 params(j) = params(j).move_to(idxs(j));
252 nExpected = nExpected+1;
259 if flag_shrink && irefin < o.no_refinements
260 % Prepares for refinement
262 params(j) = params(j).shrink_around(idxs(j));
271 ipro = progress2_change(ipro, [], [], iiter, nExpected);
273 progress2_close(ipro);
276 % I don't need a
try...
"finally" for this, not critical, really
283 methods(Access=
protected)
284 function v = get_ticks(o, centre, length, no_points)
285 x1 = centre-length/2;
286 x2 = centre+length/2;
287 v = linspace(x1, x2, no_points);
Base Sub-dataset Generation Specification (SGS) class.
Group Aggregator - Classes - Vote.
function parallel_close()
Block that resolves estimato posterior probabilities into classes.
Group Aggregator - Classes - First row.
Analysis Session (AS) base class.
Cascade block: sequence of blocks represented by a block.
function get_value(in o, in idx)
REpeated Train-Test - Block Cube.