Hopfield - 不正确的识别

时间:2015-01-21 12:44:08

标签: python numpy machine-learning neural-network

我试图编码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")

随意复制,并制定判决......

0 个答案:

没有答案