Mercurial > hg > camir-aes2014
diff toolboxes/MIRtoolbox1.3.2/somtoolbox/som_train_struct.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/MIRtoolbox1.3.2/somtoolbox/som_train_struct.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,389 @@ +function sTrain = som_train_struct(varargin) + +%SOM_TRAIN_STRUCT Default values for SOM training parameters. +% +% sT = som_train_struct([[argID,] value, ...]) +% +% sTrain = som_train_struct('train',sM,sD); +% sTrain = som_train_struct('finetune','data',D); +% sTrain = som_train_struct('previous',sT0); +% +% Input and output arguments ([]'s are optional): +% [argID, (string) Several default values depend on other SOM parameters +% value] (varies) or on the proporties of a data set. See below for a +% a list of required and optional arguments for +% different parameters, and well as the list of valid +% argIDs and associated values. The values which are +% unambiguous can be given without the preceeding argID. +% +% sT (struct) The training struct. +% +% Training struct contains values for training and initialization +% parameters. These parameters depend on the number of training samples, +% phase of training, the training algorithm. +% +% Here are the valid argument IDs and corresponding values. The values which +% are unambiguous (marked with '*') can be given without the preceeding rgID. +% 'dim' (scalar) input space dimension +% 'dlen' (scalar) length of the training data +% 'data' (matrix / struct) the training data +% 'munits' (scalar) number of map units +% 'msize' (vector) map size +% 'previous' (struct) previous training struct can be given in +% conjunction with 'finetune' phase (see below) +% 'phase' *(string) training phase: 'init', 'train', 'rough' or 'finetune' +% 'algorithm' *(string) algorithm to use: 'lininit', 'randinit', 'batch' or 'seq' +% 'map' *(struct) If a map struct is given, the last training struct +% in '.trainhist' field is used as the previous training +% struct. The map size and input space dimension are +% extracted from the map struct. +% 'sTrain' *(struct) a train struct, the empty fields of which are +% filled with sensible values +% +% For more help, try 'type som_train_struct' or check out online documentation. +% See also SOM_SET, SOM_TOPOL_STRUCT, SOM_MAKE. + +%%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% som_train_struct +% +% PURPOSE +% +% Default values for SOM training parameters. +% +% SYNTAX +% +% sT = som_train_struct('argID',value,...); +% sT = som_train_struct(value,...); +% +% DESCRIPTION +% +% This function is used to give sensible values for SOM training +% parameters and returns a training struct. Often, the parameters +% depend on the properties of the map and the training data. These are +% given as optional arguments to the function. If a partially filled +% train struct is given, its empty fields (field value is [] or '' or +% NaN) are supplimented with default values. +% +% The training struct has a number of fields which depend on each other +% and the optional arguments in complex ways. The most important argument +% is 'phase' which can be either 'init', 'train', 'rough' or 'finetune'. +% +% 'init' Map initialization. +% 'train' Map training in a onepass operation, as opposed to the +% rough-finetune combination. +% 'rough' Rough organization of the map: large neighborhood, big +% initial value for learning coefficient. Short training. +% 'finetune' Finetuning the map after rough organization phase. Small +% neighborhood, learning coefficient is small already at +% the beginning. Long training. +% +% The fields of training struct set by this function are listed below. +% +% '.mask' Basically, a column vector of ones. But if a previous +% train or map struct is given, it is copied from there. +% '.neigh' Default value is 'gaussian' but if a previous train or map +% struct is given, it is copied from there. +% '.alpha_type' Default value is 'inv' but if a previous training struct +% is given, it is copied from there. +% '.alpha_ini' For 'train' and 'rough' phases, this is 0.5, for +% 'finetune' it is 0.05. +% '.radius_ini' Depends on the previous training operation and the +% maximum sidelength of the map ms = max(msize). +% if there isn't one, or it is 'randinit', rad_ini = max(1,ms/2) +% if it is 'lininit', rad_ini = max(1,ms/8) +% otherwise, rad_ini = rad_fin of the previous training +% '.radius_fin' Default value is 1, but if the training phase is +% 'rough', rad_fin = max(1,rad_ini/4). +% '.trainlen' For 'train' phase this is 20 x mpd epochs, for 'rough' +% phase 4 x mpd epochs and for 'finetune' 16 x mpd +% epochs, where mpd = munits/dlen. If mpd cannot be +% calculated, it is set to be = 0.5. In any case, +% trainlen is at least one epoch. +% '.algorithm' Default training algorithm is 'batch' and default +% initialization algorithm is 'lininit'. +% +% OPTIONAL INPUT ARGUMENTS +% +% argID (string) Argument identifier string (see below). +% value (varies) Value for the argument (see below). +% +% The optional arguments can be given as 'argID',value -pairs. If an +% argument is given value multiple times, the last one is used. The +% valid IDs and corresponding values are listed below. The values +% which are unambiguous (marked with '*') can be given without the +% preceeding argID. +% +% 'dim' (scalar) input space dimension +% 'dlen' (scalar) length of the training data +% 'data' (matrix / struct) the training data +% 'munits' (scalar) number of map units +% 'msize' (vector) map size +% 'previous' (struct) previous training struct can be given in +% conjunction with 'finetune' phase. +% 'phase' *(string) training phase: 'init', 'train', 'rough' or 'finetune' +% 'algorithm' *(string) algorithm to use: 'lininit', 'randinit', +% 'batch' or 'seq' +% 'map' *(struct) If a map struc is given, the last training struct +% in '.trainhist' field is used as the previous training +% struct. The map size and input space dimension are +% extracted from the map struct. +% 'sTrain' *(struct) a train struct, the empty fields of which are +% filled with sensible values +% +% OUTPUT ARGUMENTS +% +% sT (struct) The training struct. +% +% EXAMPLES +% +% The most important optional argument for the training parameters is +% 'phase'. The second most important are 'previous' and/or 'map'. +% +% To get default initialization parameters, use: +% +% sTrain = som_train_struct('phase','init'); +% or +% sTrain = som_train_struct('init'); +% +% To get default training parameters, use: +% +% sTrain = som_train_struct('phase','train','data',D,'map',sMap); +% or +% sTrain = som_train_struct('train','data',D,sMap); +% or +% sTrain = som_train_struct('train','dlen',dlen, ... +% 'msize',sMap.topol.msize,'dim',dim); +% +% If you want to first rough train and then finetune, do like this: +% +% sT1 = som_train_struct('rough','dlen',length(D),sMap); % rough training +% sT2 = som_train_struct('finetune','previous',sT1); % finetuning +% +% SEE ALSO +% +% som_make Initialize and train a map using default parameters. +% som_topol_struct Default map topology. +% som_randinint Random initialization algorithm. +% som_lininit Linear initialization algorithm. +% som_seqtrain Sequential training algorithm. +% som_batchtrain Batch training algorithm. + +% Copyright (c) 1999-2000 by the SOM toolbox programming team. +% http://www.cis.hut.fi/projects/somtoolbox/ + +% Version 2.0beta juuso 101199 090200 210301 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% check arguments + +% initial default structs +sTrain = som_set('som_train'); + +% initialize optional parameters +dlen = NaN; +msize = 0; +munits = NaN; +sTprev = []; +dim = NaN; +phase = ''; + +% varargin +i=1; +while i<=length(varargin), + argok = 1; + if ischar(varargin{i}), + switch varargin{i}, + case 'dim', i=i+1; dim = varargin{i}; + case 'dlen', i=i+1; dlen = varargin{i}; + case 'msize', i=i+1; msize = varargin{i}; + case 'munits', i=i+1; munits = varargin{i}; msize = 0; + case 'phase', i=i+1; phase = varargin{i}; + case 'algorithm', i=i+1; sTrain.algorithm = varargin{i}; + case 'mask', i=i+1; sTrain.mask = varargin{i}; + case {'previous','map'}, + i=i+1; + if strcmp(varargin{i}.type,'som_map'), + if length(varargin{i}.trainhist), + sTprev = varargin{i}.trainhist(end); + msize = varargin{i}.topol.msize; + end + elseif strcmp(varargin{i}.type,'som_train'), + sTprev = varargin{i}; + end + case 'data', + i=i+1; + if isstruct(varargin{i}), [dlen dim] = size(varargin{i}.data); + else [dlen dim] = size(varargin{i}); + end + case {'init','train','rough','finetune'}, phase = varargin{i}; + case {'lininit','randinit','seq','batch'}, sTrain.algorithm = varargin{i}; + otherwise argok=0; + end + elseif isstruct(varargin{i}) & isfield(varargin{i},'type'), + switch varargin{i}.type, + case 'som_train', + sT = varargin{i}; + if ~isempty(sT.algorithm), sTrain.algorithm = sT.algorithm; end + if ~isempty(sT.neigh), sTrain.neigh = sT.neigh; end + if ~isempty(sT.mask), sTrain.mask = sT.mask; end + if ~isnan(sT.radius_ini), sTrain.radius_ini = sT.radius_ini; end + if ~isnan(sT.radius_fin), sTrain.radius_fin = sT.radius_fin; end + if ~isnan(sT.alpha_ini), sTrain.alpha_ini = sT.alpha_ini; end + if ~isempty(sT.alpha_type), sTrain.alpha_type = sT.alpha_type; end + if ~isnan(sT.trainlen), sTrain.trainlen = sT.trainlen; end + if ~isempty(sT.data_name), sTrain.data_name = sT.data_name; end + if ~isempty(sT.time), sTrain.time = sT.time; end + case 'som_map', + if strcmp(varargin{i}.type,'som_map'), + if length(varargin{i}.trainhist), + sTprev = varargin{i}.trainhist(end); + msize = varargin{i}.topol.msize; + end + if ~isempty(varargin{i}.neigh) & isempty(sTrain.neigh), + sTrain.neigh = varargin{i}.neigh; + end + if ~isempty(varargin{i}.mask) & isempty(sTrain.mask), + sTrain.mask = varargin{i}.mask; + end + elseif strcmp(varargin{i}.type,'som_train'), + sTprev = varargin{i}; + end + case 'som_topol', msize = varargin{i}.msize; + case 'som_data', [dlen dim] = size(varargin{i}.data); + otherwise argok=0; + end + else + argok = 0; + end + if ~argok, + disp(['(som_train_struct) Ignoring invalid argument #' num2str(i)]); + end + i = i+1; +end + +% dim +if ~isempty(sTprev) & isnan(dim), dim = length(sTprev.mask); end + +% mask +if isempty(sTrain.mask) & ~isnan(dim), sTrain.mask = ones(dim,1); end + +% msize, munits +if ~msize | isempty(msize), + if isnan(munits), msize = [10 10]; + else s = round(sqrt(munits)); msize = [s round(munits/s)]; + end +end +munits = prod(msize); + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% action + +% previous training +prevalg = ''; +if ~isempty(sTprev), + if any(findstr(sTprev.algorithm,'init')), prevalg = 'init'; + else prevalg = sTprev.algorithm; + end +end + +% first determine phase +if isempty(phase), + switch sTrain.algorithm, + case {'lininit','randinit'}, phase = 'init'; + case {'batch','seq',''}, + if isempty(sTprev), phase = 'rough'; + elseif strcmp(prevalg,'init'), phase = 'rough'; + else phase = 'finetune'; + end + otherwise, phase = 'train'; + end +end + +% then determine algorithm +if isempty(sTrain.algorithm), + if strcmp(phase,'init'), sTrain.algorithm = 'lininit'; + elseif any(strcmp(prevalg,{'init',''})), sTrain.algorithm = 'batch'; + else sTrain.algorithm = sTprev.algorithm; + end +end + +% mask +if isempty(sTrain.mask), + if ~isempty(sTprev), sTrain.mask = sTprev.mask; + elseif ~isnan(dim), sTrain.mask = ones(dim,1); + end +end + +% neighborhood function +if isempty(sTrain.neigh), + if ~isempty(sTprev) & ~isempty(sTprev.neigh), sTrain.neigh = sTprev.neigh; + else sTrain.neigh = 'gaussian'; + end +end + +if strcmp(phase,'init'), + sTrain.alpha_ini = NaN; + sTrain.alpha_type = ''; + sTrain.radius_ini = NaN; + sTrain.radius_fin = NaN; + sTrain.trainlen = NaN; + sTrain.neigh = ''; +else + mode = [phase, '-', sTrain.algorithm]; + + % learning rate + if isnan(sTrain.alpha_ini), + if strcmp(sTrain.algorithm,'batch'), sTrain.alpha_ini = NaN; + else + switch phase, + case {'train','rough'}, sTrain.alpha_ini = 0.5; + case 'finetune', sTrain.alpha_ini = 0.05; + end + end + end + if isempty(sTrain.alpha_type), + if ~isempty(sTprev) & ~isempty(sTprev.alpha_type) ... + & ~strcmp(sTrain.algorithm,'batch'), + sTrain.alpha_type = sTprev.alpha_type; + elseif strcmp(sTrain.algorithm,'seq'), + sTrain.alpha_type = 'inv'; + end + end + + % radius + ms = max(msize); + if isnan(sTrain.radius_ini), + if isempty(sTprev) | strcmp(sTprev.algorithm,'randinit'), + sTrain.radius_ini = max(1,ceil(ms/4)); + elseif strcmp(sTprev.algorithm,'lininit') | isnan(sTprev.radius_fin), + sTrain.radius_ini = max(1,ceil(ms/8)); + else + sTrain.radius_ini = sTprev.radius_fin; + end + end + if isnan(sTrain.radius_fin), + if strcmp(phase,'rough'), + sTrain.radius_fin = max(1,sTrain.radius_ini/4); + else + sTrain.radius_fin = 1; + end + end + + % trainlen + if isnan(sTrain.trainlen), + mpd = munits/dlen; + if isnan(mpd), mpd = 0.5; end + switch phase, + case 'train', sTrain.trainlen = ceil(50*mpd); + case 'rough', sTrain.trainlen = ceil(10*mpd); + case 'finetune', sTrain.trainlen = ceil(40*mpd); + end + sTrain.trainlen = max(1,sTrain.trainlen); + end + +end + +return; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%