我正在创建一个应用程序,用于对城市环境图像中的人类进行分类。
我以以下方式训练分类器:
int main (int argc, char **argv)
{
/* STEP 2. Opening the file */
//1. Declare a structure to keep the data
CvMLData cvml;
//2. Read the file
cvml.read_csv ("directory/train_rand.csv");
//3. Indicate which column is the response
cvml.set_response_idx (0);
/* STEP 3. Splitting the samples */
//1. Select 4000 for the training
CvTrainTestSplit cvtts (4000, true);
//2. Assign the division to the data
cvml.set_train_test_split (&cvtts);
printf ("Training ... ");
/* STEP 4. The training */
//1. Declare the classifier
CvBoost boost;
//2. Train it with 100 features
boost.train (&cvml, CvBoostParams (CvBoost::REAL,100, 0, 1, false, 0),
false);
/* STEP 5. Calculating the testing and training error */
// 1. Declare a couple of vectors to save the predictions of each sample
std::vector<float> train_responses, test_responses;
// 2. Calculate the training error
float fl1 = boost.calc_error (&cvml, CV_TRAIN_ERROR, &train_responses);
// 3. Calculate the test error
float fl2 = boost.calc_error (&cvml, CV_TEST_ERROR, &test_responses);
cout<<"Error train: "<<fl1<<endl;
cout<<"Error test: "<<fl2<<endl;
/* STEP 6. Save your classifier */
// Save the trained classifier
boost.save ("./trained_boost_4000samples-100ftrs.xml", "boost");
return 0;
}
train_rand.csv 是一个文件,其中第一列是类别。其余列将成为问题的特征。例如,我可以使用三个功能。它们中的每一个代表图像中每个像素的红色、蓝色和绿色的平均值。所以我的 csv 文件应该是这样的。请注意,在第一列中我使用了一个字符,因此 OpenCV 将其识别为一个类别。
B,124.34,45.4,12.4
B,64.14,45.23,3.23
B,42.32,125.41,23.8
R,224.4,35.34,163.87
R,14.55,12.423,89.67
...
对于我的实际问题,我使用了 100 个特征和 8000 个样本。我用一半的数据训练分类器,用剩下的数据测试。
训练后,我得到了大约 5% 的测试错误(这对于仅 100 个特征来说已经相当不错了)。
现在我想在新数据中使用分类器:
CvBoost boost
boost.load("directory/trained_boost_4000samples-100ftrs.xml");
float x = boost.predict(SampleData,Mat(),Range::all(),false,false);
cout<<x;
我在数千个样本上运行这段代码,它总是输出相同的值,即 2。我真的不明白我在这里做错了什么,但即使我以错误的方式训练分类器,它也不会t 以相同的方式分类 100% 的时间,而且,我之前计算的测试误差表明分类器应该可以正常工作。
困扰我的一件事是 SampleData 必须具有与我用来训练的样本相同数量的列。问题是,用于训练的数据有 100 列 + 1 个响应,如果我尝试运行只有 100 个特征的分类器,它会抛出一个异常,说大小不匹配。如果我用 101 个特征(这绝对是任意的)运行分类器,它可以工作,但结果没有任何意义。
谁能帮我这个?提前致谢!
问候