我正在尝试为字母识别构建一个 Hopfield Network 解决方案。我正在用 Python 做这件事。我的代码如下:正如您在输出中看到的 - 它始终是相同的模式,它是训练集之一。
#!/usr/bin/env python
import random
import copy
import math
def GenCorelationMatrix(letters):
''' Assume all letters are same length
The main diagon filled with zeros'''
oneLetterLen = len(letters[0][0])
matrix = [[0 for x in xrange(oneLetterLen)] for x in xrange(oneLetterLen)]
for col1 in range(oneLetterLen-1):
matrix[col1][col1] = 0
for col2 in range(col1+1,oneLetterLen):
value = 0
for row in letters:
for letter in row:
if letter[col1] == letter[col2]:
value += 1
else:
value -= 1
matrix[col1][col2] = value
matrix[col2][col1] = value
return matrix
def MutateLetter(letter, percentOfMutation):
'''
Get a letter - 1d array of binary chars
returns the same letter but with percentOfMutation
'''
samplesNumber = len(letter) * percentOfMutation / 100
indexesToChange = random.sample(xrange(len(letter)), samplesNumber)
mutation = list(copy.deepcopy(letter))
for i in indexesToChange:
mutation[i] = toggle(mutation[i])
return "".join(mutation)
def toggle(value):
''' value is a string value of '0' or '1'
returns the oposite value as a string '''
return str(int(not(int(value))))
def recoverLetter(HopfieldMatrix, corruptedletter, bipolarMode=False):
''' Get the hopfield corelation matrix and some corrupted letter
and returns the recovered letter'''
recovered = list(copy.deepcopy(corruptedletter))
allPositionsAgrees = False
while not allPositionsAgrees:
allPositionsAgrees = True
indexes = range(len(recovered))
random.shuffle(indexes)
for pos in indexes:
lastBit = recovered[pos]
recovered[pos] = '0' #so that position will not take effect
newValue = 0
for i in range(len(recovered)):
newValue += HopfieldMatrix[i][pos]*int(recovered[i])
if bipolarMode and 0==int(recovered[i]):
newValue -= HopfieldMatrix[i][pos]
if newValue >= 0:
recovered[pos] = '1'
if lastBit != recovered[pos]:
allPositionsAgrees = False
return "".join(recovered)
def mostFit(letters, letter):
featness = 0
let = list(letter)
retLetter = None
x = 0
y = 0
for row in range(len(letters)):
for l in range(len(letters[row])):
ll = list(letters[row][l])
lfeatness = 0
for i in range(len(ll)):
if ll[i] == let[i]:
lfeatness += 1
if abs(lfeatness) > featness:
featness = abs(lfeatness)
retLetter = copy.deepcopy(letters[row][l])
x = row
y = l
return retLetter,featness,x,y
def printLetter(letter, _2dim=True):
if not _2dim:
print letter
return
rowLen = int(math.sqrt(len(letter)))
for i in range(rowLen):
print letter[i*rowLen:(i+1)*rowLen]
def Test0():
letters = [['001010','111100', '010001', '011000', '101010']]
hopfieldMatrix = GenCorelationMatrix(letters)
print "matrix:"
for row in hopfieldMatrix:
print row
print "training: %s"%str(letters)
for i in range(2**6):
x = str(bin(i)[2:])
test = '0'*(6-len(x))+x
rec = recoverLetter(hopfieldMatrix, test)
print "%s --> %s "%(test, rec)
if __name__ == "__main__":
Test0()
test0() 的输出是:(左边的输入,右边的输出。
matrix:
[0, -1, 1, 5, 1, -1]
[-1, 0, -1, -1, -5, 1]
[1, -1, 0, 1, 1, -5]
[5, -1, 1, 0, 1, -1]
[1, -5, 1, 1, 0, -1]
[-1, 1, -5, -1, -1, 0]
training: [['001010', '111100', '010001', '011000', '101110']]
000000 --> 101110
000001 --> 010001
000010 --> 101110
000011 --> 101110
000100 --> 101110
000101 --> 101110
000110 --> 101110
000111 --> 101110
001000 --> 101110
001001 --> 101110
001010 --> 101110
001011 --> 101110
001100 --> 101110
001101 --> 101110
001110 --> 101110
001111 --> 101110
010000 --> 010001
010001 --> 010001
010010 --> 010001
010011 --> 010001
010100 --> 101110
010101 --> 101110
010110 --> 101110
010111 --> 010001
011000 --> 010001
011001 --> 010001
011010 --> 101110
011011 --> 101110
011100 --> 101110
011101 --> 101110
011110 --> 101110
011111 --> 101110
100000 --> 101110
100001 --> 010001
100010 --> 101110
100011 --> 101110
100100 --> 101110
100101 --> 101110
100110 --> 101110
100111 --> 101110
101000 --> 101110
101001 --> 101110
101010 --> 101110
101011 --> 101110
101100 --> 101110
101101 --> 101110
101110 --> 101110
101111 --> 101110
110000 --> 101110
110001 --> 101110
110010 --> 101110
110011 --> 101110
110100 --> 101110
110101 --> 101110
110110 --> 101110
110111 --> 101110
111000 --> 101110
111001 --> 101110
111010 --> 101110
111011 --> 101110
111100 --> 101110
111101 --> 101110
111110 --> 101110
111111 --> 101110