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