
org.numenta.nupic.Parameters Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of htm.java Show documentation
Show all versions of htm.java Show documentation
The Java version of Numenta's HTM technology
/* ---------------------------------------------------------------------
* Numenta Platform for Intelligent Computing (NuPIC)
* Copyright (C) 2014, Numenta, Inc. Unless you have an agreement
* with Numenta, Inc., for a separate license for this software code, the
* following terms and conditions apply:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses.
*
* http://numenta.org/licenses/
* ---------------------------------------------------------------------
*/
package org.numenta.nupic;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import org.joda.time.format.DateTimeFormatter;
import org.numenta.nupic.model.Cell;
import org.numenta.nupic.model.Column;
import org.numenta.nupic.model.DistalDendrite;
import org.numenta.nupic.research.ComputeCycle;
import org.numenta.nupic.research.SpatialPooler;
import org.numenta.nupic.research.TemporalMemory;
import org.numenta.nupic.util.ArrayUtils;
import org.numenta.nupic.util.BeanUtil;
import org.numenta.nupic.util.MersenneTwister;
import org.numenta.nupic.util.Tuple;
/**
* Specifies parameters to be used as a configuration for a given {@link TemporalMemory}
* or {@link SpatialPooler}
*
* @author David Ray
* @author Kirill Solovyev
* @see SpatialPooler
* @see TemporalMemory
* @see Connections
* @see ComputeCycle
*/
public class Parameters {
private static final Map DEFAULTS_ALL;
private static final Map DEFAULTS_TEMPORAL;
private static final Map DEFAULTS_SPATIAL;
private static final Map DEFAULTS_ENCODER;
static {
Map defaultParams = new ParametersMap();
/////////// Universal Parameters ///////////
defaultParams.put(KEY.SEED, 42);
defaultParams.put(KEY.RANDOM, new MersenneTwister((int)defaultParams.get(KEY.SEED)));
/////////// Temporal Memory Parameters ///////////
Map defaultTemporalParams = new ParametersMap();
defaultTemporalParams.put(KEY.COLUMN_DIMENSIONS, new int[]{2048});
defaultTemporalParams.put(KEY.CELLS_PER_COLUMN, 32);
defaultTemporalParams.put(KEY.ACTIVATION_THRESHOLD, 13);
defaultTemporalParams.put(KEY.LEARNING_RADIUS, 2048);
defaultTemporalParams.put(KEY.MIN_THRESHOLD, 10);
defaultTemporalParams.put(KEY.MAX_NEW_SYNAPSE_COUNT, 20);
defaultTemporalParams.put(KEY.INITIAL_PERMANENCE, 0.21);
defaultTemporalParams.put(KEY.CONNECTED_PERMANENCE, 0.5);
defaultTemporalParams.put(KEY.PERMANENCE_INCREMENT, 0.10);
defaultTemporalParams.put(KEY.PERMANENCE_DECREMENT, 0.10);
defaultTemporalParams.put(KEY.TM_VERBOSITY, 0);
defaultTemporalParams.put(KEY.LEARN, true);
DEFAULTS_TEMPORAL = Collections.unmodifiableMap(defaultTemporalParams);
defaultParams.putAll(DEFAULTS_TEMPORAL);
//////////// Spatial Pooler Parameters ///////////
Map defaultSpatialParams = new ParametersMap();
defaultSpatialParams.put(KEY.INPUT_DIMENSIONS, new int[]{64});
defaultSpatialParams.put(KEY.POTENTIAL_RADIUS, 16);
defaultSpatialParams.put(KEY.POTENTIAL_PCT, 0.5);
defaultSpatialParams.put(KEY.GLOBAL_INHIBITIONS, false);
defaultSpatialParams.put(KEY.INHIBITION_RADIUS, 0);
defaultSpatialParams.put(KEY.LOCAL_AREA_DENSITY, -1.0);
defaultSpatialParams.put(KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, 10.0);
defaultSpatialParams.put(KEY.STIMULUS_THRESHOLD, 0.0);
defaultSpatialParams.put(KEY.SYN_PERM_INACTIVE_DEC, 0.01);
defaultSpatialParams.put(KEY.SYN_PERM_ACTIVE_INC, 0.1);
defaultSpatialParams.put(KEY.SYN_PERM_CONNECTED, 0.10);
defaultSpatialParams.put(KEY.SYN_PERM_BELOW_STIMULUS_INC, 0.01);
defaultSpatialParams.put(KEY.SYN_PERM_TRIM_THRESHOLD, 0.5);
defaultSpatialParams.put(KEY.MIN_PCT_OVERLAP_DUTY_CYCLE, 0.001);
defaultSpatialParams.put(KEY.MIN_PCT_ACTIVE_DUTY_CYCLE, 0.001);
defaultSpatialParams.put(KEY.DUTY_CYCLE_PERIOD, 1000);
defaultSpatialParams.put(KEY.MAX_BOOST, 10.0);
defaultSpatialParams.put(KEY.SP_VERBOSITY, 0);
defaultSpatialParams.put(KEY.LEARN, true);
DEFAULTS_SPATIAL = Collections.unmodifiableMap(defaultSpatialParams);
defaultParams.putAll(DEFAULTS_SPATIAL);
/////////// Encoder Parameters ///////////
Map defaultEncoderParams = new ParametersMap();
defaultEncoderParams.put(KEY.N, 500);
defaultEncoderParams.put(KEY.W, 21);
defaultEncoderParams.put(KEY.MIN_VAL, 0.);
defaultEncoderParams.put(KEY.MAX_VAL, 1000.);
defaultEncoderParams.put(KEY.RADIUS, 21.);
defaultEncoderParams.put(KEY.RESOLUTION, 1.);
defaultEncoderParams.put(KEY.PERIODIC, false);
defaultEncoderParams.put(KEY.CLIP_INPUT, false);
defaultEncoderParams.put(KEY.FORCED, false);
defaultEncoderParams.put(KEY.FIELD_NAME, "UNSET");
defaultEncoderParams.put(KEY.FIELD_TYPE, "int");
defaultEncoderParams.put(KEY.ENCODER, "ScalarEncoder");
defaultEncoderParams.put(KEY.FIELD_ENCODING_MAP, Collections.emptyMap());
defaultEncoderParams.put(KEY.AUTO_CLASSIFY, Boolean.FALSE);
DEFAULTS_ENCODER = Collections.unmodifiableMap(defaultEncoderParams);
defaultParams.putAll(DEFAULTS_ENCODER);
DEFAULTS_ALL = Collections.unmodifiableMap(defaultParams);
}
/**
* Constant values representing configuration parameters for the {@link TemporalMemory}
*/
public static enum KEY {
/////////// Universal Parameters ///////////
/**
* Total number of columns
*/
COLUMN_DIMENSIONS("columnDimensions", int[].class),
/**
* Total number of cells per column
*/
CELLS_PER_COLUMN("cellsPerColumn", Integer.class, 1, null),
/**
* Learning variable
*/
LEARN("learn", Boolean.class),
/**
* Random Number Generator
*/
RANDOM("random", Random.class),
/**
* Seed for random number generator
*/
SEED("seed", Integer.class),
/////////// Temporal Memory Parameters ///////////
/**
* If the number of active connected synapses on a segment
* is at least this threshold, the segment is said to be active.
*/
ACTIVATION_THRESHOLD("activationThreshold", Integer.class, 0, null),
/**
* Radius around cell from which it can
* sample to form distal {@link DistalDendrite} connections.
*/
LEARNING_RADIUS("learningRadius", Integer.class, 0, null),
/**
* If the number of synapses active on a segment is at least this
* threshold, it is selected as the best matching
* cell in a bursting column.
*/
MIN_THRESHOLD("minThreshold", Integer.class, 0, null),
/**
* The maximum number of synapses added to a segment during learning.
*/
MAX_NEW_SYNAPSE_COUNT("maxNewSynapseCount", Integer.class),
/**
* Initial permanence of a new synapse
*/
INITIAL_PERMANENCE("initialPermanence", Double.class, 0.0, 1.0),
/**
* If the permanence value for a synapse
* is greater than this value, it is said
* to be connected.
*/
CONNECTED_PERMANENCE("connectedPermanence", Double.class, 0.0, 1.0),
/**
* Amount by which permanence of synapses
* are incremented during learning.
*/
PERMANENCE_INCREMENT("permanenceIncrement", Double.class, 0.0, 1.0),
/**
* Amount by which permanences of synapses
* are decremented during learning.
*/
PERMANENCE_DECREMENT("permanenceDecrement", Double.class, 0.0, 1.0),
TM_VERBOSITY("tmVerbosity", Integer.class, 0, 10),
/////////// Spatial Pooler Parameters ///////////
INPUT_DIMENSIONS("inputDimensions", int[].class),
POTENTIAL_RADIUS("potentialRadius", Integer.class),
POTENTIAL_PCT("potentialPct", Double.class), //TODO add range here?
GLOBAL_INHIBITIONS("globalInhibition", Boolean.class),
INHIBITION_RADIUS("inhibitionRadius", Integer.class, 0, null),
LOCAL_AREA_DENSITY("localAreaDensity", Double.class), //TODO add range here?
NUM_ACTIVE_COLUMNS_PER_INH_AREA("numActiveColumnsPerInhArea", Double.class),//TODO add range here?
STIMULUS_THRESHOLD("stimulusThreshold", Double.class), //TODO add range here?
SYN_PERM_INACTIVE_DEC("synPermInactiveDec", Double.class, 0.0, 1.0),
SYN_PERM_ACTIVE_INC("synPermActiveInc", Double.class, 0.0, 1.0),
SYN_PERM_CONNECTED("synPermConnected", Double.class, 0.0, 1.0),
SYN_PERM_BELOW_STIMULUS_INC("synPermBelowStimulusInc", Double.class, 0.0, 1.0),
SYN_PERM_TRIM_THRESHOLD("synPermTrimThreshold", Double.class, 0.0, 1.0),
MIN_PCT_OVERLAP_DUTY_CYCLE("minPctOverlapDutyCycles", Double.class),//TODO add range here?
MIN_PCT_ACTIVE_DUTY_CYCLE("minPctActiveDutyCycles", Double.class),//TODO add range here?
DUTY_CYCLE_PERIOD("dutyCyclePeriod", Integer.class),//TODO add range here?
MAX_BOOST("maxBoost", Double.class), //TODO add range here?
SP_VERBOSITY("spVerbosity", Integer.class, 0, 10),
///////////// SpatialPooler / Network Parameter(s) /////////////
/** Number of cycles to send through the SP before forwarding data to the rest of the network. */
SP_PRIMER_DELAY("sp_primer_delay", Integer.class),
///////////// Encoder Parameters //////////////
/** number of bits in the representation (must be >= w) */
N("n", Integer.class),
/**
* The number of bits that are set to encode a single value - the
* "width" of the output signal
*/
W("w", Integer.class),
/** The minimum value of the input signal. */
MIN_VAL("minVal", Double.class),
/** The maximum value of the input signal. */
MAX_VAL("maxVal", Double.class),
/**
* inputs separated by more than, or equal to this distance will have non-overlapping
* representations
*/
RADIUS("radius", Double.class),
/** inputs separated by more than, or equal to this distance will have different representations */
RESOLUTION("resolution", Double.class),
/**
* If true, then the input value "wraps around" such that minval = maxval
* For a periodic value, the input must be strictly less than maxval,
* otherwise maxval is a true upper bound.
*/
PERIODIC("periodic", Boolean.class),
/**
* if true, non-periodic inputs smaller than minval or greater
* than maxval will be clipped to minval/maxval
*/
CLIP_INPUT("clipInput", Boolean.class),
/**
* If true, skip some safety checks (for compatibility reasons), default false
* Mostly having to do with being able to set the window size < 21
*/
FORCED("forced", Boolean.class),
/** Name of the field being encoded */
FIELD_NAME("fieldName", String.class),
/** Primitive type of the field, used to auto-configure the type of encoder */
FIELD_TYPE("fieldType", String.class),
/** Encoder name */
ENCODER("encoderType", String.class),
/** Designates holder for the Multi Encoding Map */
FIELD_ENCODING_MAP("fieldEncodings", Map.class),
CATEGORY_LIST("categoryList", List.class),
// Network Layer indicator for auto classifier generation
AUTO_CLASSIFY("hasClassifiers", Boolean.class),
// How many bits to use if encoding the respective date fields.
// e.g. Tuple(bits to use:int, radius:double)
DATEFIELD_SEASON("season", Tuple.class),
DATEFIELD_DOFW("dayOfWeek", Tuple.class),
DATEFIELD_WKEND("weekend", Tuple.class),
DATEFIELD_HOLIDAY("holiday", Tuple.class),
DATEFIELD_TOFD("timeOfDay", Tuple.class),
DATEFIELD_CUSTOM("customDays", Tuple.class), // e.g. Tuple(bits:int, List:"mon,tue,fri")
DATEFIELD_PATTERN("formatPattern", String.class),
DATEFIELD_FORMATTER("dateFormatter", DateTimeFormatter.class);
private static final Map fieldMap = new HashMap<>();
static {
for (KEY key : KEY.values()) {
fieldMap.put(key.getFieldName(), key);
}
}
public static KEY getKeyByFieldName(String fieldName) {
return fieldMap.get(fieldName);
}
final private String fieldName;
final private Class> fieldType;
final private Number min;
final private Number max;
/**
* Constructs a new KEY
*
* @param fieldName
* @param fieldType
*/
private KEY(String fieldName, Class> fieldType) {
this(fieldName, fieldType, null, null);
}
/**
* Constructs a new KEY with range check
*
* @param fieldName
* @param fieldType
* @param min
* @param max
*/
private KEY(String fieldName, Class> fieldType, Number min, Number max) {
this.fieldName = fieldName;
this.fieldType = fieldType;
this.min = min;
this.max = max;
}
public Class> getFieldType() {
return fieldType;
}
public String getFieldName() {
return fieldName;
}
public Number getMin() {
return min;
}
public Number getMax() {
return max;
}
public boolean checkRange(Number value) {
if (value == null) {
throw new IllegalArgumentException("checkRange argument can not be null");
}
return (min == null && max == null) ||
(min != null && max == null && min.doubleValue() <= value.doubleValue()) ||
(max != null && min == null && value.doubleValue() < value.doubleValue()) ||
(min != null && min.doubleValue() <= value.doubleValue() && max != null && value.doubleValue() < max.doubleValue());
}
}
/**
* Save guard decorator around params map
*/
private static class ParametersMap extends EnumMap {
/**
* Default serialvers
*/
private static final long serialVersionUID = 1L;
ParametersMap() {
super(Parameters.KEY.class);
}
@Override public Object put(KEY key, Object value) {
if (value != null) {
if (!key.getFieldType().isInstance(value)) {
throw new IllegalArgumentException(
"Can not set Parameters Property '" + key.getFieldName() + "' because of type mismatch. The required type is " + key.getFieldType());
}
if (value instanceof Number && !key.checkRange((Number)value)) {
throw new IllegalArgumentException(
"Can not set Parameters Property '" + key.getFieldName() + "' because of value '" + value + "' not in range. Range[" + key.getMin() + "-" + key.getMax() + "]");
}
}
return super.put(key, value);
}
}
/**
* Map of parameters to their values
*/
private final Map paramMap = Collections.synchronizedMap(new ParametersMap());
//TODO apply from container to parameters
/**
* Returns the size of the internal parameter storage.
* @return
*/
public int size() {
return paramMap.size();
}
/**
* Factory method. Return global {@link Parameters} object with default values
*
* @return {@link Parameters} object
*/
public static Parameters getAllDefaultParameters() {
return getParameters(DEFAULTS_ALL);
}
/**
* Factory method. Return temporal {@link Parameters} object with default values
*
* @return {@link Parameters} object
*/
public static Parameters getTemporalDefaultParameters() {
return getParameters(DEFAULTS_TEMPORAL);
}
/**
* Factory method. Return spatial {@link Parameters} object with default values
*
* @return {@link Parameters} object
*/
public static Parameters getSpatialDefaultParameters() {
return getParameters(DEFAULTS_SPATIAL);
}
/**
* Factory method. Return Encoder {@link Parameters} object with default values
* @return
*/
public static Parameters getEncoderDefaultParameters() {
return getParameters(DEFAULTS_ENCODER);
}
/**
* Called internally to populate a {@link Parameters} object with the keys
* and values specified in the passed in map.
*
* @return {@link Parameters} object
*/
private static Parameters getParameters(Map map) {
Parameters result = new Parameters();
for (KEY key : map.keySet()) {
result.setParameterByKey(key, map.get(key));
}
return result;
}
/**
* Constructs a new {@code Parameters} object.
* It is private. Only allow instantiation with Factory methods.
* This way we will never have erroneous Parameters with missing attributes
*/
private Parameters() {
}
/**
* Sets the fields specified by this {@code Parameters} on the specified
* {@link Connections} object.
*
* @param cn
*/
public void apply(Object cn) {
BeanUtil beanUtil = BeanUtil.getInstance();
Set presentKeys = paramMap.keySet();
synchronized (paramMap) {
for (KEY key : presentKeys) {
beanUtil.setSimpleProperty(cn, key.fieldName, getParameterByKey(key));
}
}
}
/**
* Copies the specified parameters into this {@code Parameters}
* object over writing the intersecting keys and values.
* @param p the Parameters to perform a union with.
* @return this Parameters object combined with the specified
* Parameters object.
*/
public Parameters union(Parameters p) {
for(KEY k : p.paramMap.keySet()) {
setParameterByKey(k, p.getParameterByKey(k));
}
return this;
}
/**
* Returns a Set view of the keys in this {@code Parameter}s
* object
* @return
*/
public Set keys() {
Set retVal = paramMap.keySet();
return retVal;
}
/**
* Returns a separate instance of the specified {@code Parameters} object.
* @return a unique instance.
*/
public Parameters copy() {
return new Parameters().union(this);
}
/**
* Returns an empty instance of {@code Parameters};
* @return
*/
public static Parameters empty() {
return new Parameters();
}
/**
* Set parameter by Key{@link KEY}
*
* @param key
* @param value
*/
public void setParameterByKey(KEY key, Object value) {
paramMap.put(key, value);
}
/**
* Get parameter by Key{@link KEY}
*
* @param key
* @return
*/
public Object getParameterByKey(KEY key) {
return paramMap.get(key);
}
/**
* @param key IMPORTANT! This is a nuclear option, should be used with care.
* Will knockout key's parameter from map and compromise integrity
*/
public void clearParameter(KEY key) {
paramMap.remove(key);
}
/**
* Convenience method to log difference this {@code Parameters} and specified
* {@link Connections} object.
*
* @param cn
* @return true if find it different
*/
public boolean logDiff(Object cn) {
if (cn == null) {
throw new IllegalArgumentException("cn Object is required and can not be null");
}
boolean result = false;
BeanUtil beanUtil = BeanUtil.getInstance();
BeanUtil.PropertyInfo[] properties = beanUtil.getPropertiesInfoForBean(cn.getClass());
for (int i = 0; i < properties.length; i++) {
BeanUtil.PropertyInfo property = properties[i];
String fieldName = property.getName();
KEY propKey = KEY.getKeyByFieldName(property.getName());
if (propKey != null) {
Object paramValue = this.getParameterByKey(propKey);
Object cnValue = beanUtil.getSimpleProperty(cn, fieldName);
if ((paramValue != null && !paramValue.equals(cnValue)) || (paramValue == null && cnValue != null)) {
result = true;
System.out.println(
"Property:" + fieldName + " is different - CN:" + cnValue + " | PARAM:" + paramValue);
}
}
}
return result;
}
//TODO I'm not sure we need maintain implicit setters below. Kinda contradict unified access with KEYs
/**
* Returns the seeded random number generator.
*
* @param r the generator to use.
*/
public void setRandom(Random r) {
paramMap.put(KEY.RANDOM, r);
}
/**
* Sets the number of {@link Column}.
*
* @param columnDimensions
*/
public void setColumnDimensions(int[] columnDimensions) {
paramMap.put(KEY.COLUMN_DIMENSIONS, columnDimensions);
}
/**
* Sets the number of {@link Cell}s per {@link Column}
*
* @param cellsPerColumn
*/
public void setCellsPerColumn(int cellsPerColumn) {
paramMap.put(KEY.CELLS_PER_COLUMN, cellsPerColumn);
}
/**
* Sets the activation threshold.
*
* If the number of active connected synapses on a segment
* is at least this threshold, the segment is said to be active.
*
* @param activationThreshold
*/
public void setActivationThreshold(int activationThreshold) {
paramMap.put(KEY.ACTIVATION_THRESHOLD, activationThreshold);
}
/**
* Radius around cell from which it can
* sample to form distal dendrite connections.
*
* @param learningRadius
*/
public void setLearningRadius(int learningRadius) {
paramMap.put(KEY.LEARNING_RADIUS, learningRadius);
}
/**
* If the number of synapses active on a segment is at least this
* threshold, it is selected as the best matching
* cell in a bursting column.
*
* @param minThreshold
*/
public void setMinThreshold(int minThreshold) {
paramMap.put(KEY.MIN_THRESHOLD, minThreshold);
}
/**
* The maximum number of synapses added to a segment during learning.
*
* @param maxNewSynapseCount
*/
public void setMaxNewSynapseCount(int maxNewSynapseCount) {
paramMap.put(KEY.MAX_NEW_SYNAPSE_COUNT, maxNewSynapseCount);
}
/**
* Seed for random number generator
*
* @param seed
*/
public void setSeed(int seed) {
paramMap.put(KEY.SEED, seed);
}
/**
* Initial permanence of a new synapse
*
* @param
*/
public void setInitialPermanence(double initialPermanence) {
paramMap.put(KEY.INITIAL_PERMANENCE, initialPermanence);
}
/**
* If the permanence value for a synapse
* is greater than this value, it is said
* to be connected.
*
* @param connectedPermanence
*/
public void setConnectedPermanence(double connectedPermanence) {
paramMap.put(KEY.CONNECTED_PERMANENCE, connectedPermanence);
}
/**
* Amount by which permanences of synapses
* are incremented during learning.
*
* @param permanenceIncrement
*/
public void setPermanenceIncrement(double permanenceIncrement) {
paramMap.put(KEY.PERMANENCE_INCREMENT, permanenceIncrement);
}
/**
* Amount by which permanences of synapses
* are decremented during learning.
*
* @param permanenceDecrement
*/
public void setPermanenceDecrement(double permanenceDecrement) {
paramMap.put(KEY.PERMANENCE_DECREMENT, permanenceDecrement);
}
////////////////////////////// SPACIAL POOLER PARAMS //////////////////////////////////
/**
* A list representing the dimensions of the input
* vector. Format is [height, width, depth, ...], where
* each value represents the size of the dimension. For a
* topology of one dimension with 100 inputs use 100, or
* [100]. For a two dimensional topology of 10x5 use
* [10,5].
*
* @param inputDimensions
*/
public void setInputDimensions(int[] inputDimensions) {
paramMap.put(KEY.INPUT_DIMENSIONS, inputDimensions);
}
/**
* This parameter determines the extent of the input
* that each column can potentially be connected to.
* This can be thought of as the input bits that
* are visible to each column, or a 'receptiveField' of
* the field of vision. A large enough value will result
* in 'global coverage', meaning that each column
* can potentially be connected to every input bit. This
* parameter defines a square (or hyper square) area: a
* column will have a max square potential pool with
* sides of length 2 * potentialRadius + 1.
*
* @param potentialRadius
*/
public void setPotentialRadius(int potentialRadius) {
paramMap.put(KEY.POTENTIAL_RADIUS, potentialRadius);
}
/**
* The inhibition radius determines the size of a column's local
* neighborhood. of a column. A cortical column must overcome the overlap
* score of columns in his neighborhood in order to become actives. This
* radius is updated every learning round. It grows and shrinks with the
* average number of connected synapses per column.
*
* @param inhibitionRadius the local group size
*/
public void setInhibitionRadius(int inhibitionRadius) {
paramMap.put(KEY.INHIBITION_RADIUS, inhibitionRadius);
}
/**
* The percent of the inputs, within a column's
* potential radius, that a column can be connected to.
* If set to 1, the column will be connected to every
* input within its potential radius. This parameter is
* used to give each column a unique potential pool when
* a large potentialRadius causes overlap between the
* columns. At initialization time we choose
* ((2*potentialRadius + 1)^(# inputDimensions) *
* potentialPct) input bits to comprise the column's
* potential pool.
*
* @param potentialPct
*/
public void setPotentialPct(double potentialPct) {
paramMap.put(KEY.POTENTIAL_PCT, potentialPct);
}
/**
* If true, then during inhibition phase the winning
* columns are selected as the most active columns from
* the region as a whole. Otherwise, the winning columns
* are selected with respect to their local
* neighborhoods. Using global inhibition boosts
* performance x60.
*
* @param globalInhibition
*/
public void setGlobalInhibition(boolean globalInhibition) {
paramMap.put(KEY.GLOBAL_INHIBITIONS, globalInhibition);
}
/**
* The desired density of active columns within a local
* inhibition area (the size of which is set by the
* internally calculated inhibitionRadius, which is in
* turn determined from the average size of the
* connected potential pools of all columns). The
* inhibition logic will insure that at most N columns
* remain ON within a local inhibition area, where N =
* localAreaDensity * (total number of columns in
* inhibition area).
*
* @param localAreaDensity
*/
public void setLocalAreaDensity(double localAreaDensity) {
paramMap.put(KEY.LOCAL_AREA_DENSITY, localAreaDensity);
}
/**
* An alternate way to control the density of the active
* columns. If numActivePerInhArea is specified then
* localAreaDensity must be less than 0, and vice versa.
* When using numActivePerInhArea, the inhibition logic
* will insure that at most 'numActivePerInhArea'
* columns remain ON within a local inhibition area (the
* size of which is set by the internally calculated
* inhibitionRadius, which is in turn determined from
* the average size of the connected receptive fields of
* all columns). When using this method, as columns
* learn and grow their effective receptive fields, the
* inhibitionRadius will grow, and hence the net density
* of the active columns will *decrease*. This is in
* contrast to the localAreaDensity method, which keeps
* the density of active columns the same regardless of
* the size of their receptive fields.
*
* @param numActiveColumnsPerInhArea
*/
public void setNumActiveColumnsPerInhArea(double numActiveColumnsPerInhArea) {
paramMap.put(KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, numActiveColumnsPerInhArea);
}
/**
* This is a number specifying the minimum number of
* synapses that must be on in order for a columns to
* turn ON. The purpose of this is to prevent noise
* input from activating columns. Specified as a percent
* of a fully grown synapse.
*
* @param stimulusThreshold
*/
public void setStimulusThreshold(double stimulusThreshold) {
paramMap.put(KEY.STIMULUS_THRESHOLD, stimulusThreshold);
}
/**
* The amount by which an inactive synapse is
* decremented in each round. Specified as a percent of
* a fully grown synapse.
*
* @param synPermInactiveDec
*/
public void setSynPermInactiveDec(double synPermInactiveDec) {
paramMap.put(KEY.SYN_PERM_INACTIVE_DEC, synPermInactiveDec);
}
/**
* The amount by which an active synapse is incremented
* in each round. Specified as a percent of a
* fully grown synapse.
*
* @param synPermActiveInc
*/
public void setSynPermActiveInc(double synPermActiveInc) {
paramMap.put(KEY.SYN_PERM_ACTIVE_INC, synPermActiveInc);
}
/**
* The default connected threshold. Any synapse whose
* permanence value is above the connected threshold is
* a "connected synapse", meaning it can contribute to
* the cell's firing.
*
* @param synPermConnected
*/
public void setSynPermConnected(double synPermConnected) {
paramMap.put(KEY.SYN_PERM_CONNECTED, synPermConnected);
}
/**
* Sets the increment of synapse permanences below the stimulus
* threshold
*
* @param synPermBelowStimulusInc
*/
public void setSynPermBelowStimulusInc(double synPermBelowStimulusInc) {
paramMap.put(KEY.SYN_PERM_BELOW_STIMULUS_INC, synPermBelowStimulusInc);
}
/**
* @param synPermTrimThreshold
*/
public void setSynPermTrimThreshold(double synPermTrimThreshold) {
paramMap.put(KEY.SYN_PERM_TRIM_THRESHOLD, synPermTrimThreshold);
}
/**
* A number between 0 and 1.0, used to set a floor on
* how often a column should have at least
* stimulusThreshold active inputs. Periodically, each
* column looks at the overlap duty cycle of
* all other columns within its inhibition radius and
* sets its own internal minimal acceptable duty cycle
* to: minPctDutyCycleBeforeInh * max(other columns'
* duty cycles).
* On each iteration, any column whose overlap duty
* cycle falls below this computed value will get
* all of its permanence values boosted up by
* synPermActiveInc. Raising all permanences in response
* to a sub-par duty cycle before inhibition allows a
* cell to search for new inputs when either its
* previously learned inputs are no longer ever active,
* or when the vast majority of them have been
* "hijacked" by other columns.
*
* @param minPctOverlapDutyCycles
*/
public void setMinPctOverlapDutyCycle(double minPctOverlapDutyCycles) {
paramMap.put(KEY.MIN_PCT_OVERLAP_DUTY_CYCLE, minPctOverlapDutyCycles);
}
/**
* A number between 0 and 1.0, used to set a floor on
* how often a column should be activate.
* Periodically, each column looks at the activity duty
* cycle of all other columns within its inhibition
* radius and sets its own internal minimal acceptable
* duty cycle to:
* minPctDutyCycleAfterInh *
* max(other columns' duty cycles).
* On each iteration, any column whose duty cycle after
* inhibition falls below this computed value will get
* its internal boost factor increased.
*
* @param minPctActiveDutyCycles
*/
public void setMinPctActiveDutyCycle(double minPctActiveDutyCycles) {
paramMap.put(KEY.MIN_PCT_ACTIVE_DUTY_CYCLE, minPctActiveDutyCycles);
}
/**
* The period used to calculate duty cycles. Higher
* values make it take longer to respond to changes in
* boost or synPerConnectedCell. Shorter values make it
* more unstable and likely to oscillate.
*
* @param dutyCyclePeriod
*/
public void setDutyCyclePeriod(int dutyCyclePeriod) {
paramMap.put(KEY.DUTY_CYCLE_PERIOD, dutyCyclePeriod);
}
/**
* The maximum overlap boost factor. Each column's
* overlap gets multiplied by a boost factor
* before it gets considered for inhibition.
* The actual boost factor for a column is number
* between 1.0 and maxBoost. A boost factor of 1.0 is
* used if the duty cycle is >= minOverlapDutyCycle,
* maxBoost is used if the duty cycle is 0, and any duty
* cycle in between is linearly extrapolated from these
* 2 end points.
*
* @param maxBoost
*/
public void setMaxBoost(double maxBoost) {
paramMap.put(KEY.MAX_BOOST, maxBoost);
}
/**
* spVerbosity level: 0, 1, 2, or 3
*
* @param spVerbosity
*/
public void setSpVerbosity(int spVerbosity) {
paramMap.put(KEY.SP_VERBOSITY, spVerbosity);
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
StringBuilder result = new StringBuilder("{\n");
StringBuilder spatialInfo = new StringBuilder();
StringBuilder temporalInfo = new StringBuilder();
StringBuilder otherInfo = new StringBuilder();
this.paramMap.keySet();
for (KEY key : paramMap.keySet()) {
if (DEFAULTS_SPATIAL.containsKey(key)) {
buildParamStr(spatialInfo, key);
} else if (DEFAULTS_TEMPORAL.containsKey(key)) {
buildParamStr(temporalInfo, key);
} else {
buildParamStr(otherInfo, key);
}
}
if (spatialInfo.length() > 0) {
result.append("\tSpatial: {\n").append(spatialInfo).append("\t}\n");
}
if (temporalInfo.length() > 0) {
result.append("\tTemporal: {\n").append(temporalInfo).append("\t}\n");
}
if (otherInfo.length() > 0) {
result.append("\tOther: {\n").append(otherInfo).append("\t}\n");
}
return result.append("}").toString();
}
private void buildParamStr(StringBuilder spatialInfo, KEY key) {
Object value = getParameterByKey(key);
if (value instanceof int[]) {
value = ArrayUtils.intArrayToString(value);
}
spatialInfo.append("\t\t").append(key.getFieldName()).append(":").append(value).append("\n");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy