2013-05-30 7 views
5

Przekazuję algorytm, który używa Maszyny Wektorów Pomocniczych z Pythona (przy użyciu scikit-learn) do C++ (przy użyciu biblioteki uczenia maszynowego OpenCV).Importuj wyszkoloną maszynę SVM z scikit-learn do OpenCV

Mam dostęp do wyszkolonej maszyny SVM w Pythonie i mogę zaimportować parametry modelu SVM z pliku XML do OpenCV. Ponieważ implementacja SVM zarówno scikit-learn, jak i OpenCV opiera się na LibSVM, myślę, że powinno być możliwe wykorzystanie parametrów wyszkolonej SVM scikit w OpenCV.

Poniższy przykład pokazuje plik XML, który może być użyty do zainicjowania SVM w OpenCV:

<?xml version="1.0"?> 
<opencv_storage> 
<my_svm type_id="opencv-ml-svm"> 
    <svm_type>C_SVC</svm_type> 
    <kernel><type>RBF</type> 
    <gamma>0.058823529411764705</gamma></kernel> 
    <C>100</C> 
    <term_criteria><epsilon>0.0</epsilon> 
    <iterations>1000</iterations></term_criteria> 
    <var_all>17</var_all> 
    <var_count>17</var_count> 
    <class_count>2</class_count> 
    <class_labels type_id="opencv-matrix"> 
    <rows>1</rows> 
    <cols>2</cols> 
    <dt>i</dt> 
    <data> 
     0 1</data></class_labels> 
    <sv_total>20</sv_total> 
    <support_vectors> 
    <_> 
     2.562423055146794554e-02 1.195797425735170838e-01 
     8.541410183822648050e-02 9.395551202204914520e-02 
     1.622867934926303379e-01 3.074907666176152077e-01 
     4.099876888234874062e-01 4.697775601102455179e-01 
     3.074907666176152077e-01 3.416564073529061440e-01 
     5.124846110293592716e-01 5.039432008455355660e-01 
     5.466502517646497639e-01 1.494746782168964394e+00 
     4.168208169705446942e+00 7.214937388193202183e-01 
     7.400275229357797802e-01</_> 
    <!-- omit 19 vectors to keep it short --> 
    </support_vectors> 
    <decision_functions> 
    <_> 
     <sv_count>20</sv_count> 
     <rho>-5.137523249549433402e+00</rho> 
     <alpha> 
     2.668992955678978518e+01 7.079767098112181145e+01 
     3.554240018130368384e+01 4.787014908624512088e+01 
     1.308470223155845069e+01 5.499185410034550614e+01 
     4.160483074010306126e+01 2.885504210853826379e+01 
     7.816431542954153144e+01 6.882061506693679576e+01 
     1.069534676985309574e+01 -1.000000000000000000e+02 
     -5.088050252552544350e+01 -1.101740897543916375e+01 
     -7.519686789702373630e+01 -3.893481464245511603e+01 
     -9.497774056452135483e+01 -4.688632332663718927e+00 
     -1.972745089701982835e+01 -8.169343841768861125e+01</alpha> 
     <index> 
     0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
     </index></_></decision_functions></my_svm> 
</opencv_storage> 

Chciałbym teraz, aby wypełnić ten plik XML z wartościami z przeszkoloną scikit-learn SVM. Ale nie jestem pewien, w jaki sposób odpowiadają parametry scikit-learn i OpenCV. Oto co mam do tej pory (clf jest przedmiotem klasyfikator w Pythonie):

  • <kernel><gamma> odpowiada clf.gamma
  • <C> odpowiada na clf.C
  • <term_criteria><epsilon> odpowiada clf.tol
  • <support_vectors> odpowiada clf.support_vectors_

Czy to jest poprawne do tej pory? Oto elementy, których nie jestem pewien:

  • Co z <term_criteria><iterations>?
  • Czy <decision_functions><_><rho> odpowiada clf.intercept_?
  • Czy <decision_functions><_><alpha> odpowiada clf.dual_coef_? Tutaj nie jestem pewien, ponieważ dokumentacja naukowo-techniczna zawiera "dual_coef_, która zawiera produkt". Wygląda na to, że OpenCV spodziewa się, że będzie tylko α i, a nie y iA.

Odpowiedz

6

Już nie potrzebujesz epsilon i iterations, są one używane w problemach optymalizacji treningu. Możesz ustawić je na swój ulubiony numer lub zignorować je.

Przenoszenie wektorów pomocniczych może wymagać trochę skrzypiec, ponieważ indeksowanie może się różnić między i . Kod XML w twoim przykładzie nie ma na przykład rozproszonego formatu.

chodzi o inne parametry:

  • rho powinna odpowiadać intercept_, ale być może trzeba zmienić znak.
  • scikit's dual_coef_ odpowiada sv_coef w standardowych modelach (czyli alpha_i * y_i).

Jeśli skarży się na wartości, które zapewniają alpha przy przenoszeniu użyć wartości bezwzględne jest dual_coef_ (na przykład wszystkie dodatnie). Są to prawdziwe wartości alfa modelu SVM.

+0

Dziękuję za tę odpowiedź. Jeszcze tego nie próbowałem, ale i tak twoja odpowiedź zawiera bardzo przydatne informacje. Jak mogę się dowiedzieć, czy muszę zmienić znak "intercept_"? –

+1

@RobertHegner, możesz użyć kilku punktów testowych, identycznych w scikit i opencv. Jeśli znak przecięcia jest błędny, wartości decyzji w prognozie różnią się dokładnie o 2 * przecięcie. –

+1

Podobnie jak odniesienie dla innych: nie musiałem zmieniać znaku 'intercept_' i nie musiałem używać wartości bezwzględnej' dual_coef_'. Wygląda na to, że działa doskonale! Jeszcze raz dziękuję Marc! –