2016-04-26 10 views
0

Ich versuche Neuronales Netzwerk mit OpenCV ANN Library zu implementieren. Ich hatte eine funktionierende Lösung, aber nach dem Upgrade auf OpenCV 3.1 funktionierte es nicht mehr. Also habe ich einen vereinfachten Code zum Testen erstellt, aber das Problem bleibt bestehen. ANN wird erfolgreich trainiert, aber wenn ich versuche, eine Vorhersage mit einer Zeile von trainData aufzurufen, gibt es Mat of nan -Werte zurück. Der Code istOpenCV 3.1 ANN predict returns nan

cv::Ptr<cv::ml::ANN_MLP> nn = cv::ml::ANN_MLP::create(); 
nn->setActivationFunction(cv::ml::ANN_MLP::SIGMOID_SYM); 
nn->setTrainMethod(cv::ml::ANN_MLP::BACKPROP); 
nn->setBackpropMomentumScale(0.1); 
nn->setBackpropWeightScale(0.1); 
nn->setTermCriteria(cv::TermCriteria(cv::TermCriteria::MAX_ITER, (int)100000, 1e-6)); 

cv::Mat trainData(15, 4, CV_32FC1); 
trainData.at<float>(0, 0) = 5.5f; trainData.at<float>(0, 1) = 3.5f; trainData.at<float>(0, 2) = 1.3f; trainData.at<float>(0, 3) = 0.2f; 
trainData.at<float>(1, 0) = 6.5f; trainData.at<float>(1, 1) = 2.8f; trainData.at<float>(1, 2) = 4.5999999f; trainData.at<float>(1, 3) = 1.5f; 
trainData.at<float>(2, 0) = 6.3000002f; trainData.at<float>(2, 1) = 2.3f; trainData.at<float>(2, 2) = 4.4000001f; trainData.at<float>(2, 3) = 1.3f; 
trainData.at<float>(3, 0) = 6.0f; trainData.at<float>(3, 1) = 2.2f; trainData.at<float>(3, 2) = 4.0f; trainData.at<float>(3, 3) = 1.0f; 
trainData.at<float>(4, 0) = 4.5999999f; trainData.at<float>(4, 1) = 3.0999999f; trainData.at<float>(4, 2) = 1.5f; trainData.at<float>(4, 3) = 0.2f; 
trainData.at<float>(5, 0) = 5.0f; trainData.at<float>(5, 1) = 3.2f; trainData.at<float>(5, 2) = 1.2f; trainData.at<float>(5, 3) = 0.2f; 
trainData.at<float>(6, 0) = 7.4000001f; trainData.at<float>(6, 1) = 2.8f; trainData.at<float>(6, 2) = 6.0999999f; trainData.at<float>(6, 3) = 1.9f; 
trainData.at<float>(7, 0) = 6.0f; trainData.at<float>(7, 1) = 2.9000001f; trainData.at<float>(7, 2) = 4.5f; trainData.at<float>(7, 3) = 1.5f; 
trainData.at<float>(8, 0) = 5.0f; trainData.at<float>(8, 1) = 3.4000001f; trainData.at<float>(8, 2) = 1.5f; trainData.at<float>(8, 3) = 0.2f; 
trainData.at<float>(9, 0) = 6.4000001f; trainData.at<float>(9, 1) = 2.9000001f; trainData.at<float>(9, 2) = 4.3000002f; trainData.at<float>(9, 3) = 1.3f; 
trainData.at<float>(10, 0) = 7.1999998f; trainData.at<float>(10, 1) = 3.5999999f; trainData.at<float>(10, 2) = 6.0999999f; trainData.at<float>(10, 3) = 2.5f; 
trainData.at<float>(11, 0) = 5.0999999f; trainData.at<float>(11, 1) = 3.3f; trainData.at<float>(11, 2) = 1.7f; trainData.at<float>(11, 3) = 0.5f; 
trainData.at<float>(12, 0) = 7.1999998f; trainData.at<float>(12, 1) = 3.0f; trainData.at<float>(12, 2) = 5.8000002f; trainData.at<float>(12, 3) = 1.6f; 
trainData.at<float>(13, 0) = 6.0999999f; trainData.at<float>(13, 1) = 2.8f; trainData.at<float>(13, 2) = 4.0f; trainData.at<float>(13, 3) = 1.3f; 
trainData.at<float>(14, 0) = 5.8000002f; trainData.at<float>(14, 1) = 2.7f; trainData.at<float>(14, 2) = 4.0999999f; trainData.at<float>(14, 3) = 1.0f; 

