如何使用hopfield网络来学习更多模式?

时间:2013-10-08 20:47:33

标签: c# artificial-intelligence neural-network

神经元数量与Hopfield网络识别模式的能力之间是否有任何关系?

我用C#编写神经网络程序,用Hopfield网络识别模式。我的网络有64个神经元。当我为2种模式训练网络时,每件事都很好用,但是当我为更多模式训练网络时,Hopfield找不到答案!

所以,根据我的代码,我如何使用Hopfield网络来学习更多模式?

我应该对此代码进行更改吗?

我的train()功能:

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];
            }

还有Present()函数(此函数用于返回给定模式的答案):

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++];
        }

在下面的图像中,我训练了Hopfield的角色A和P,当输入模式像A或P时,网络以真实的方式识别它们 enter image description here enter image description here

然后我为角色C训练它: enter image description here

这是每件事都出错的地方!

现在,如果我输入类似C的模式,则会出现此问题: enter image description here

如果像A一样输入模式,看看会发生什么: enter image description here

如果训练更多模式,整个网格变黑!

1 个答案:

答案 0 :(得分: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网络herehere的虚假模式,稳定性和学习情况。