神经网络无法学习。卡在50%

时间:2018-10-21 21:16:58

标签: c++ neural-network

我是NN的初学者。我正在尝试为XOR函数创建一个NN,但它不是在学习,它停留在50% 谁能给我一些建议?谢谢。 这是代码:

/// Matrix.cpp

#include "pch.h"
#include "Matrix.h"
....
 Matrix Matrix::sigmoidDerivate(const Matrix &m) {
    assert(m.rows >= 1 && m.cols >= 1);

    Matrix tmp(m.rows, m.cols);
    for (ushort i = 0; i < tmp.rows; i++) {
        for (ushort j = 0; j < tmp.cols; j++) {
            tmp.mat[i][j] = m.mat[i][j]*(1-m.mat[i][j]);
        }
    }
    return tmp;
}

Matrix Matrix::sigmoid(const Matrix &m) {
    assert(m.rows >= 1 && m.cols >= 1);

    Matrix tmp(m.rows, m.cols);
    for (ushort i = 0; i < tmp.rows; i++) {
        for (ushort j = 0; j < tmp.cols; j++) {
            tmp.mat[i][j]= 1 / (1 + exp(-m.mat[i][j]));
        }
    }
    return tmp;
}


Matrix Matrix::randomMatrix(ushort rows, ushort cols) {
    assert(rows>=1 && cols>=1);

    Matrix tmp(rows,cols);

    const int range_from = -3;
    const int range_to = 3;
    std::random_device                  rand_dev;
    std::mt19937                        generator(rand_dev());
    std::uniform_real_distribution<double>  distr(range_from, range_to);

    for (ushort i = 0; i < rows; i++) {
        for (ushort j = 0; j < cols; j++) {
            tmp.mat[i][j] = distr(generator);
        }
    }
    return tmp;
}

这是main():

vector<vector<double>> in = {
        {0,0},
        {1,0},
        {0,1},
        {1,1}
    };
    vector<double> out = { 0,1,1,0 };

    const ushort inputNeurons = 2;
    const ushort hiddenNeurons = 3;
    const ushort outputNeurons = 1;

    const double learningRate = 0.03;

    Matrix w_0_1 = Matrix::randomMatrix(inputNeurons, hiddenNeurons);
    Matrix w_1_2 = Matrix::randomMatrix(hiddenNeurons, outputNeurons);
    unsigned int epochs = 100000;

    for (int i = 0; i < epochs; i++) {
        for (int j = 0; j < in.size(); j++) {
            Matrix Layer_0 = Matrix::createRowMatrix(in[j]);
            Matrix desired_output = Matrix::createRowMatrix({ out[j] });

            Matrix Layer_1 = Matrix::sigmoid(Matrix::multiply(Layer_0, w_0_1));
            Matrix Layer_2 = Matrix::sigmoid(Matrix::multiply(Layer_1, w_1_2));


            Matrix error = Matrix::POW2(Matrix::substract(Layer_2, desired_output));

            //backprop
            Matrix Layer_2_delta = Matrix::elementWiseMultiply(
                Matrix::substract(Layer_2, desired_output),
                Matrix::sigmoidDerivate(Layer_2)
            );

            Matrix Layer_1_delta = Matrix::elementWiseMultiply(
                Matrix::multiply(Layer_2_delta, Matrix::transpose(w_1_2)),
                Matrix::sigmoidDerivate(Layer_1)
            );


            Matrix w_1_2_delta = Matrix::multiply(Matrix::transpose(Layer_1), Layer_2_delta);
            Matrix w_0_1_delta = Matrix::multiply(Matrix::transpose(Layer_0), Layer_1_delta);

            //updating weights
            w_0_1 = Matrix::multiply(w_0_1_delta, learningRate);
            w_1_2 = Matrix::multiply(w_1_2_delta, learningRate); 
}
}

NN体系结构为:2-> 3-> 1 在隐藏层中,如果数量较小(例如2-4),则输出为50%。对于隐藏层上的8个神经元,..输出变为大约49%。 请帮忙。

1 个答案:

答案 0 :(得分:0)

我对C ++不那么了解,所以我不确定。但在这一行:

 Matrix::substract(Layer_2, desired_output),

您正在执行的操作类似于从现有图层中减去所需的“良好”输出。我认为应该相反。所以你必须乘以-1

对我来说,它就像那样工作。如果您愿意,我可以将您的源代码发送给您。 (是Java)