java - XOR神经网络(FF)收敛到0.5

标签 java neural-network xor

我创建了一个程序,可以创建任意大小/长度的灵活神经网络,但是我正在使用XOR设置的简单结构(前馈,Sigmoid激活,反向传播,无批处理)对其进行测试。

编辑:以下是我没有提供足够信息的原始问题的全新方法

编辑2:我开始在-2.5到2.5之间权重,并修复了我的代码中忘记了一些负面因素的问题。现在,对于所有情况,收敛为0,或者对于所有情况,收敛为1,而不是0.5

一切都按照我认为的方式工作,但是它趋向于0.5,而不是在0和1的输出之间振荡。我已经完全通过并手工计算了整个前馈/计算增量误差/后向支撑的设置./等,它与我从程序中得到的匹配。我还尝试过通过更改学习率/动量来优化它,以及增加网络的复杂性(更多神经元/层)。

因此,我假设我的方程式之一是错误的,或者在我的神经网络中我还有其他误解。以下是我对每个步骤都遵循的方程式的逻辑:

我有一个带有两个输入和一个偏置的输入层,一个带有2个神经元和一个偏置的隐藏层,以及带有1个神经元的输出。


取两个输入神经元和偏向神经元各自的输入,然后将它们乘以它们各自的权重,然后将它们加在一起作为隐藏层中两个神经元中每个神经元的输入。
取得每个隐藏神经元的输入,使其通过Sigmoid激活函数(参考文献1),并将其用作神经元的输出。
取隐藏层中每个神经元的输出(偏差为1),将它们乘以各自的权重,然后将这些值添加到输出神经元的输入中。
通过Sigmoid激活函数传递输出神经元的输入,并将其用作整个网络的输出。
计算输出神经元的Delta误差(参考2)
计算2个隐藏神经元各自的Delta误差(参考3)
计算每个权重的梯度(参考4)(从头开始并向后计算)
计算每个重量的增量重量(参考5),并将其添加到其值中。
通过更改输入和预期输出重新开始过程(参考文献6)


以下是对方程式/过程的引用的详细信息(这可能是我的问题所在!):


x是神经元的输入:(1/(1 + Math.pow(Math.E, (-1 * x))))
-1*(actualOutput - expectedOutput)*(Sigmoid(x) * (1 - Sigmoid(x))//Same sigmoid used in reference 1
SigmoidDerivative(Neuron.input)*(The sum of(Neuron.Weights * the deltaError of the neuron they connect to))
ParentNeuron.output * NeuronItConnectsTo.deltaError
learningRate*(weight.gradient) + momentum*(Previous Delta Weight)
我有一个arrayList,其中的值依次为0,1,1,0。它采用第一对(0,1),然后期望为1。对于第二次,它使用第二对(1,1)并期望0。它只是不断迭代每个新集合的列表。也许以这种系统的方式训练它会导致问题?


就像我之前说过的那样,他们之所以认为我不认为这是代码问题,是因为它与我用纸和铅笔计算出的结果完全匹配(如果出现编码错误,则不会发生)。

另外,当我第一次初始化权重时,会给它们一个介于0和1之间的随机double值。本文建议这样做可能会导致问题:Neural Network with backpropogation not converging
可以吗?我使用了n ^(-1/2)规则,但是并没有解决它。

如果我可以更具体,或者您想要其他代码,请告诉我,谢谢!

最佳答案

这是错的

SigmoidDerivative(Neuron.input)*(((Neuron.Weights *它们连接的神经元的deltaError的总和))
首先是乙状结肠激活(g)
第二个是乙状结肠激活的导数

private double g(double z) {
    return 1 / (1 + Math.pow(2.71828, -z));
}

private double gD(double gZ) {
    return gZ * (1 - gZ);
}


不相关的注释:您使用的(-1 * x)表示法确实很奇怪,只需使用-x

从如何表达ANN步骤的角度看,您的实现似乎很差。尝试着重于实现Forward / BackPropogation,然后实现UpdateWeights方法。
创建一个矩阵类

这是我的Java实现,非常简单,有些粗糙。我使用Matrix类使其背后的数学代码看起来非常简单。

如果您可以用C ++编写代码,则可以使运算符重载,这将使更容易编写可理解的代码。

https://github.com/josephjaspers/ArtificalNetwork/blob/master/src/artificalnetwork/ArtificalNetwork.java



这是算法(C ++)

所有这些代码都可以在我的github上找到(神经网络既简单又功能齐全)
每层都包含偏置节点,这就是为什么存在偏移的原因

void NeuralNet::forwardPropagation(std::vector<double> data) {
    setBiasPropogation(); //sets all the bias nodes activation to 1
    a(0).set(1, Matrix(data)); //1 to offset for bias unit (A = X)

    for (int i = 1; i < layers; ++i) {
        //  (set(1 -- offsets the bias unit

        z(i).set(1, w(i - 1) * a(i - 1)); 
        a(i) = g(z(i)); // g(z ) if the sigmoid function
    }
}
void NeuralNet::setBiasPropogation() {
    for (int i = 0; i < activation.size(); ++i) {
        a(i).set(0, 0, 1);
    }
}


outLayer D = A-Y(y是输出数据)
hiddenLayers d ^ l =(w ^ l(T)* d ^ l + 1)*:gD(a ^ l)

d =导数向量

W =权重矩阵(长度=连接,宽度=特征)

a =激活矩阵

gD =导数函数

^ l =不具备权力(这仅表示在l层)


=点积


*:=相乘(将每个元素“直通”相乘)

cpy(n)返回偏移n的矩阵副本(忽略n行)

void NeuralNet::backwardPropagation(std::vector<double> output) {
    d(layers - 1) = a(layers - 1) - Matrix(output);
    for (int i = layers - 2; i > -1; --i) {
    d(i) = (w(i).T() * d(i + 1).cpy(1)).x(gD(a(i))); 
    }       
}


解释这些代码可能会使图像混乱,因此我发送此链接(我认为是很好的来源),其中还包含对BackPropagation的解释,可能比我自己的解释更好。
http://galaxy.agh.edu.pl/~vlsi/AI/backp_t_en/backprop.html

void NeuralNet::updateWeights() {
    // the operator () (int l, int w) returns a double reference at that position in the matrix
    // thet operator [] (int n) returns the nth double (reference) in the matrix (useful for vectors) 
    for (int l = 0; l < layers - 1; ++l) {
        for (int i = 1; i < d(l + 1).length(); ++i) {
            for (int j = 0; j < a(l).length(); ++j) {
                w(l)(i - 1, j) -= (d(l + 1)[i] * a(l)[j]) * learningRate + m(l)(i - 1, j);
                m(l)(i - 1, j) = (d(l + 1)[i] * a(l)[j]) * learningRate * momentumRate;
            }
        }
    }
}

关于java - XOR神经网络(FF)收敛到0.5,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39523744/

相关文章:

java - 为什么 start() 在我的 Thread 扩展中不起作用

java - JSP 的分页问题

machine-learning - 神经网络,最小神经元数量

python - 训练批处理 : which Tensorflow method is the right one?

python - 并非所有参数在字符串格式化 python 期间都会转换

java - 如何将 "angle-jump"从0补偿到360,反之亦然?

java - Maven:从阴影插件中排除依赖

python - 我们应该如何使用 pad_sequences 在 keras 中填充文本序列?

c++ - 我们能否使用位操作来确定 0 在数组中是否出现奇数次

algorithm - 三胞胎的数量