0

Is there any relation between number of neurons and ability of Hopfield network to recognize patterns?

I write neural network program in C# to recognize patterns with Hopfield network. My network has 64 neurons. When I train network for 2 patterns, every things work nice and easy, but when I train network for more patterns, Hopfield can't find answer!

So, according to my code, how can I use Hopfield network to learn more patterns?

Should I make changes in this code?

There is my train() function:

public void Train(bool[,] pattern)
{
    //N is number of rows in our square matrix
    //Convert input pattern to bipolar
    int[,] PatternBipolar = new int[N, N];

    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            {
                if (pattern[i, j] == true)
                {
                    PatternBipolar[i, j] = 1;
                }
                else
                {
                    PatternBipolar[i, j] = -1;
                }
            }

    //convert to row matrix
    int count1 = 0;
    int[] RowMatrix = new int[(int)Math.Pow(N, 2)];
    for (int j = 0; j < N; j++)
        for (int i = 0; i < N; i++)
            {
                RowMatrix[count1] = PatternBipolar[i, j];
                count1++;
            }

    //convert to column matrix
    int count2 = 0;
    int[] ColMatrix = new int[(int)Math.Pow(N, 2)];
    for (int j = 0; j < N; j++)
        for (int i = 0; i < N; i++)
            {
                ColMatrix[count2] = PatternBipolar[i, j];
                count2++;
            }

    //multiplication
    int[,] MultipliedMatrix = new int[(int)Math.Pow(N, 2), (int)Math.Pow(N, 2)];
    for (int i = 0; i < (int)Math.Pow(N, 2); i++)
        for (int j = 0; j < (int)Math.Pow(N, 2); j++)
            {
                MultipliedMatrix[i, j] = ColMatrix[i] * RowMatrix[j];
            }

    //cells in the northwest diagonal get set to zero
    for (int i = 0; i < (int)Math.Pow(N, 2); i++)
        MultipliedMatrix[i, i] = 0;

    // WightMatrix + MultipliedMatrix

    for (int i = 0; i < (int)Math.Pow(N, 2); i++)
        for (int j = 0; j < (int)Math.Pow(N, 2); j++)
            {
                WeightMatrix[i, j] += MultipliedMatrix[i, j];
            }

And there is Present() function (this function is used to return answer for a given pattern):

public void Present(bool[,] Pattern)
{
    int[] output = new int[(int)(int)Math.Pow(N, 2)];

    for (int j = 0; j < N; j++)
        for (int i = 0; i < N; i++)
            {
                OutputShowMatrix[i, j] = 0;
            }

    //convert bool to binary
    int[] PatternBinary = new int[(int)Math.Pow(N, 2)];
    int count = 0;
    for (int j = 0; j < N; j++)
        for (int i = 0; i < N; i++)
            {
                if (Pattern[i, j] == true)
                {
                    PatternBinary[count] = 1;
                }
                else
                {
                    PatternBinary[count] = 0;
                }
                count++;
            }

    count = 0;
    int activation = 0;
    for (int j = 0; j < (int)Math.Pow(N, 2); j++)
    {
        for (int i = 0; i < (int)Math.Pow(N, 2); i++)
        {
            activation = activation + (PatternBinary[i] * WeightMatrix[i, j]);
        }

        if (activation > 0)
        {
            output[count] = 1;
        }
        else
        {
            output[count] = 0;
        }

        count++;
        activation = 0;
    }

    count = 0;
    for (int j = 0; j < N; j++)
        for (int i = 0; i < N; i++)
        {
            OutputShowMatrix[i, j] = output[count++];
        }

In below images I trained Hopfield for characters A and P and when input patterns are like A or P, network recognize them in true way enter image description here enter image description here

Then I train it for character C: enter image description here

This is where every things go wrong!

Now if I enter pattern like C, this issue happen: enter image description here

And if enter pattern like A, see what happen: enter image description here

And if train more patterns, whole of grid become black!

4

1 回答 1

1

我在您的代码中只发现了一个错误:您只执行了一次节点值计算迭代,而没有验证值是否已经收敛。我已经像这样修复了这个方法:

public bool[,] Present(bool[,] pattern)
{
    bool[,] result = new bool[N, N];
    int[] activation = new int[N * N];

    int count = 0;
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
        {
            activation[count++] = pattern[i, j] ? 1 : 0;
        }

    bool convergence = false;
    while (!convergence)
    {
        convergence = true;
        var previousActivation = (int[])activation.Clone();
        for (int i = 0; i < N * N; i++)
        {
            activation[i] = 0;
            for (int j = 0; j < N * N; j++)
            {
                activation[i] += (previousActivation[j] * WeightMatrix[i, j]);
            }

            activation[i] = activation[i] > 0 ? 1 : 0;

            if (activation[i] != previousActivation[i])
            {
                convergence = false;
            }
        }
    }

    count = 0;
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
        {
            result[i, j] = activation[count++] == 1;
        }

    return result;
}

这略微改善了结果,但可能还应该改进以异步计算值以避免循环。

不幸的是,这仍然会引入您所描述的行为。这是由称为虚假模式的现象造成的。为了让网络学习不止一种模式,请考虑使用 Hebb 规则对其进行训练。您可以在此处此处阅读有关 Hopfield 网络的虚假模式、稳定性和学习的信息。

于 2013-10-13T00:09:57.233 回答