这个问题比代码更具概念性,因此用JS编写的这个问题应该无关紧要 .

所以我正在尝试创建一个神经网络,我正在通过尝试训练它来做一个简单的任务来测试它 - 一个OR门(或者,实际上,只是任何逻辑门) . 为了简单起见,我没有使用任何批次使用Gradient Descent(批处理对于此任务来说似乎是不必要的,而且我所拥有的代码越少,调试就越容易) .

但是,经过多次迭代后,输出总是收敛到输出的平均值 . 例如,给定此训练集:

[0,0] = 0
[0,1] = 1
[1,0] = 1
[1,1] = 0

无论输入如何,输出总是收敛于0.5左右 . 如果训练集是:

[0,0] = 0,
[0,1] = 1,
[1,0] = 1,
[1,1] = 1

输出总是收敛到0.75左右 - 所有训练输出的平均值 . 对于所有输出组合,这似乎都是正确的 .

似乎这种情况正在发生,因为无论何时给出输出为0的东西,它都会改变权重以接近它,并且每当给出输出为1的东西时,它会改变权重以接近它,这意味着加班时间会在平均值附近收敛 .

这是反向传播代码(用Javascript编写):

this.backpropigate = function(data){
    //Sets the inputs
    for(var i = 0; i < this.layers[0].length; i ++){
        if(i < data[0].length){
            this.layers[0][i].output = data[0][i];
        }
        else{
            this.layers[0][i].output = 0;
        }
    }
    this.feedForward(); //Rerun through the NN with the new set outputs
    for(var i = this.layers.length-1; i >= 1; i --){
        for(var j = 0; j < this.layers[i].length; j ++){
            var ref = this.layers[i][j];
            //Calculate the gradients for each Neuron
            if(i == this.layers.length-1){ //Output layer neurons
                var error = ref.output - data[1][j]; //Error
                ref.gradient = error * ref.output * (1 - ref.output);
            }
            else{ //Hidden layer neurons
                var gradSum = 0; //Find sum from the next layer
                for(var m = 0; m < this.layers[i+1].length; m ++){
                    var ref2 = this.layers[i+1][m];
                    gradSum += (ref2.gradient * ref2.weights[j]);
                }
                ref.gradient = gradSum * ref.output * (1-ref.output);
            }
            //Update each of the weights based off of the gradient
            for(var m = 0; m < ref.weights.length; m ++){
                //Find the corresponding neuron in the previous layer
                var ref2 = this.layers[i-1][m];
                ref.weights[m] -= LEARNING_RATE*ref2.output*ref.gradient;
            }
        }
    }
    this.feedForward();
};

这里,NN处于这样的结构中,其中每个神经元是具有输入,权重和基于输入/权重计算的输出的对象,并且神经元存储在其中x维是层的2D 'layers'阵列中(所以,第一层是输入,第二层是隐藏等,而y维是该层内部的神经元对象的列表 . 输入的'data'以 [data,correct-output] 的形式给出,就像 [[0,1],[1]] 一样 .

我的LEARNING_RATE也是1,我的隐藏层有2个神经元 .

我觉得我的反向传播方法一定存在一些概念问题,因为我已经测试了我的代码的其他部分(比如feedForward部分),它运行正常 . 我尝试使用各种来源,虽然我主要依靠关于反向传播的维基百科文章以及它给我的方程式 .

.

.

我知道阅读我的代码可能会让人感到困惑,尽管我尽量让它变得简单易懂,但任何帮助都会非常感激 .