关于matlab 中libsvm中model中的保存与调用新发现 博客分类: matlab 图像 matlablibsvmsavemodelloadmodel
代码在网上可以找到,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)
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include "svm.h"
- #include "mex.h"
- #include "svm_model_matlab.h"
- void exit_with_help()
- {
- mexPrintf(
- "Usage: savemodel('filename', model);\n"
- );
- }
- int savemodel(const char *filename, const mxArray *matlab_struct)
- {
- const char *error_msg;
- struct svm_model* model;
- int result;
- model = matlab_matrix_to_model(matlab_struct, &error_msg);
- if (model == NULL)
- {
- mexPrintf("Error: can't read model: %s\n", error_msg);
- }
- result = svm_save_model(filename, model);
- if( result != 0 )
- {
- mexPrintf("Error: can't write model to file!\n");
- }
- return result;
- }
- void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
- {
- if(nrhs == 2)
- {
- char filename[256];
- int *result;
- mxGetString(prhs[0], filename, mxGetN(prhs[0])+1);
- plhs[0] = mxCreateNumericMatrix(1, 1, mxINT8_CLASS, 0);
- result = mxGetPr(plhs[0]);
- *result = savemodel(filename, prhs[1]);
- }
- else
- {
- exit_with_help();
- return;
- }
- }
读取文件中的svm model:( loadmodel.c )
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include "svm.h"
- #include "mex.h"
- #include "svm_model_matlab.h"
- void exit_with_help()
- {
- mexPrintf(
- "Usage: model = loadmodel('filename', num_of_feature);\n"
- );
- }
- void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
- {
- if(nrhs == 2)
- {
- char filename[256];
- int num_of_feature;
- struct svm_model* model;
- int featurenum;
- const char *error_msg;
- mxGetString(prhs[0], filename, mxGetN(prhs[0])+1);
- model = svm_load_model(filename);
- if(model == NULL)
- {
- mexPrintf("Error: can't read the model file!\n");
- return;
- }
- featurenum = *(mxGetPr(prhs[1]));
- error_msg = model_to_matlab_structure(plhs, featurenum, model);
- if(error_msg)
- mexPrintf("Error: can't convert libsvm model to matrix structure: %s\n", error_msg);
- svm_free_and_destroy_model(&model);
- }
- else
- {
- exit_with_help();
- return;
- }
- }
这两个文件放入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);
完美运行