【问题标题】:OpenCV Error When Train ANN_MLP训练 ANN_MLP 时出现 OpenCV 错误
【发布时间】:2016-04-24 23:55:19
【问题描述】:

我希望训练神经网络对两种类型的图像进行分类,但是当训练网络时出现此错误:

OpenCV 错误:cv 中的参数错误(输出训练数据应为浮点矩阵,其行数等于训练样本数,列数等于最后(输出)层的大小): :ml::ANN_MLPImpl::prepare_to_train,文件 C:\buildslave64\win64_amdocl\master_PackSlave-win64-vc14-shared\opencv\modules\ml\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);
    }
}

我不明白为什么会这样!请帮帮我,谢谢。

【问题讨论】:

    标签: c++ opencv


    【解决方案1】:

    ann 的 train 响应与通常的 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 列。 一种方法(有无穷无尽的..)是:

    // 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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-12
      • 1970-01-01
      • 2021-05-18
      • 1970-01-01
      • 1970-01-01
      • 2015-02-08
      • 2019-06-22
      • 1970-01-01
      相关资源
      最近更新 更多