2016-05-09 8 views
1

現在、私はさまざまな感情の認識のために異なるSVMを訓練しようとしています。たとえば、幸せな感情を認識するために、私は幸せな人のイメージを怒り、恐怖、嫌悪感など他の感情を表現するポジティブやイメージとしてSVMを訓練します。画像は、私がトレーニングセクションとテストセクションで分割したデータベースに保存されています。OpenCV 3.1.0:訓練されたSVMを保存してロードする

私はSVMを訓練したときにすぐにデータベースのテスト画像の精度をテストするためにSVMを使用していますが、これは問題ありません。しかし、私は訓練されたSVMを保存します。なぜなら、他のプログラムでそれらを使用したいので、他のプログラムを開始するたびに再トレーニングしたくないからです。

私はSVMを他のプログラムにロードしましたが、結果は非常に悪かったです。精度は0%に近いものでした。だから私は訓練プログラムにSVMsを保存し、immedialtyロードしようとしましたが、ここでも精度はゼロ%近くになっています。

SVMをロードしてSVMタイプ、カーネルタイプ、およびサポートベクターを出力すると、SVM .xmlファイルと同じであることがわかりました。だから私は、予測が正しい方法で実行されないという問題があると思います。 SVMを保存して適切な方法でロードするかどうかもわかりません。

私は解決策を探してみましたが、成功しませんでした。私が試してみましたリンクには次のものがあります

Train SVM and save it with OpenCV 3.0

How to load previously stored svm classifier?

Load Trained SVM – Emgu CV

opencv 3 (C++) auto trained SVM loading issue

私はSVMのを訓練するとロードせずに、すぐにそれらをテストするために使用するコードそれらは再びです:

trainData = ml::TrainData::create(training_mat, ROW_SAMPLE, label_mat); 
svm = SVM::create(); 
svm->setType(SVM::C_SVC); 
svm->setKernel(SVM::RBF); 
svm->trainAuto(trainData); 
svm->save(svmSaveNames[i]); 

// Test SVMs 
data_file.open(filenameLabelsTestingImages[i]); 
data_file << "Number\n"; 
startTest = stopTest; 
stopTest = startTest + emotionCountersTesting[i]; 
int numberRightClassified = 0; 
int numberClassified = 0; 

for (int j = 0; j < numberOfTestImg; j++) 
{ 
    cv::Mat testing_one_image_mat(1, numberOfFeatures, CV_32F); 
    for (int k = 0; k < numberOfFeatures; k++) 
    { 
     testing_one_image_mat.at<float>(0, k) = testing_mat.at<float>(j, k); 
    } 

    int value_svm = svmNew->predict(testing_one_image_mat); 

    if (value_svm == 1) 
    { 
     if (j >= startTest && j < stopTest) 
     { 
      numberRightClassified++; 
     } 
     numberClassified++; 
    } 
    data_file << value_svm << endl; 
} 
data_file.close(); 

従う

trainData = ml::TrainData::create(training_mat, ROW_SAMPLE, label_mat); 
svm = SVM::create(); 
svm->setType(SVM::C_SVC); 
svm->setKernel(SVM::RBF); 
svm->trainAuto(trainData); 
svm->save(svmSaveNames[i]); 

Ptr<SVM> svmNew = SVM::create(); 
svmNew = SVM::load<SVM>(svmSaveNames[i]); 
//cout << "The type is " << svmNew->getType() << endl; 
//cout << "The kernel type is " << svmNew->getKernelType() << endl; 
//cout << "The support vectors are " << svmNew->getSupportVectors() << endl; 

// Test SVMs 
data_file.open(filenameLabelsTestingImages[i]); 
data_file << "Number\n"; 
startTest = stopTest; 
stopTest = startTest + emotionCountersTesting[i]; 
int numberRightClassified = 0; 
int numberClassified = 0; 

for (int j = 0; j < numberOfTestImg; j++) 
{ 
    cv::Mat testing_one_image_mat(1, numberOfFeatures, CV_32F); 
    for (int k = 0; k < numberOfFeatures; k++) 
    { 
     testing_one_image_mat.at<float>(0, k) = testing_mat.at<float>(j, k); 
    } 

    //int value_svm = svm -> predict(testing_one_image_mat); 
    int value_svm = svmNew->predict(testing_one_image_mat); 

    if (value_svm == 1) 
    { 
     if (j >= startTest && j < stopTest) 
     { 
      numberRightClassified++; 
     } 
     numberClassified++; 
    } 
    data_file << value_svm << endl; 
} 
data_file.close(); 

配列svmSaveNamesは、svm_anger.xmlのような異なるSVMのを保存するための名前の文字列が含まれているとして、私は最初のSVMを保存し、予測のために再びそれらをロードするためのコードを変更するまで、だから、これは正常に動作しますsvm_contempt.xml、...

変数data_fileを使用して、テストされているSVMごとに.txtファイルを作成します。ですからまずSVMを訓練してテストして感情の怒りを認識させ、このSVMをテストしながらすべてのテストイメージを使用します。したがって、すべての画像(1 =正/ -1 =負)の予測はテキストファイルに書き込まれます。

startTestパラメータとstopTestパラメータは、ポジティブ画像が予測値1を与えるかどうかを確認するために使用され、ポジティブとして認識される必要がある画像の範囲内にあるかどうかを確認するために使用されます。データベースのテストマップでは、私はすべての画像をその感情によって最初の怒りと軽蔑を命じました...

2次元マトリックスtesting_matには、感情を予測するためにSVMに与えられたすべてのテスト画像のデータが含まれています。

私の問題は、私がSVMをロードした後、私に正しい予測を与えてくれないことです。

答えて

0

私が線形カーネルを使用すると、何の問題もないことがわかりました。だから私はSVMを保存して読み込むことができ、予測は正しいです。だから私はそれが他のカーネルではなく、線形カーネルで動作する理由を探し始めました。

答えは、OpenCV 3.1にGithubの問題#5054によるバグがあります。私は提案されたソリューションを試しましたが、それでも動作しませんでした。最終的に私はOpenCV 2.4をドローロードしましたが、今はすべてうまくいきます。

+0

私はsvmクラシファイアxmlを生成する方法を教えてください。 –

+0

良い説明のために[OpenCVとSVMを画像で使う](http://stackoverflow.com/questions/14694810/using-opencv-and-svm-with-images)をチェックすることができます。 – Plzzz

関連する問題