神经网络精度稳定

时间:2018-12-02 15:25:44

标签: c++ machine-learning neural-network backpropagation

我正在建立一个用于识别字母的神经网络。目前,在训练期间,该网络似乎稳定在12%左右的稳定水平。作为输入,网络拍摄10x10图像(格式为100x1列向量),并输出26x1列向量,其中每个元素对应一个不同的字母。现在,我没有一个很好的数据集(只有50个样本),但是我对其进行了数百次迭代,并且每次迭代的准确性并没有真正超过6/50的正确率。我认为正确的标识是与正确字母相对应的元素,该正确字母是向量中的最大数字。我希望在继续和扩展数据集之前能获得不错的准确性。

ML::Matrix ML::NeuralNetwork::calculate(const Matrix & input)
{
    //all inputs and layers are column vectors
    //weights and biases are std::vector of ML::Matrix
    Matrix resultant = input;
    results.add(resultant); //circular linked list to store the intermediate results
    for (int i = 0; i < weights.size(); ++i) {
        resultant = (weights[i] * resultant) + biases[i];
        resultant.function(sigmoid); //apply sigmoid to every element in the matrix
        results.add(resultant);
    }
    return resultant;
}

void ML::NeuralNetwork::learn(const Matrix & calc, const Matrix & real)
{
    //backpropagation
    ML::Matrix cost = 2 * (calc - real); //derivative of cost function: (calc - real)^2
    for (int i = weights.size() - 1; i >= 0; --i) {
        ML::Matrix dCdB = cost.hadamardProduct(ML::sigDerivative(weights[i] * results[i] + biases[i]));
        ML::Matrix dCdW = dCdB * results[i].transpose();
        cost = weights[i].transpose() * dCdB;
        weights[i] -= learningRate * dCdW;
        biases[i] -= learningRate * dCdB;
    }

}
ML::Matrix ML::Matrix::operator*(const Matrix & other) const throw(ML::MathUndefinedException)
{
    //naive matrix-multiplication and matrix-vector product
    if (columns != other.rows) throw MathUndefinedException();
    Matrix output(rows, other.columns);
    if (other.columns == 1) {
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < columns; ++j)
                output.set(i, output.get(i) + get(i, j) * other.get(j));
        }
    }
    else {
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < columns; ++j) {
                for (int k = 0; k < other.rows; ++k) {
                    output.set(i, j, output.get(i, j) + get(i, k) * other.get(k, j));
                }
            }
        }
    }
    return output;
}

通过简单的示例,我的网络可以更好地工作。在具有3个输入和1个输出的测试中,它稳定在大约70%的水平,而在另一个只有1个输入和1个输出的测试中,它将获得大约99%的精度,因此我不确定代码是否有问题。虽然代码针对n个任意大小的层进行了抽象,但我一直在测试大约1-2个隐藏层(总共3-4个层)。我测试了各种培训率,甚至非恒定和差异的培训率。我已经单独测试了每个单独的矩阵操作函数(hadamardProduct,转置,矩阵加法等),所以我几乎可以确定问题不在其中一个函数中(因此,除了矩阵乘法)

所有帮助将不胜感激

0 个答案:

没有答案