Thereâs a misconception in BaMI.
For each of these correctly active segments, reinforce the synapses that activated the segment, and punish the synapses that didnât contribute (lines 16-20).
It doesnât actually do that. The synapses that activated the segment arenât potential synapses, only connected synapses count for the activation of the segment.
The code in lines 16-20 reinforces both potential and connected synapses where the presynaptic cell belongs to the previous active cells while it punishes synapses where the presynaptic cell does not belong to the previous active cells.
Looking only at the receiving end works well in the first stage of the algorithm when choosing which cells to become active while applying learning rules.
In the second stage, when itâs time to determine which cells become predictive you have to inevitably go through every cell in the structure because thereâs no concept of âgiving sideâ only âreceiving sideâ.
My optimization works like this:
Every Segment class has values that state its precise location and both synapses that connect from and to it.
int index
int cellIndex
int columnIndex
array ingoingSynapses
array outgoingSynapses
Every Synapse class has values which essentially mean connect this parent to this child, a permanence and a uniqueID.
int parentSegmentIndex
int parentCellIndex
int parentColumnIndex
int childSegmentIndex
int childCellIndex
int childColumnIndex
float permanence
string uniqueID (random number from 0 to 999999)
Example
If the goal is to connect the first segment (index=0) of the second cell (cellIndex=1) in the third column (columnIndex=2) to the first segment (index=0) of the first cell (cellIndex=0) in the 100th column (columnIndex=99) two identical synapses (that share the same uniqueID) are stored in their correct places.
exampleSynapse
parentSegmentIndex = 0
parentCellIndex = 1
parentColumnIndex = 2
childSegmentIndex = 0
childCellIndex = 0
childColumnIndex = 99
permanence = 0.3
uniqueID = â430589â
Is stored in both:
parentSegment.outgoingSynapses (the segment at 0 of cell 1 in column 2)
childSegment.ingoingSynapses (the segment at 0 of cell 0 in column 99)
When its time for this procedure:
For each of these correctly active segments, reinforce the synapses that activated the segment, and punish the synapses that didnât contribute (lines 16-20).
The code in my implementation reinforces both the ingoingSynapses of the active segment (child) where their parent belongs to the previous active cells and the identical outgoingSynapses that belong to the corresponding segments (parent) of the previous active cells.
It punishes ingoingSynapses of the active segment (child) where their parent doesnât belong to the previous active cells. Then by using the parent information in the synapses themselves and the uniqueID it traces back to the correct segment (parent) of a cell (that doesnât belong to the previous active cells) and updates the outgoingSynapses there too without having to check every cell in the structure.
In the second stage, the ougoingSynapses in the segments of active cells predict the correct cells.
Now, that I think of it again the uniqueID probably isnât needed.