cv::Mat trainLabels(15, 1, CV_32FC1); 
trainLabels.at<float>(0, 0) = 0; trainLabels.at<float>(1, 0) = 0; 
trainLabels.at<float>(2, 0) = 0; trainLabels.at<float>(3, 0) = 0; 
trainLabels.at<float>(4, 0) = 0; trainLabels.at<float>(5, 0) = 0; 
trainLabels.at<float>(6, 0) = 1; trainLabels.at<float>(7, 0) = 0; 
trainLabels.at<float>(8, 0) = 0; trainLabels.at<float>(9, 0) = 0; 
trainLabels.at<float>(10, 0) = 1; trainLabels.at<float>(11, 0) = 0; 
trainLabels.at<float>(12, 0) = 1; trainLabels.at<float>(13, 0) = 0; trainLabels.at<float>(14, 0) = 0; 

cv::Mat layers = cv::Mat(3, 1, CV_32SC1); 
layers.row(0) = cv::Scalar(trainData.cols); 
layers.row(1) = cv::Scalar(4); 
layers.row(2) = cv::Scalar(1); 
nn->setLayerSizes(layers); 
nn->train(trainData, cv::ml::SampleTypes::ROW_SAMPLE, trainLabels); 

cv::Mat out; 
nn->predict(trainData.row(6), out); 

for (int y = 0; y< out.cols; y++) { 
    std::cout << out.row(0).col(y) << ","; 
} 

std::cout << std::endl; 

Ausgang ist:

[nan]

trainData Matrix hat 15 Zeilen und 4 Spalten, Werte werden manuell eingestellt. trainLabels ist eine Matrix aus 15 Zeilen und 1 Spalte.

Ich verwende Visual Studio 2015 und Projekt ist x86.

bearbeiten Wenn ich spare den algortihm mit nn-> save ("file") bekomme ich folgende:

<?xml version="1.0"?> 
<opencv_storage> 
<opencv_ml_ann_mlp> 
    <format>3</format> 
    <layer_sizes> 
    4 2 1</layer_sizes> 
    <activation_function>SIGMOID_SYM</activation_function> 
    <f_param1>1.</f_param1> 
    <f_param2>1.</f_param2> 
    <min_val>0.</min_val> 
    <max_val>0.</max_val> 
    <min_val1>0.</min_val1> 
    <max_val1>0.</max_val1> 
    <training_params> 
    <train_method>BACKPROP</train_method> 
    <dw_scale>1.0000000000000001e-01</dw_scale> 
    <moment_scale>1.0000000000000001e-01</moment_scale> 
    <term_criteria> 
     <iterations>100000</iterations></term_criteria></training_params> 
    <input_scale> 
    3.0610774975484543e+02 -7.2105386030315177e+00 
    6.5791999914499740e+02 -7.6542332347898991e+00 
    1.4846784833724132e+02 -2.1387134611442429e+00 
    3.7586804114718842e+02 -1.5919117803235303e+00</input_scale> 
    <output_scale> 
    .Inf .Nan</output_scale> 
    <inv_output_scale> 
    0. 0.</inv_output_scale> 
    <weights> 
    <_> 
     -9.9393472658672849e-02 -2.6465950290426005e-01 
     7.0886408359726163e-02 2.9121955862626381e-01 
     5.6651702579549310e-02 -2.1540916480791003e-01 
     -1.0692250684467182e-01 -2.4494868679529785e-01 
     5.2300263291242721e-01 7.7835339395571990e-03</_> 
    <_> 
     6.8110331452494011e-01 -1.4243818904976885e-01 
     -1.7380883866714303e-01</_></weights></opencv_ml_ann_mlp> 
</opencv_storage> 

Antwort

4

OK, nach einer gewissen Zeit zu versuchen, mögliche Kombinationen ich eine Lösung gefunden.

Die Aktivierungsfunktion muss nach dem Einstellen der Schichtgrößen eingestellt werden. Ich weiß nicht genau warum, aber wenn ich Zeilen wie diese

nn->setLayerSizes(layers); 
nn->setActivationFunction(cv::ml::ANN_MLP::SIGMOID_SYM); 

ihre Arbeit flippt. Wenn jemand den Grund dafür kennt, bitte sag es mir.

+1

Oh wow, ich kratzte mich auch über diesen lächerlichen Käfer. Danke, dass du es herausgefunden hast! – Kent