我希望列车神经网络对两种类型的图像进行分类,但是当列车网络出现这种错误时:
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);
}
}
我不知道为什么会这样!请帮助我,谢谢。
答案 0 :(得分:0)
如果你的ann中有2个输出神经元,每个训练特征也需要2个输出神经元,而不是单个&#34;类标签&#34; (例如与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);