Я создаю приложение для классификации людей в изображениях городской среды.openCV C++: Проблемы с CvBoost (класс Adaboost)
Я дрессировать classifer в следующем порядке:
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. я действительно не» я понимаю, что я делаю неправильно здесь, но даже если бы я обучал классификатору неправильным образом, он не классифицировал бы 100% времени таким же образом, также, ошибка теста, которую я вычислил до того, как показывает, что классификатор должен работать хорошо.
Одна вещь, которая меня беспокоит, заключается в том, что SampleData должен иметь такое же количество столбцов, что и образец, который я использовал для обучения. Дело в том, что данные, используемые для обучения, имеют 100 столбцов + 1 ответ, и если я попытаюсь запустить классификатор всего за 100 функций, он выдает исключение, говорящее, что размеры не совпадают. Если я запускаю классификатор с 101 функциями (что абсолютно произвольно), он работает, но результаты не имеют никакого смысла.
Может ли кто-нибудь помочь мне с этим? Заранее спасибо!
С уважением
Я не мог найти какой-либо документации о формате обучающих данных. Вы уверены, что первый столбец - это метка, также примеры, которые я видел, используют реальные значения в качестве ярлыков, можете ли вы сопоставить 'B' /' R' с '-1.0' /' 1.0'? – Robert