關於matlab 中libsvm中model中的保存與調用新發現

代碼在網上可以找到,savemodel.c與loadmodel.c 我把網上的引用放在下面

 

最近一直在用matlab和libsvm,發現libsvm庫用起來還是很方便的,就是沒有模型直接保存到文件和讀取模型的matlab接口(C++的接口有)。由於有會用的Opencv等C/C++庫,所以數據交換比較麻煩。看了一下libsvm的svm.h、svm.cpp文件,發現有svm_save_model(),svm_load_model()等函數。於是乎用mex小做封裝,寫了兩個matlab可以直接調用的接口。

 

保存svm model到文件:(savemodel.c)

 

[cpp] view plaincopy
 
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <ctype.h>  
  5. #include "svm.h"  
  6.   
  7. #include "mex.h"  
  8. #include "svm_model_matlab.h"  
  9.   
  10.   
  11. void exit_with_help()  
  12. {  
  13.     mexPrintf(  
  14.     "Usage: savemodel('filename', model);\n"  
  15.     );  
  16. }  
  17.   
  18. int savemodel(const char *filename, const mxArray *matlab_struct)  
  19. {  
  20.     const char *error_msg;  
  21.     struct svm_model* model;  
  22.     int result;  
  23.     model = matlab_matrix_to_model(matlab_struct, &error_msg);  
  24.       
  25.     if (model == NULL)  
  26.     {  
  27.         mexPrintf("Error: can't read model: %s\n", error_msg);  
  28.     }  
  29.       
  30.     result = svm_save_model(filename, model);  
  31.       
  32.     if( result != 0 )  
  33.     {  
  34.         mexPrintf("Error: can't write model to file!\n");  
  35.     }  
  36.       
  37.     return result;  
  38. }  
  39.   
  40. void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])  
  41. {  
  42.     if(nrhs == 2)  
  43.     {  
  44.         char filename[256];  
  45.         int *result;  
  46.           
  47.         mxGetString(prhs[0], filename, mxGetN(prhs[0])+1);  
  48.           
  49.         plhs[0] = mxCreateNumericMatrix(1, 1, mxINT8_CLASS, 0);  
  50.           
  51.         result = mxGetPr(plhs[0]);  
  52.         *result = savemodel(filename, prhs[1]);  
  53.     }  
  54.     else  
  55.     {  
  56.         exit_with_help();         
  57.         return;  
  58.     }  
  59. }  


讀取文件中的svm model:( loadmodel.c )

 

 

[cpp] view plaincopy
 
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <ctype.h>  
  5. #include "svm.h"  
  6.   
  7. #include "mex.h"  
  8. #include "svm_model_matlab.h"  
  9.   
  10.   
  11. void exit_with_help()  
  12. {  
  13.     mexPrintf(  
  14.     "Usage: model = loadmodel('filename', num_of_feature);\n"  
  15.     );  
  16. }  
  17.   
  18. void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])  
  19. {  
  20.     if(nrhs == 2)  
  21.     {  
  22.         char filename[256];  
  23.         int num_of_feature;  
  24.         struct svm_model* model;  
  25.         int featurenum;  
  26.         const char *error_msg;  
  27.           
  28.         mxGetString(prhs[0], filename, mxGetN(prhs[0])+1);  
  29.         model = svm_load_model(filename);  
  30.           
  31.         if(model == NULL)  
  32.         {  
  33.             mexPrintf("Error: can't read the model file!\n");  
  34.             return;  
  35.         }  
  36.           
  37.         featurenum = *(mxGetPr(prhs[1]));  
  38.           
  39.         error_msg = model_to_matlab_structure(plhs, featurenum, model);  
  40.           
  41.         if(error_msg)  
  42.             mexPrintf("Error: can't convert libsvm model to matrix structure: %s\n", error_msg);  
  43.           
  44.         svm_free_and_destroy_model(&model);  
  45.     }  
  46.     else  
  47.     {  
  48.         exit_with_help();         
  49.         return;  
  50.     }  
  51. }  


這兩個文件放入libsvm-3.1/matlab目錄下,然後打開同目錄下的make.m文件,添加如下兩行(紅色部分):

 

mex -O -largeArrayDims -I..\ -c ..\svm.cpp
mex -O -largeArrayDims -I..\ -c svm_model_matlab.c
mex -O -largeArrayDims -I..\ svmtrain.c svm.obj svm_model_matlab.obj
mex -O -largeArrayDims -I..\ svmpredict.c svm.obj svm_model_matlab.obj
mex -O -largeArrayDims -I..\ savemodel.c svm.obj svm_model_matlab.obj
mex -O -largeArrayDims -I..\ loadmodel.c svm.obj svm_model_matlab.obj

最後在matlab中,libsvm-3.1/matlab目錄下運行“make”,等到編譯完成後,生成savemodel.mexw32、loadmodel.mexw32兩個文件。(64位的系統生成的兩個文件擴展名不一樣)

此時就可以在matlab中使用savemodel('filename', model)和model = loadmodel('filename', num)來讀取和保存訓練好的svm模型了。

注意:loadmodel接口中的第二個參數num是向量的維度(特徵數),即500個30維的樣本,num=30

(貌似多了這個參數是因爲matlab調用了model_to_matlab_structure這個接口的緣故,在c/c++中讀寫模型就不需用num這個參數了)

 

如果需要在c/c++程序中調用libsvm的模型文件,就直接用svm_save_model(),svm_load_model()等函數進行操作了。

 

我用的版本是libsvm 2.91,savemodel.c沒有問題,loadmodel需要做如下修改

svm_free_and_destroy_model(&model);  修改爲   svm_destroy_model(model);

 

完美運行

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章