我试图编码Hopfield模式识别网络,它可以识别二进制地图中的数字。问题是:在90%的结果中我得到相同的blob(甚至不是特定的模式,只是噪声)。 任何人都可以向我解释我做错了什么? 我有Hopfield网,有81个神经元和10个模式。培训方法:Hebbian。 我已经实现了自己的网络,但也发现了其他实现。
模式:
piec = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1,
1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1,
1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1]
siedem = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1,
-1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1,
-1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
szesc = [-1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1,
-1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1]
dziewiec = [-1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1,
-1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1,
-1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1]
zero = [-1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1,
-1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1,
-1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
jeden = [-1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1,
-1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1,
-1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, ]
trzy = [-1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1,
-1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1,
-1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, ]
dwa = [-1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1,
-1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1,
-1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1]
cztery = [-1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1,
1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1,
-1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
wzorce = list()
wzorce.append(zero)
wzorce.append(jeden)
wzorce.append(dwa)
wzorce.append(trzy)
wzorce.append(cztery)
wzorce.append(piec)
wzorce.append(szesc)
wzorce.append(siedem)
wzorce.append(dziewiec)
网络:
import numpy as np
class InvalidWeightsException(Exception):
pass
class InvalidNetworkInputException(Exception):
pass
class HopfieldNetwork(object):
def __init__(self, num_inputs):
self._num_inputs = num_inputs
self._weights = np.random.uniform(-1.0, 1.0, (num_inputs, num_inputs))
def set_weights(self, weights):
"""Update the weights array"""
if weights.shape != (self._num_inputs, self._num_inputs):
raise InvalidWeightsException()
self._weights = weights
def get_weights(self):
"""Return the weights array"""
return self._weights
def evaluate(self, input_pattern):
"""Calculate the output of the network using the input data"""
if input_pattern.shape != (self._num_inputs, ):
raise InvalidNetworkInputException()
sums = input_pattern.dot(self._weights)
s = np.zeros(self._num_inputs)
for i, value in enumerate(sums):
if value > 0:
s[i] = 1
else:
s[i] = -1
return s
def run(self, input_pattern, max_iterations=200):
"""Run the network using the input data until the output state doesn't change
or a maximum number of iteration has been reached."""
last_input_pattern = input_pattern
iteration_count = 0
while True:
result = self.evaluate(last_input_pattern)
iteration_count += 1
if np.array_equal(result, last_input_pattern) or iteration_count == max_iterations:
return result
else:
last_input_pattern = result
训练:
def hebbian_training(network, input_patterns):
"""Train a network using the Hebbian learning rule"""
n = len(input_patterns)
num_neurons = network.get_weights().shape[0]
weights = np.zeros((num_neurons, num_neurons))
for i in range(num_neurons):
for j in range(num_neurons):
if i == j:
continue
for m in range(n):
weights[i, j] += input_patterns[m][i] * input_patterns[m][j]
weights *= 1/float(n)
network.set_weights(weights)
和“主要”:
import random
def mutate_wzorzec(wzorzec, mutacje=0):
for _ in range(mutacje):
do_mutacji = random.randint(0, len(wzorzec))
wzorzec[do_mutacji] *= -1
return wzorzec
import wzorce81 as wzr
input_patterns = np.array([np.array(x) for x in wzr.wzorce])
network = HopfieldNetwork(81)
hebbian_training(network, input_patterns)
mutacje=[]
for wzor in input_patterns:
mutacje.append(mutate_wzorzec(wzor))
shape1=9
shape2=9
for i, mutacja in enumerate(mutacje):
wynik = network.run(np.array(mutacja))
mutacja.shape=(shape1,shape2)
wynik.shape=(shape1,shape2)
plt.subplot(5, 4, 2*i+1)
plt.imshow(mutacja, interpolation="nearest")
plt.subplot(5, 4, 2*i+2)
plt.imshow(wynik, interpolation="nearest")
随意复制,并制定判决......