NAME
som_layer -- create 2d-self organizing map
PROTOTYPE
unitptr som_layer( int din, int dx, int dy, float (*f)(float), float (*h)(float), int mode, unitptr dest)
ARGUMENTS
- int din
- dimensionality of input vector
- int dx
- width of map; periodic boundary conditions along width directions, if negative
- int dy
- height of map; periodic boundary conditions along height direction, if negative. Total number of nodes is n=abs(dx*dy).
- float (*f)(float)
- activation function common to all nodes. If f=NULL, the function f(x)=exp(-x) will be used as a default for f.
- float (*h)(float)
- neighborhood function common to all nodes. If h=NULL, the function h(x)=exp(-x) will be used as a default for h.
- int mode
- mode parameter (see below)
- unitptr dest
- host unit for newly created instance
RETURN VALUE:
- unitptr u:
- pointer to newly created unit
INTERFACE OF CREATED UNIT:
For mode=0 or 1
- X_in[din]:
- (input field 0) input vector
- Y_in[din]:
- (input field 1) mask g1 for input vector
- Z_in[din]:
- (input field 2) mask g2 for adaptation
- Eps_in[3]:
- (input field 3) adaptation gains
eps1,eps2 and neighborhood width parameter
sigma
- Ctl_in[2]:
- (input field 4) control inputs c,beta
- X_out[n]:
- (output field 0) output vector
( n=dx*dy)
- Y_out[2]:
- (output field 1) cartesian position of
bestmatch node
in map (range is [0..dx-1]x[0..dy-1])
- Z_out[(din+1)*n]:
- (packed output field 2) weights and
radii.
For mode=2 or 3
- in_0[din]:
- (input field 0) input vector x_0 for
node 0
- in_1[din]:
- (input field 1) input vector x_1 for
node 1
EXECUTION OF CREATED UNIT:
For mode=0 or 2 or 5:
X_out[i]:= (1-c)*X_out[i] + c*f(s_i)
For mode=1 or 3 a normalization of the values f(s_i) is
performed, and the output is given by
X_out[i]:= (1-c)*X_out[i] + c*F(s_i)
F(s_i) = f(s_i) / sum_j f(s_j)
For mode=5, the additional output field out_3 is updated
according to
out_3[i]:= (1-c)*out_3[i] + c*BestMatchVector[i]
The argument values s_i to the user-defined activation function
f(.) are defined by
s_i = beta*d[i]/sig[i],
d[i] = sqrt( sum_j g1[j]^2*(x_i[j]-w[i][j])^2)
(if mode=0 or 1, all vectors x_i are the same and equal to
X_in.) A common choice for f(.) is a decaying exponential.
For this specify f=FUN_EXPM (this is also taken as
default, if f=NULL)..
In addition, the 2-dimensional position vector ( xbest,
ybest), 0=<xbest<dx, 0=<ybest<dy in the dx*dy-lattice of the
node with d[k]=minimal ( best match) node will be returned
at output field Y_out.
ADAPTATION:
For all internal nodes i=0..n-1:
Delta w[i][j] = eps1 * h( R[ik]/sigma^2 ) *
* (x_i[j] - w[i][j]) * g2[j] * X_out[i]
Here, R[ik] is the square of the euclidean lattice distance
between the 2d-positions of node i and the "best match node"
k in the dx*dy-lattice.
In addition, for the "best match node" k the radius sig[k]
is adapted according to
Delta sig[k] = eps2 * (d[k] - sig[k])*X_out[k];
Weights and radii are accessible at packed output field
Z_out, that contains them in the order sig[0], w[0][0..din-1],
sig[1], w[1][0..din-1], ... sig[n-1], w[n-1][0..din-1].
INITIALIZATION:
The weights w[i][j] may be initialized or re-initialized by
calling ctrl_unit(cmode,u), where cmode is one of the following
- NST_I_RND
- uniformly between RND_LIMIT1 and RND_LIMIT2
- NST_I_NOR
- uniformly between RND_LIMIT1 and RND_LIMIT2
and subsequent normalization to unit length.
- NST_I_ZERO
- set all weights to zero
- NST_I_USER
- put the unit into initialization mode
(see below).
In addition, a call of ctrl_unit(cmode,u) with cmode one of
the above sets all output values X_out to zero, and all
values sig[k] to 1.
Default initialization is with cmode=NST_I_NOR. If
initialization of the weights w[i][j] to user defined values is
desired, a special initialization mode can be turned on.
This is achieved by a call ctrl_unit(NST_I_USER,u), where u
is the unitptr to the instance of the som_layer to be
initialized. Currently, init_unit(u) is equivalent to
ctrl_unit(NST_I_USER,u). However, the use of init_unit
should be avoided, since future changes may be desirable for
the definition of this routine.
If the layer has been created with mode=0 or mode=1, i.e.
if all internal som-units share a common input field X_in,
initialization mode will then persist for the next n calls
of exec_unit(u) that follow the call
ctrl_unit(NST_I_USER,u). The i -th of these calls
( i=0,1,2..n-1) will set the weight vector w[i][.] of the i-
th internal SOM-unit to the values that are present at the
input field X_in[] during that call. No adaptation and no
computation of output values occurs while the unit is in
initialization mode. After the n-1 -th call exec_unit(u)
(i.e. after a total of n calls, since numbering started with
0), initialization mode ends and the unit reverts to normal
operation.
If the layer has been created with mode=2 or mode=3, i.e.
if each internal SOM-unit i, i=0,1,..n-1 has its own input
field in_i, initialization mode will only persist for the
next single call of exec_unit(u) that follows the call
ctrl_unit(NST_I_USER,u). During that call, the values
present at the n input fields in_0..in_n-1 will be copied
into the n weight vectors w[i][.] (i=0,i,..n-1).
Currently, there is no way provided to specify the radii
(except for a load_unit-operation). They always start with
default values sig[k]=1, but may be adapted during operation
of the unit (see below).
LOAD AND SAVE:
The weights of a unit can be saved to a file by calling
save_unit(fp,u), where fp must be a file pointer to a file
opened for writing. The header section of the file has the
format described on the manual pages for routine fvinit.
The header section is followed by a parameter block containing
the weight parameters in the following order:
par: sig[0] win[0][0] win[0][1] ...
... win[0][din-1] sig[1] win[1][0] ...
... win[1][din-1] sig[2] win[2][0] ...
...
... win[n-1][din-1] aux[0] ... aux[n-1]
A shorter way to say the same is
par: Z_out[0] ... Z_out[n*(din+1)-1]
aux[0] ... aux[n-1]
Here, aux[0..n-1] are n auxiliary variables for internal
use, and n=dx*dy is the number of nodes.
The saved parameters (preceded by a header block in the for-
mat described for routine fvinit) can be read back into a
som_layer-unit v by calling load_unit(fp,v). Units u and v
need not be the same, however, they must have been created
with the same values for the numbers din,dx,dy.
DESCRIPTION:
Creates a layer of n SOM-units. Upon each call of exec_unit
this layer maps an din-dimensional input vector into a
n -dimensional activity pattern. The mapping operation is
identical to that of a layer created by constructor rbf_layer,
but the adaptation rule for the weights differs (see Section
ADAPTATION and below).
An optional multiplicative mask g1[.] (default values
g1[i]=1, i=0..din-1) may be specified (only one mask g1[]
that is common to all nodes can be specified). For each
node, the actual input "seen" is the original input vector
for that node, but componentwise multiplied with the
corresponding components of the vector g1[] (see the formulas
given in Sec. EXECUTION).
Similarly, a second mask g2[.] (default values g2[i]=1,
i=0..din-1) may be specified for scaling the components of
the adaptation step (in many cases, a sensible choice will
be to set g1=g2).
The node activities f_i become a linear (precisely: a convex)
combination of the old and of the newly computed
activities. The decay of the old activities is determined by
a decay factor (1-c), where c is the value at the control
pin CTL_in[0] (default is c=1). The newly computed activities
are multiplicatively scaled by the factor c and superimposed
over the decayed old activities. This has the
effect, that the nodes behave like leaky integrators with a
time constant of 1/c iteration steps. Special cases result
for c=1 and c=0. In the former case, the new activities completely
replace the old activities. This is the default
setting after creation of the unit. In the latter case, the
node activities retain their old values and the output does
not change (in fact, in this case, the internal computation
is suppressed; therefore, c=0 can be used to "switch the
unit off").
If mode=0 or 2, the node activities f_i specify the output
X_out directly. If mode=1 or 3, an additional multiplicative
normalization is performed, which normalizes the sum of
all outputs to unity.
If eps1 and eps2 are not both zero, each adapt-call will
perform a refinement step for the centers w[i] and for the
radii sig[i] as given by the formula in Section ADAPTATION.
While, apart from the additional return of the lattice location
of the minimal distance node, the mapping operation is
identical to that of unit rbf_layer, the above adaptation
step differs in the following way: for each node i, the
magnitude of the adaptation step is no longer determined by the
response of that node, but by the square R[ik] of the
euclidean lattice distance between i and the "best match"
node k=(xbest,ybest) determined during the forward pass.
The function h(.) can be specified by the user to determine
that functional dependence (usually, h(.) will be chosen to
be a decaying exponential [for this, the prespecified function
pointer FUN_EXPM may be used as value for argument h.
This is also the default if h=NULL, but other choices are
possible as well). For the additional "scaling radius"
sigma, the value at pin 2 of input field EPS_in is used.
The smoothing parameter beta can be used to control
the degree of overlap between the individual node responses.
Small values of beta result in large overlap, however, the
value beta=0 is special: for beta=0, the network operates in
"winner-take-all"-mode. In this mode, X_out[i]=0, except
for i=k, where X_out[k]=1 and k denotes the index of
the unit with minimal distance d[k] ("maximal response").
DEFAULT VALUES:
c=1, sigma ( =EPS_[2])=1, beta=0, g[i] =1, sig[i]=1,
w[i] initialized with NST_I_NOR, all other zero.
DEFAULTS:
f=FUN_EXPM, h=FUN_EXPM, if NULL -Pointers are specified.
SEE ALSO:
som_op, rbf_layer, bp_layer, delta_layer
FILE
/homes/jontrup/nst5/man/../o.sol2//../foldersrc/nst_adaptive.c