Я пытаюсь обучить нейронную сеть, используя алгоритм обратного распространения. в OpenCV 2.3.
Однако это не предсказывает правильно …. даже на тренировочном наборе данных. Может кто-нибудь помочь мне найти, что здесь не так?
training_feature_matrix — Nx69 матрица значений с плавающей запятой
training_age_matrix — Nx4 матрица значений с плавающей точкой
test_feature_matrix — Mx69 матрица значений с плавающей точкой
test_age_matrix — Mx4 матрица значений с плавающей точкой
матрицы признаков (упомянутые выше) имеют вид: [0,123435, 0,4542665, 0,587545, … 68-таких значений + последнее значение ‘1,0 или 2,0’ в зависимости от его мужского / женского пола)
матрицы возраста (упомянутые выше) имеют вид: [1, 0, 0, 0; 1, 0, 0, 0; 0, 1, 0, 0; …] здесь 1 показывает класс возраста (ребенок, ребенок, взрослый, старый), которому принадлежит соответствующий ряд матрицы признаков.
вот код: я вызываю функцию ‘mlp’, используя вышеприведенные матрицы в качестве параметров)
cv::Mat mlp(cv::Mat& training_feature_matrix, cv::Mat& training_age_matrix, cv::Mat& test_feature_matrix, cv::Mat& test_age_matrix)
{
cv::Mat layers = cv::Mat(3, 1, CV_32SC1);
layers.row(0) = cv::Scalar(69);
layers.row(1) = cv::Scalar(36);
layers.row(2) = cv::Scalar(4); // cout<<layers<<"\n";
CvANN_MLP ann;
CvANN_MLP_TrainParams params;
CvTermCriteria criteria;
criteria.max_iter = 10000;
criteria.epsilon = 0.001;
criteria.type = CV_TERMCRIT_ITER + CV_TERMCRIT_EPS;
params.train_method = CvANN_MLP_TrainParams::BACKPROP;
params.bp_dw_scale = 0.1;
params.bp_moment_scale = 0.1;
params.term_crit = criteria;
ann.create(layers, CvANN_MLP::SIGMOID_SYM);
ann.train(training_feature_matrix, training_age_matrix, cv::Mat(), cv::Mat(), params);
cv::Mat predicted(test_age_matrix.rows, 4, CV_32SC1);
for(int i = 0; i < test_feature_matrix.rows; i++)
{
cv::Mat response(1, 4, CV_32F);
cv::Mat sample = test_feature_matrix.row(i);
ann.predict(sample, response);
for (int g = 0; g < 4; g++)
{
predicted.at<int>(i,g) = response.at<float>(0,g);
}
}
cout << "\n";
cout << ann.get_weights(0) << "\n";
cout << ann.get_layer_sizes() << "\n";
cout << ann.get_layer_count() << "\n\n";
return predicted;
}
РЕДАКТИРОВАТЬ Кроме того, ann.get_weights (0) & ann.get_layer_sizes () возвращают значения мусора, но ann.get_layer_count () возвращает правильное значение 3.
Спасибо 🙂
Прошло много времени с тех пор, как этот вопрос задан, но я поделюсь ответом. У меня была похожая проблема с выходными значениями сигмоида. Это решено сейчас. Вы можете проверить мою проблему здесь:
Сигмоидальный выход OpenCV Neural Network
Чтобы подвести итог ошибки, это происходит из-за параметры по умолчанию для функции создания mlp. Используйте как это: ann.create (слои, CvANN_MLP :: SIGMOID_SYM, 1, 1).
Обратное распространение не всегда сходится. Вполне возможно, взорвать и производить глупости. Это вероятно, если значения epsilon или momentum_scale слишком велики. Ваш импульс выглядит как верхний предел того, что может сработать, и я постараюсь уменьшить его.