|
| 1 | + |
| 2 | +(* |
| 3 | +
|
| 4 | +deeptemporalmemory.m |
| 5 | +
|
| 6 | +Mathematica implementation of a Deep Temporal Memory based on multiple triadic memory instances |
| 7 | +Copyright (c) 2022 Peter Overmann |
| 8 | +
|
| 9 | +Permission is hereby granted, free of charge, to any person obtaining a copy of this software |
| 10 | +and associated documentation files (the “Software”), to deal in the Software without restriction, |
| 11 | +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 12 | +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, |
| 13 | +subject to the following conditions: |
| 14 | +
|
| 15 | +The above copyright notice and this permission notice shall be included in all copies or substantial |
| 16 | +portions of the Software. |
| 17 | +
|
| 18 | +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT |
| 19 | +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| 20 | +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| 21 | +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE |
| 22 | +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 23 | +
|
| 24 | +
|
| 25 | +Requires TriadicMemory. |
| 26 | +
|
| 27 | +*) |
| 28 | + |
| 29 | + |
| 30 | + |
| 31 | +R[f_Symbol, {n_Integer, p_Integer} ] := Module[ {T, x, y, z, overlap}, |
| 32 | + |
| 33 | + (* instantiate a triadic memory unit *) |
| 34 | + |
| 35 | + TriadicMemory[ T, {n, p}]; |
| 36 | + |
| 37 | + overlap[a_SparseArray, b_SparseArray] := Total[BitAnd[a, b]]; |
| 38 | + |
| 39 | + x = y = z = SparseArray[{0}, {n}]; |
| 40 | + |
| 41 | + (* reset x, y, z if input is zero *) |
| 42 | + |
| 43 | + f[SparseArray[{0}, {n}]] := x = y = z = SparseArray[{0}, {n}]; |
| 44 | + |
| 45 | + f[input_SparseArray] := Module[ {}, |
| 46 | + |
| 47 | + x = BitOr[y, z]; (* binarize x and y using ranked-max algorithm *) |
| 48 | + y = input; |
| 49 | + |
| 50 | + If[Total[x] > 0 && overlap[T[_, y, z = T[x, y, _]], x] < p, T[x, y, z = T[]]]; |
| 51 | + |
| 52 | + z |
| 53 | + ] |
| 54 | + ]; |
| 55 | + |
| 56 | + |
| 57 | + |
| 58 | +TemporalMemory[t_Symbol, {n_Integer, p_Integer}] := |
| 59 | + |
| 60 | + Module[{M, R1, R2, R3, R4, R5, R6, R7, x, y, z, t1, t2, t3, t4, t5, t6, t7, t8}, |
| 61 | + |
| 62 | + (* predictions / readout memory *) |
| 63 | + TriadicMemory[M, {n, p}]; |
| 64 | + |
| 65 | + (* bigram encoder units *) |
| 66 | + R[ #, {n, p}] & /@ {R1, R2, R3, R4, R5, R6, R7 }; |
| 67 | + |
| 68 | + (* initialize state variables with null vectors *) |
| 69 | + x = y = z = t1 = t2 = t3 = t4 = t5 = t6 = t7 = M[0]; |
| 70 | + |
| 71 | + t[inp_] := Module[ {}, |
| 72 | + |
| 73 | + (* flush state if input is zero - needed when used as a sequence memory *) |
| 74 | + If[Total[inp] == 0, x = y = z = M[0]]; |
| 75 | + |
| 76 | + (* store new prediction if necessary *) |
| 77 | + If[z != inp, M[x, y, inp]]; |
| 78 | + |
| 79 | + (* encoding chain *) |
| 80 | + t1 = R1[inp]; |
| 81 | + t2 = R2[t1]; |
| 82 | + t3 = R3[t2]; |
| 83 | + t4 = R4[t3]; |
| 84 | + t5 = R5[t4]; |
| 85 | + t6 = R6[t5]; |
| 86 | + t7 = R7[t6]; |
| 87 | + |
| 88 | + (* prediction readout from t1, t2, t4 and t7 *) |
| 89 | + z = M[x = BitOr[t1, t4], y = BitOr[t2, t7], _] |
| 90 | + ] |
| 91 | + |
| 92 | + ]; |
| 93 | + |
0 commit comments