Я использую библиотеку FANN для построения нейронных сетей для решения проблемы регрессии. Дело в том, что после того, как сети обучены на соответствующем обучающем наборе (который, кажется, работает достаточно хорошо), каждый отдельный тест выдает точно такой же результат. Другими словами, учитывая любое состояние моих 16 прогнозирующих переменных, мой прогнозируемый результат, согласно ANN, одинаков.
Я полагаю, что сеть правильно вычисляет первую строку вычисления, а затем всегда выводит этот результат на другие вычисления, независимо от того, что я им передаю (как это, похоже, очень хорошо работает в первом примере обучения, давая точный прогноз ).
Например, мои первые переменные примера обучения:
1 1 13.5 13.5 13.5 14.5 14.4 14.3 14.3 14.2 14.5 13 11.7 12.2 12.2 11.3
Мой целевой вывод — 14,5, и в каждом тесте сеть выводит что-то между 14,69 и 14,7 (из-за небольшого времени вычислений и поскольку я только играю с пакетом, я тренирую его каждый раз, когда запускаю код).
Таким образом, этот вывод кажется вполне законным с этим набором данных.
Дело в том, что когда я пытаюсь запустить его на нескольких других входах, я всегда получаю один и тот же 14.69 / 14.7 (идентичный вывод даже для самой маленькой цифры).
Поскольку сеть, кажется, правильно обрабатывает обучающий пример, изучает отношения и правильно вычисляет на ОДНОМ новом тестовом примере, я склонен полагать, что вся обучающая часть верна. Поскольку нет причин, по которым сеть всегда будет выводить одно и то же значение, я предполагаю, что мой способ тестирования не верен.
Мой вопрос: каков точный синтаксис для тестирования нейронной сети FANN на новом наборе данных? и как мне распечатать / сохранить соответствующие выходные данные?
Вот текущее состояние моего кода:
fann_type *calc_out;
fann_type input[16];
for (int i = 0; i < 20; i++)
{
if (!rowHasNA(timeSerie, i))
{
cout << "Input : ";
for (int j = 1; j < 17; j++)
{
input[j - 1] = timeSerie(i, j);
cout << input[j - 1] << " ";
}
cout << endl;
calc_out = fann_run(ann, input);
cout << "Input " << i << " gives : " << calc_out[0] << endl;
}
}
Куда:
rowHasNA
это пользовательская функция, которую я использовал, чтобы определить, есть ли в моем примере хотя бы один NAann
это fann*
который уже был обученtimeSerie
это matrix<double>
где каждая строка является тестовым примеромЯ все еще немного озадачен тем, как работает пакет FANN, поскольку я не нашел действительно четкой документации о том, как обучать сети и тестировать их. Я изо всех сил пытаюсь понять, как fann_type
работает.
Заранее спасибо.
Для предъявления по месту требования.
Код, который написан выше, является правильным: в случае, когда сеть была должным образом обучена, ей удается вывести разные значения для разных входов.
Основная проблема заключалась в обучении сети. Поскольку он дал мне правильный ответ (14,7, который был очень близок к ожидаемому 14,5), я предположил, что он был должным образом обучен. На самом деле, это не так, и это было своего рода «наилучшее среднее значение», соответствующее целям обучения. Поскольку мой тренировочный набор имеет очень небольшую дисперсию, всегда выводил одно и то же значение, независимо от того, какой ввод подается, давал приличную MSE (хотя, намного хуже, чем у меня в R и Octave, но так как я никогда не использовал FANN, я сделал не знаю чего ожидать).
Решение простое, и я должен был подумать об этом раньше: масштабирование функций.
Я предположил, что пакет сам по себе масштабируется, учитывая некоторую литературу, с которой я столкнулся в Интернете. При использовании самого базового кода для обучения сетей масштабирование функций не применяется к обучающим наборам.
Я рекомендую функцию масштабирования от 0 до 1 (х — мин / макс — мин).