简体   繁体   English

XOR 神经网络误差不断收敛到 0.5

[英]XOR neural network error keeps converging to 0.5

I just started attempting to make my own neural network in c# by copying a simple one I found written in python and the output always ends at 0.5.我刚开始尝试在 c# 中创建自己的神经网络,方法是复制一个我发现的用 python 编写的简单神经网络,而 output 总是以 0.5 结束。 I looked at all other questions posted about this same problem on Google and none of the solutions were applicable.我查看了在 Google 上发布的关于同一问题的所有其他问题,但没有一个解决方案适用。 I have no idea why this is happening.我不知道为什么会这样。 Here's what my code looks like right now:这是我的代码现在的样子:

public class NeuralNetwork
        {
            private double[,] w;

            public NeuralNetwork()
            {
                w = random(2, 1);
            }

            public double[,] getWeights()
            {
                return w;
            }

            public void train(double[,] x, double[,] y, int iterations)
            {
                for (int i = 0; i < iterations; i++)
                {
                    double[,] output = think(x);
                    double[,] error = Mat.subtract(Mat.transpose(y), output);
                    double[,] adjust = dot(Mat.transpose(x), Mat.multiply(error, doSigDeriv(output)));

                    w = Mat.add(w, adjust);
                }
            }

            public double[,] think(double[,] inputs)
            {
                return doSig(dot(inputs, w));
            }

            private double[,] dot(double[,] a, double[,] b)
            {
                double[,] dot = new double[a.GetLength(0), b.GetLength(1)];

                for (int i = 0; i < a.GetLength(0); i++)
                {
                    for (int j = 0; j < b.GetLength(1); j++)
                    {
                        for (int k = 0; k < b.GetLength(0); k++)
                            dot[i, j] += a[i, k] * b[k, j];
                    }
                }
                return dot;
            }

            private double[,] random(int w, int h)
            {
                double[,] a = new double[w, h];
                for (int i = 0; i < w; i++)
                {
                    for (int j = 0; j < h; j++)
                    {
                        a[i, j] = 2 * (double)rand.NextDouble() - 1;
                    }
                }
                return a;
            }

            private double[,] doSig(double[,] a)
            {
                double[,] b = new double[a.GetLength(0), a.GetLength(1)];
                for (int i = 0; i < a.GetLength(0); i++)
                {
                    for (int j = 0; j < a.GetLength(1); j++)
                    {
                        b[i, j] = sig(a[i, j]);
                    }
                }
                return b;
            }

            private double[,] doSigDeriv(double[,] a)
            {
                double[,] b = new double[a.GetLength(0), a.GetLength(1)];
                for (int i = 0; i < a.GetLength(0); i++)
                {
                    for (int j = 0; j < a.GetLength(1); j++)
                    {
                        b[i, j] = a[i, j] * (1 - a[i, j]);
                    }
                }
                return b;
                //return Mat.multiply(a, Mat.subtract(one(a), a));
            }

            private double sig(double x)
            {
               return 1 / (double)(1 + Math.Exp(-x));
            }
        }

x is the array I used for inputs and y for outputs, and Mat is just a class I made to handle the matrix operations. x 是我用于输入的数组,y 用于输出,Mat 只是我用来处理矩阵运算的 class。 When I tested it, I changed the iterations to 10000 and 50000 and got the same result.当我测试它时,我将迭代次数更改为 10000 和 50000 并得到相同的结果。 Any insight is greatly appreciated, thanks.非常感谢任何见解,谢谢。

EDIT: I just realized that when it's supposed to be 0, it's -0.5 and 1 is 0.5.编辑:我刚刚意识到,当它应该是 0 时,它是 -0.5 而 1 是 0.5。

Of course the comment of user219279 is correct: NN better run in GPU/Tensor nowadays, which is much faster when you are going to scale up your network.当然,user219279 的评论是正确的:NN 现在更好地在 GPU/Tensor 中运行,当您要扩展网络时这要快得多。 For XOR back propagation and study however, you won't need performance.但是,对于 XOR 反向传播和研究,您不需要性能。

An output value of 0.5 is very common and called "local minimum". output 值为 0.5 非常常见,称为“局部最小值”。 It happens when your network training cannot converge, for some reason.当您的网络训练由于某种原因无法收敛时,就会发生这种情况。 Weights reach giant +/- values instead of a balance with small values and 0/1 outputs.权重达到巨大的 +/- 值,而不是具有小值和 0/1 输出的平衡。

The error I see above: there are not enough weights.我在上面看到的错误:没有足够的权重。 You allocate your weights as a 2x1 array, connecting input output.您将权重分配为 2x1 数组,连接输入 output。 You can't train a XOR outcome net with only 2 weights.你不能训练一个只有 2 个权重的 XOR 结果网络。 You need at least 5 weights.您至少需要 5 个砝码。 See for more info on a suitable XOR architecture http://mnemstudio.org/neural-networks-multilayer-perceptrons.htm有关合适的 XOR 架构的更多信息,请参阅http://mnemstudio.org/neural-networks-multilayer-perceptrons.htm

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM