Точность нейронной сети - PullRequest
0 голосов
/ 02 декабря 2018

Я делаю нейронную сеть для идентификации букв.В настоящее время во время обучения сеть, похоже, выходит на плато с точностью около 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, транспонирование, добавление матрицы и т. Д.), Поэтому я почти уверен, что проблема не в одной из этих функций (поэтому я не показывал их код, за исключениемумножение матриц)

Буду признателен за любую помощь

...