2016-04-24 71 views
0

我想训练神经网络分类两件式的图像,但是当列车网络发生这样的错误:OpenCV的错误当火车ANN_MLP

OpenCV的错误:错误的参数(输出训练数据应该是一个浮点矩阵数的行等于训练样本的数量和等于最后(输出)层的大小的列的数量)在cv :: ml :: ANN_MLPImpl :: prepare_to_train中,文件C:\ buildslave64 \ win64_amdocl \ master_PackSlave-win64-vc14 -shared \的OpenCV \模块\毫升\ SRC \ ann_mlp.cpp,线675

我的代码:

#include "opencv2\core.hpp" 
#include "opencv2\imgproc.hpp" 
#include "opencv2\imgcodecs.hpp" 
#include "opencv2\highgui.hpp" 
#include "opencv2\ml.hpp" 
#include <string> 
#include "lbp.h" 
using namespace cv; 
using namespace cv::ml; 
void LoadTrainingData(); 

Mat Data; 
Mat Lables; 
//const int numberOfClass1 = 2384; 
//const int numberOfClass2 = 2462; 
const int numberOfClass1 = 23; 
const int numberOfClass2 = 24; 
int Class1 = 1; 
int Class2 = -1; 
const int imageDimention = 22; 

std::string NumberToString(size_t Number) 
{ 
    std::stringstream ss; 
    ss << Number; 
    return ss.str(); 
} 



void main() { 
    LoadTrainingData(); 
    Ptr<ANN_MLP> annClassifier; 
    annClassifier = ANN_MLP::create(); 
    annClassifier->setActivationFunction(ANN_MLP::ActivationFunctions::SIGMOID_SYM); 
    Mat layers(1, 3, CV_32F); 
    layers.at<float>(0) = Data.cols; 
    layers.at<float>(1) = 100; 
    layers.at<float>(2) = 2; 
    annClassifier->setLayerSizes(layers); 
    annClassifier->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6)); 
    annClassifier->setTrainMethod(ANN_MLP::TrainingMethods::BACKPROP); 
    bool trained = annClassifier->train(Data,ROW_SAMPLE,Lables); 
    if (trained) 
     annClassifier->save("Ann_sigmoid_eye"); 

} 
void LoadTrainingData() { 

    Data = Mat(numberOfClass1 + numberOfClass2, imageDimention*imageDimention, CV_32FC1); 
    Lables = Mat(numberOfClass1 + numberOfClass2,1 , CV_32SC1); 
    // load openEye 
    Mat img; 
    Mat lbpImg; 
    Mat row; 
    std::string path; 
    for (size_t i = 1; i <= numberOfClass2; i++) 
    { 
     path = "class1 (" + NumberToString(i) + ").jpg"; 
     img = imread(path); 
     if (img.channels() > 1) 
      cvtColor(img, img, CV_BGR2GRAY); 
     lbp::ELBP(img,lbpImg, 1, 16);  
     row = lbpImg.reshape(0, 1); 
     row.convertTo(row, CV_32FC1); 
     Data.push_back(row); 
     Lables.push_back(Class1); 

    } 
    for (size_t i = 1; i <= numberOfClass1; i++) 
    { 
     path ="class2 (" + NumberToString(i) + ").jpg"; 
     img = imread(path); 
     if (img.channels() > 1) 
      cvtColor(img, img, CV_BGR2GRAY); 
     lbp::ELBP(img,lbpImg, 1, 16); 
     row = lbpImg.reshape(0, 1); 
     row.convertTo(row, CV_32FC1); 
     Data.push_back(row); 
     Lables.push_back(Class2); 
    } 
} 

我不这样做的原因!请帮助我,谢谢。

回答

0

对于ann的火车响应与通常的opencv ml方法有点不同。

如果您的ann中有2个输出神经元,那么每个训练特征也需要2个输出神经元,而不是单个“类标签”(例如使用SVM)。

它应该是这样的:

[train_data]    [train_responses] 

lbpfeature1     -1 1  // class A 
lbpfeature2     -1 1  // class A 
lbpfeature3     1 -1  // class B 
lbpfeature4     1 -1  // class B 

因此,响应必须NUM_FEATURES行X 2周的cols。 单程(有无尽..)将是:

// leave Labels empty (btw, your original code seems to leave the 1st element empty) 
    // Lables = Mat(numberOfClass1 + numberOfClass2,1 , CV_32SC1); 

    // instead of 
    //Lables.push_back(Class1); 
    Lables.push_back(1.0f); 
    Lables.push_back(-1.0f); 

    // and instead of 
    //Lables.push_back(Class2); 
    Lables.push_back(-1.0f); 
    Lables.push_back(1.0f); 

    // then, before training, reshape to N x 2: 
    Labels = Labels.reshape(1, Labels.rows/2); 
    Data.convertTo(Data, CV_32FC1); 
    Lables.convertTo(Lables, CV_32FC1);