Нейронная сеть Точность плато

Я делаю нейронную сеть для идентификации букв. В настоящее время во время обучения сеть, похоже, выходит на плато с точностью около 12%. В качестве входных данных сеть берет изображение 10×10 (отформатированное как вектор столбцов 100×1) и выводит вектор столбцов 26×1, где каждому элементу соответствует отдельная буква. Сейчас у меня нет большого набора данных (всего 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

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector