反向传播不工作:神经网络Java

反向传播不工作:神经网络Java,java,matrix,neural-network,backpropagation,sigmoid,Java,Matrix,Neural Network,Backpropagation,Sigmoid,根据这个python示例,我创建了一个具有3层的简单神经网络:(PS:您必须向下滚动,直到到达第2部分) 这是我的Java代码实现: private void trainNet() { // INPUT is a 4*3 matrix // SYNAPSES is a 3*4 matrix // SYNAPSES2 is a 4*1 matrix // 4*3 matrix DOT 3*4 matrix => 4*4 matrix: unrefined te

根据这个python示例,我创建了一个具有3层的简单神经网络:(PS:您必须向下滚动,直到到达第2部分)

这是我的Java代码实现:

private void trainNet()
{
    // INPUT is a 4*3 matrix
    // SYNAPSES is a 3*4 matrix
    // SYNAPSES2 is a 4*1 matrix
    // 4*3 matrix DOT 3*4 matrix => 4*4 matrix: unrefined test results
    double[][] layer1 = sigmoid(dot(inputs, synapses), false);

    // 4*4 matrix DOT 4*1 matrix => 4*1 matrix: 4 final test results
    double[][] layer2 = sigmoid(dot(layer1, synapses2), false);

    // 4*1 matrix - 4*1 matrix => 4*1 matrix: error of 4 test results
    double[][] layer2Error = subtract(outputs, layer2);

    // 4*1 matrix DOT 4*1 matrix => 4*1 matrix: percentage of change of 4 test results
    double[][] layer2Delta = dot(layer2Error, sigmoid(layer2, true));

    // 4*1 matrix DOT 3*1 matrix => 4*1 matrix
    double[][] layer1Error = dot(layer2Delta, synapses2);

    // 4*1 matrix DOT 4*4 matrix => 4*4 matrix: percentage of change of 4 test results
    double[][] layer1Delta = dot(layer1Error, sigmoid(layer1, true));

    double[][] transposedInputs = transpose(inputs);
    double[][] transposedLayer1 = transpose(layer1);

    //  4*4 matrix DOT 4*1 matrix => 4*1 matrix: the updated weights
    // Update the weights
    synapses2 = sum(synapses2, dot(transposedLayer1, layer2Delta));

    // 3*4 matrix DOT 4*4 matrix => 3*4 matrix: the updated weights
    // Update the weights
    synapses = sum(synapses, dot(transposedInputs, layer1Delta));

    // Test each value of two 4*1 matrices with each other
    testValue(layer2, outputs);
}
我自己创建的点、和、减和转置函数,我非常确信它们能完美地完成它们的工作

第一批输入给了我大约0.4的误差,这是可以的,因为权重是随机值。第二次运行时,误差幅度较小,但仅为非常小的数值(0.001)

经过500000批(总共2000000次测试)后,网络仍然没有给出任何正确的值!所以我试着使用更多的批次。使用1000000个批次(总共4000000个测试),网络生成了高达16900个正确结果

谁能告诉我发生了什么事

这些是使用的重量:

第一层:

  • 2.038829298171684 2.816232761170282 1.6740269469812146 1.63442276238497
  • 1.5890997594993828 1.7909325329112222 2.101840236824494 1.063579126586681
  • 3.7612384070713113.757148454039234 3.7557450538398176 3.6715972104291605
第二层:

  • -0.019603811941904248
  • 218.382533232553
  • 53.70133275445734
  • -272.83589796861514

    编辑: 感谢lsnare指点我使用图书馆会更容易

以下是使用math.nist.gov/javanumerics库的工作代码:

private void trainNet()
{
    // INPUT is a 4*3 matrix
    // SYNAPSES is a 3*4 matrix
    // SYNAPSES2 is a 4*1 matrix
    // 4*3 matrix DOT 3*4 matrix => 4*4 matrix: unrefined test results
    Matrix hiddenLayer = sigmoid(inputs.times(synapses), false);

    // 4*4 matrix DOT 4*1 matrix => 4*1 matrix: 4 final test results
    Matrix outputLayer = sigmoid(hiddenLayer.times(synapses2), false);

    // 4*1 matrix - 4*1 matrix => 4*1 matrix: error of 4 test results
    Matrix outputLayerError = outputs.minus(outputLayer);

    // 4*1 matrix DOT 4*1 matrix => 4*1 matrix: percentage of change of 4 test results
    Matrix outputLayerDelta = outputLayerError.arrayTimes(sigmoid(outputLayer, true));

    // 4*1 matrix DOT 1*4 matrix => 4*4 matrix
    Matrix hiddenLayerError = outputLayerDelta.times(synapses2.transpose());

    // 4*4 matrix DOT 4*4 matrix => 4*4 matrix: percentage of change of 4 test results
    Matrix hiddenLayerDelta = hiddenLayerError.arrayTimes(sigmoid(hiddenLayer, true));

    //  4*4 matrix DOT 4*1 matrix => 4*1 matrix: the updated weights
    // Update the weights
    synapses2 = synapses2.plus(hiddenLayer.transpose().times(outputLayerDelta));

    // 3*4 matrix DOT 4*4 matrix => 3*4 matrix: the updated weights
    // Update the weights
    synapses = synapses.plus(inputs.transpose().times(hiddenLayerDelta));

    // Test each value of two 4*1 matrices with each other
    testValue(outputLayer.getArrayCopy(), outputs.getArrayCopy());
}

通常,在编写涉及高级数学或数值计算(如线性代数)的代码时,最好使用该领域专家编写的现有库,而不是编写自己的函数。标准库将产生更准确的结果,并且更有可能更高效。例如,在您引用的博客中,作者使用numpy库计算点积和矩阵的转置。对于Java,您可以使用NIST开发的Java矩阵包(JAMA):
例如,要转换矩阵,请执行以下操作:

double[4][3] in = {{0,0,1},{0,1,1},{1,0,1},{1,1,1}};
Matrix input = new Matrix(in);
input = input.transpose();

我不确定这是否能完全解决您的问题,但希望这能帮助您在将来节省编写额外代码的时间。

您能否添加点、和、减、转置和sigmoid函数以澄清问题?非常感谢您向我指出这一点!问题是我的方法有效,但它们没有足够的错误检查,因此mn矩阵可以乘以pq矩阵(p≠ n) .很乐意帮忙!我自己在尝试实现矩阵运算时也遇到过类似的问题:)