I have an idea for Simplified implementation of Grid cells layer, may be !!
You decide if I’m bit too clever for the wrong reason
What is left is the easy part i.e. how to ENCODE/DECODE this thing to/from SDR ?
lets start with some snippets from the paper .
To form a unique representation requires multiple grid cell
modules with different scales or orientations (Figures 1C,D).
For illustration purposes say we have 10 grid cell modules and
each module can encode 25 possible locations via a bump of
activity. These 10 bumps encode the current location of the
animal. Notice, if the animal moves continuously in one direction
the activity of individual modules will repeat due to the tiling, but
the ensemble activity of 10 modules is unlikely to repeat due to
the differences in scale and orientation between the modules. The
representational capacity formed by such a code is large. In our
example the number of unique locations that can be represented
is 25 10 ≈ 10 14 .
To summarize the above properties, a set of grid cell modules
can unambiguously represent locations in an environment.
These locations can be path integrated via movement, and
environmental landmarks are used to correct path integration
errors. By choosing random starting points within modules,
unique location spaces can be defined for each environment. The
space of all possible cell activations grows exponentially with the
number of modules, thus the capacity for representing locations
and environments is large.
So required property number one “unambiguously represent locations” i.e. many unique locations.
The idea is to use MODULO operation as a grid-module.
F.e. if we select 3 prime numbers 5,11,13 … we get unique location-coords, based on the reminders.
Second the loc-ids are tiled courtesy of mod-operation.
Third if you return back at a position you get the same unique ID.
Forth adding more primes increases the capacity.
Fifth starting from random value (position) gives us different sequence of reminders as we move around i.e. different maps
In [515]: [(i,list(i % np.array([5,11,13]))) for i in range(50,60)]
Out[515]:
[(50, [0, 6, 11]),
(51, [1, 7, 12]),
(52, [2, 8, 0]),
(53, [3, 9, 1]),
(54, [4, 10, 2]),
(55, [0, 0, 3]),
(56, [1, 1, 4]),
(57, [2, 2, 5]),
(58, [3, 3, 6]),
(59, [4, 4, 7])]
The first question that remains is how to ENCODE/DECODE the location-coords to/from SDR ?
This is 1D representation of integers i.e. if used to create grid-layer beside scaling it to N-dims we have to solve the problem of nudging it based on feedback from the Sense layer.
Here is how we do that :
1. decode the sense-SDR
2. using the reminders (location-coord) as input to Chinese-reminders-theorem with pairwise-coprimes (primes fit the bill) recover the integer value
Why this could work ? For 1D-integer MOVE-commands could be +X and -X steps, so we do not feed the command directly but instead calculate :
Curr-1D-pos + Move = new-pos
and pass this value as input.
The structure is :
|=----------------------------->|
[ L4-TM ] <=-=> [grid mod] <=-=> [ L6-TM ]
Let say we start with 55 :
init pos = 55
loc = (0,0,3) /modulo op/
convert loc => SDR1
pass SDR1 to L4 TM
sense SDR2
L4 TM : learn SDR1 => SDR2
pass SDR2 to L6 TM
move = +1
pos = 56
loc = (1,1,4)
conv loc => SDR3
predicted = predict(SDR2) /TM of L6/
merge = predicted * SDR3 => SDR4
reminders = conv(SDR4)
new_pos = CRT(reminders)
nudge : pos = new_pos
L6 TM : learn SDR2 => SDR4