- todo
- paragraph
- description
- paragraph
- test of all properties that are described in Teuvo's paper
- paragraph
- abstract class which can also be used in order to implement the incomplete correlation matrix memory
- paragraph
- mutable version where values can be added and removed
- paragraph
- back end agnostic repository system
- paragraph
- repository distribution system
- paragraph
- Move this and related articles to a new project.
#!/usr/bin/env python3 """This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. Based on the paper "Correlation Matrix Memories" by TEUVO KOHONEN. """ __author__ = 'Mārtiņš Avots' from testingArtifacts import floatTuple import unittest class CompleteCorrelationMatrixMemory(): def __init__(self, keyValuePairs): for key in keyValuePairs: self.columns = len(key) self.rows = len(keyValuePairs[key]) break self.matrix = [[0. for i in range(self.columns)] for j in range(self.rows)] keyValuePairs = self.convertKeyValuePairs(keyValuePairs) for iRow in range(self.rows): for iColumn in range(self.columns): for key in keyValuePairs: c = self.c(key) # Deviation from TEUVO's paper value = keyValuePairs[key] self.matrix[iRow][iColumn] += c * key[iColumn] * value[iRow] def convertKeyValuePairs(self, keyValuePairs): rVal = dict() for key in keyValuePairs: value = keyValuePairs[key] key = tuple(floatTuple(key)) value = floatTuple(value) rVal[key] = value return rVal def c(self, vector): rBase = 0. for i in vector: rBase += i ** 2 return 1. / rBase def recall(self, key): key = floatTuple(key) value = [0.]*self.rows for iRow in range(len(value)): for iColumn in range(len(key)): value[iRow] self.matrix[iRow][iColumn] key[iColumn] value[iRow] += self.matrix[iRow][iColumn] * key[iColumn] return floatTuple(value) if __name__ == "__main__": from orthogonalKeyTests import OrthogonalKeyTests from randomKeyTests import RandomKeyTests from classificationTests import ClassificationTests unittest.main()
#!/usr/bin/env python3
"""This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
__author__ = 'Mārtiņš Avots'
from random import uniform, choice
def floatTuple(vector):
rVal = []
for e in vector:
rVal.append(float(e))
return rVal
def difference(a, b):
rVal = 0.
for i in range(len(a)):
rVal += abs(a[i] - b[i])
return rVal
def randomVector(length):
rVal = []
for i in range(length):
rVal.append(
uniform(-1000, 1000) # TODO Random chosen magic constants
)
return rVal
def randomZeroOneVector(length):
rVal = []
for i in range(length):
rVal.append(choice([0,1]))
return rVal
def randomZeroOnePositiveAndNegativeVector(length):
rVal = []
for i in range(length):
rVal.append(choice([-1,0,1]))
return rVal
def printImage(matrix, length):
rows=int(len(matrix) / length)
for row in range(rows):
rowStr = ""
for i in range(length):
rowStr += " " + str(round(matrix[row * length + i], 2))
print(rowStr)
print("")
images3x3 = {
"cross" : (1,0,1, 0,1,0, 1,0,1), # cross
"vertical" : (0,1,0, 0,1,0, 0,1,0), # vertical
"horizontal" : (0,0,0, 1,1,1, 0,0,0), # horizontal
"zero" : (1,1,1, 1,0,1, 1,1,1), # zero
"one" : (0,0,1, 0,1,1, 0,0,1), # one
"v" : (1,0,1, 1,0,1, 0,1,0), # v
"seven" : (1,1,1, 0,1,0, 1,0,0), # seven
"t" : (1,1,1, 0,1,0, 0,1,0), # t
"h" : (1,0,1, 1,1,1, 1,0,1) # h
}
#!/usr/bin/env python3
"""This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
Based on the paper "Correlation Matrix Memories" by TEUVO KOHONEN.
"""
__author__ = 'Mārtiņš Avots'
import unittest
from completeCorrelationMatrixMemories import CompleteCorrelationMatrixMemory
from testingArtifacts import randomVector, randomZeroOneVector, difference, images3x3, randomZeroOnePositiveAndNegativeVector
from random import uniform, sample
class RandomKeyTests(unittest.TestCase):
def testRandomKeys(self): # TODO This test fails randomly.
self.__randomKeysTest(9, 9, lambda:randomVector(9))
def testRandomZeroOneKeys(self): # TODO This test fails randomly.
self.__randomKeysTest(9, 9, lambda:randomZeroOnePositiveAndNegativeVector(9))
def __randomKeysTest(self, keySize, valueCount, randomKeyGenerator):
values = sample(list(images3x3.values()), valueCount)
mapping = {}
for i in range(valueCount):
tmpRandomVector = tuple(randomKeyGenerator())
while tmpRandomVector in mapping:
tmpRandomxVector = tuple(randomKeyGenerator())
mapping[tmpRandomVector] = values[i]
testSubject = CompleteCorrelationMatrixMemory(mapping)
overallDifference = 0.
for key in mapping:
overallDifference += difference(testSubject.recall(key), mapping[key])
meanDifference = overallDifference / (9 * 9)
print("testRandomKeys: meanDifference = " + str(meanDifference)) # TODO make logs instead of console prints
# Randomly generated vectors are assumed to be not orthogonal.
# TODO check orthogonality during test and change assertions accordingly
self.assertTrue(meanDifference < .6)
self.assertTrue(meanDifference > .4)
#!/usr/bin/env python3
"""This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
Based on the paper "Correlation Matrix Memories" by TEUVO KOHONEN.
"""
__author__ = 'Mārtiņš Avots'
from completeCorrelationMatrixMemories import CompleteCorrelationMatrixMemory
from unittest import TestCase, expectedFailure
from testingArtifacts import floatTuple, difference, images3x3
class ClassificationTests(TestCase):
# TODO high resolution image tests
def testClassificationOf2Images(self):
self.__testOrthogonalKeys({
images3x3["cross"] : (0,),
images3x3["zero"] : (2,),
})
def testClassificationOf2OtherImages(self):
self.__testOrthogonalKeys({
images3x3["cross"] : (0,),
images3x3["zero"] : (2,),
})
@expectedFailure
def testClassificationOf9Images(self):
"""It is not expected to work, as the keys are most propably not orthogonal"""
self.__testOrthogonalKeys({
images3x3["cross"] : (0,),
images3x3["vertical"] : (1,),
images3x3["horizontal"] : (2,),
images3x3["zero"] : (3,),
images3x3["one"] : (4,)
})
def __testOrthogonalKeys(self, mapping):
testSubject = CompleteCorrelationMatrixMemory(mapping)
for key in mapping:
self.assertEqual(mapping[key][0], self.__nearestNumber(mapping.values(), testSubject.recall(key)[0]))
def __nearestNumber(self, candidates, number):
"""Candidate is an tuple with 1 element."""
diff = 1000000000 # TODO magic number
candidate = None
for i in candidates:
currentDiff = abs(i[0] - number)
if currentDiff < diff:
diff = currentDiff
candidate = i[0]
return candidate
- todo
- paragraph
- Implementation