2

都市設定の画像で人間を分類するためのアプリケーションを作成しています。

次の方法で分類子をトレーニングします。

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 は、最初の列がカテゴリであるファイルです。残りの列は、問題の特徴になります。たとえば、3 つの機能を使用できます。それぞれが、画像のピクセルあたりの赤、青、緑の平均を表します。したがって、私の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% の時間を分類します。また、前に計算したテスト エラーは、分類器が正常に機能することを示しています。

私を悩ませていることの 1 つは、SampleData が、トレーニングに使用したサンプルと同じ数の列を持たなければならないことです。問題は、トレーニングに使用されるデータには 100 列 + 1 つの応答があり、100 個の機能のみで分類子を実行しようとすると、サイズが一致しないという例外がスローされるということです。101 個の機能 (これは完全に任意です) で分類器を実行すると機能しますが、結果は意味をなさないものです。

誰でもこれで私を助けることができますか?前もって感謝します!

よろしく

4

1 に答える 1