/** * The primary method in charge of learning. Adapts the permanence values of the synapses based on * the input vector, and the chosen columns after inhibition round. Permanence values are * increased for synapses connected to input bits that are turned on, and decreased for synapses * connected to inputs bits that are turned off. * * @param c the {@link Connections} (spatial pooler memory) * @param inputVector a integer array that comprises the input to the spatial pooler. There exists * an entry in the array for every input bit. * @param activeColumns an array containing the indices of the columns that survived inhibition. */ public void adaptSynapses(Connections c, int[] inputVector, int[] activeColumns) { int[] inputIndices = ArrayUtils.where(inputVector, ArrayUtils.INT_GREATER_THAN_0); double[] permChanges = new double[c.getNumInputs()]; Arrays.fill(permChanges, -1 * c.getSynPermInactiveDec()); ArrayUtils.setIndexesTo(permChanges, inputIndices, c.getSynPermActiveInc()); for (int i = 0; i < activeColumns.length; i++) { Pool pool = c.getPotentialPools().get(activeColumns[i]); double[] perm = pool.getDensePermanences(c); int[] indexes = pool.getSparsePotential(); ArrayUtils.raiseValuesBy(permChanges, perm); Column col = c.getColumn(activeColumns[i]); updatePermanencesForColumn(c, perm, col, indexes, true); } }
@Test public void testGetDensePotential() { Connections connections = new Connections(); connections.setNumInputs(10); Pool pool = new Pool(3); Synapse[] synapses = new Synapse[3]; int[] connecteds = new int[] {0, 1, 0, 0, 1, 1, 0, 1, 0, 1}; for (int i = 0, j = 0; i < connecteds.length; i++) { if (connecteds[i] == 0) continue; synapses[j] = new Synapse(connections, null, null, pool, i, i); synapses[j].setPermanence( connections, 0.0); // 0.0 -> These aren't set as connected but simply members. } int[] expected = {0, 1, 0, 0, 1, 1, 0, 1, 0, 1}; int[] dense = pool.getDensePotential(connections); assertTrue(Arrays.equals(expected, dense)); }
/** * This method increases the permanence values of synapses of columns whose activity level has * been too low. Such columns are identified by having an overlap duty cycle that drops too much * below those of their peers. The permanence values for such columns are increased. * * @param c */ public void bumpUpWeakColumns(final Connections c) { int[] weakColumns = ArrayUtils.where( c.getMemory().get1DIndexes(), new Condition.Adapter<Integer>() { @Override public boolean eval(int i) { return c.getOverlapDutyCycles()[i] < c.getMinOverlapDutyCycles()[i]; } }); for (int i = 0; i < weakColumns.length; i++) { Pool pool = c.getPotentialPools().get(weakColumns[i]); double[] perm = pool.getSparsePermanences(); ArrayUtils.raiseValuesBy(c.getSynPermBelowStimulusInc(), perm); int[] indexes = pool.getSparsePotential(); Column col = c.getColumn(weakColumns[i]); updatePermanencesForColumnSparse(c, perm, col, indexes, true); } }
@Test public void testGetDenseConnected() { Connections connections = new Connections(); connections.setSynPermConnected(0.2d); connections.setNumInputs(5); Pool pool = new Pool(3); Synapse[] synapses = new Synapse[3]; double[] perms = new double[] {0.0, 0.2, 0.0, 0.2, 0.2}; for (int i = 0, j = 0; i < perms.length; i++) { if (perms[i] == 0) continue; synapses[j] = new Synapse(connections, null, null, pool, i, i); synapses[j++].setPermanence(connections, perms[i]); } int[] expected = {0, 1, 0, 1, 1}; int[] dense = pool.getDenseConnected(connections); assertTrue(Arrays.equals(expected, dense)); int[] expected2 = {0, 1, 0, 1, 0}; // expect last bit below synPermConnected synapses[2].setPermanence(connections, 0.19d); // set last bit below synPermConnected dense = pool.getDenseConnected(connections); assertTrue(Arrays.equals(expected2, dense)); }