Topographica output_fns are composable using the + operator, which simply applies the output functions sequentially. For instance, LISSOM V1 Sheets typically use a PiecewiseLinear() output_fn, and noise can be added to this by setting the output_fn to PiecewiseLinear(...)+X(), where X() is an output function that adds noise. Others that have IdentityOF() by default can simply use the new output function instead of the old identity function. Suitable output functions for noise include variants of:
PatternCombine(generator=topo.patterns.random.UniformRandom(scale=1.0,offset=1.0),operator=numpy.multiply)where the scale and offset parameters determine the mean value and the range of the variation, respectively, the operator determines whether the noise is multiplicative, divisive, or some other type of combination, and the noise itself can either be Uniform or Gaussian (i.e., normal), or even some some user-defined distribution. There are also some other noise-related OutputFns available, such as ProportionalGaussian (variance proportional to the mean).
PatternCombine(generator=topo.patterns.random.GaussianRandom(scale=0.1,offset=-0.05),operator=numpy.add))
Hints: For additive noise, if you are modelling non-zero background levels of activity in a Sheet or Projection, you can use an offset of zero and a scale that is the level of noise you want. In other cases where you want to avoid changing the average activity levels, you can get zero-mean additive noise by making the offset be a negative number that is half of the scale. To keep the average activity levels constant with multiplicative noise requires an offset of 1.0-scale/2.0; the scale then determines the noise level. You can of course combine both types of noise in succession, in which case you will typically want to do the multiplicative noise first, to avoid scaling the additive noise.
As an example, to inject zero-mean additive uniform random noise into the LateralExcitatory Projection, just change e.g.
output_fn=IdentityOF()(if an output_fn is specified) to e.g.:
output_fn=IdentityOF()+PatternCombine(generator=topo.patterns.random.\ UniformRandom(scale=0.1,offset=-0.05),operator=numpy.add)(where in this case you could actually omit the "IdentityOF()+" because it doesn't do anything). Some networks may not state "output_fn=IdentityOF()" explicitly, in which case just add the entire string above to the definition of that projection in the .ty file. To see the results immediately, just run the network for one step, then visualize the Projection Activity and the final Activity. The long-term effects of this noise can then be evaluated by running for longer periods.
Another important way to add variability is to add jitter when the initial mapping between sheets is set up, i.e. to disturb the topographic mapping of a CFProjection's Connection Fields from the input sheet. The mapping of a CFProjection is controlled by a parameter "coord_mapper", which by default does a perfect topographic mapping that makes analysis easier, but is too ideal to be realistic. Instead, you can specify a jittered mapping for the CFProjection, by adding:
coord_mapper = Jitter(gen=UniformRandom(seed=1023),scale=0.2)to the topo.sim.connect command, to offset the values by a random amount in the range plus or minus 0.1 Sheet coordinates around the precisely topographic mapped value. The results can be visualized by plotting the Projection and enabling "Situate". Once set up, the jitter of the CF boundaries will always be present, but the weights inside the boundaries may reorganize to remove the effect of the jittering.
Note that the seed value allows you to control which specific pattern of jitter is used, e.g. if you want two different Projections of the same shape to have the same specific jittered values (e.g. for matching ON and OFF projections). Different seeds will allow the projections to be jittered independently of each other.
One could imagine the process of adjusting weights to be a stochastic or quantized process, either of which would give some variability to the process of updating weight values. For instance, this could be modeled with additive or multiplicative noise before or after any weight normalization. E.g., a script that uses CFPOF_DivisiveNormalizeL1_opt or CFPOF_DivisiveNormalizeL1 could be changed to:
CFProjection.weights_output_fn=CFPOF_DivisiveNormalizeL1(single_cf_fn=(\ PatternCombine(generator=topo.patterns.random.UniformRandom(scale=0.1,offset=-0.05),operator=numpy.add)+\ DivisiveNormalizeL1(norm_value=1.0)))(or those parameters could be set on a specific projection). To model noise arising in the normalization step itself, just exchange DivisiveNormalizeL1 and PatternCombine, or add another PatternCombine after DivisiveNormalizeL1.
Note that the weights_output_fn is used when setting up the initial weights, so if you mean for it to apply only to learning, you may want to add the noise only after the network has been initialized. For LISSOM networks this can be achieved by setting LISSOM.post_initialization_weights_output_fn instead of CFProjection.weights_output_fn.
The examples above focus on types of noise that are spatially uncorrelated, i.e. where the noise for each unit or weight or Connection Field is chosen independently of all others of that type. Many kinds of "noise" in biological systems will have spatial correlations, e.g. due to some underlying source that has a spatial extent (such as the vasculature, some diffusible chemical, etc.). To include such effects for the output_fn noise sources described above, you could add new classes in topo.patterns.random that generate spatially correlated noise rather than noise that is independent per pixel. E.g., the noise matrix could be convolved with a small blurring kernel before it is added or multiplied with the kernel, or the matrix could be low-pass filtered, e.g. to create the 1/f noise (pink noise) that is common in physical systems.
One could also consider the effects of measurement noise, e.g. on computing preference maps, which could be done by temporarily modifying the output_fn of each sheet so that what is measured is no longer the actual activity value, but a transformation of it. A better approach would probably be to add an output_fn parameter to the commands for measuring maps, so that such a function could be supplied for any measurement.
If there are any other types of noise that should be considered, please let me (Jim) know! It's probably easy enough to add it in Topographica...
Last update: noise.html,v 1.10 2009/02/23 11:23:41 jbednar Exp
Informatics Forum, 10 Crichton Street, Edinburgh, EH8 9AB, Scotland, UK
Tel: +44 131 651 5661, Fax: +44 131 651 1426, E-mail: school-office@inf.ed.ac.uk Please contact our webadmin with any comments or corrections. Logging and Cookies Unless explicitly stated otherwise, all material is copyright © The University of Edinburgh |