由于DSP片上存储空间有限,只有2M,放了一个Haar特征检测模型之后,再没有多少存储空间了。用libsvm训练出来一个11M的模型没法移植上去,于是想到了试试liblinear。结果发现liblinear训练好的模型小了很多,精度和libsvm差不多。

在vs2012建立一个工程,把liblinear里的blas.h 、blasp.h、linear.h、tron.h、daxpy.cpp、ddot.cpp、dnrm2.cpp、dscal.cpp、linear.cpp、tron.cpp导入你的项目中。

CxLibLinear.h

#ifndef _CXLIBLINEAR_H_H_
#define _CXLIBLINEAR_H_H_#include <string>
#include <vector>
#include <iostream>
#include "linear.h"using namespace std;//内存分配
#define Malloc(type,n) (type *)malloc((n)*sizeof(type))class CxLibLinear
{
public:struct parameter param;private:struct feature_node *x_space;struct problem prob;struct model* model_;public:CxLibLinear();~CxLibLinear();void init_linear_param(struct parameter& param);void train_model(const vector<vector<double>>&  x, const vector<double>& y, const struct parameter& param);int do_predict(const vector<double>& x,double& prob_est);void do_cross_validation(const vector<vector<double>>& x, const vector<double>& y, const struct parameter& param, const int & nr_fold);int load_linear_model(string model_path);int save_linear_model(string model_path);void free_model();
};#endif

CxLibLinear.cpp

#include "stdafx.h"
#include "CxLibLinear.h"CxLibLinear::CxLibLinear()
{model_ = NULL;
}CxLibLinear::~CxLibLinear()
{free_model();
}void CxLibLinear::init_linear_param(struct parameter& param)
{//参数初始化,参数调整部分在这里修改即可// 默认参数param.solver_type = L2R_L2LOSS_SVC;param.eps = 0.001;param.C = 2;param.nr_weight = 0;param.weight_label = NULL;param.weight = NULL;param.p = 0.001;param.init_sol = NULL;
}void CxLibLinear::train_model(const vector<vector<double>>& x, const vector<double>& y, const struct parameter& param)
{if (x.size() == 0){return;}//释放先前的模型free_model();/*初始化*/        long    len = x.size();long    dim = x[0].size();long    elements = len * dim;//转换数据为liblinear格式prob.l = len;prob.n = dim;prob.bias = -1.0;prob.y = Malloc(double, prob.l);prob.x = Malloc(struct feature_node *, prob.l);x_space = Malloc(struct feature_node, elements + len);int j = 0;for (int l = 0; l < len; l++){prob.x[l] = &x_space[j];for (int d = 0; d < dim; d++){                x_space[j].index = d+1;x_space[j].value = x[l][d];    j++;}x_space[j++].index = -1;prob.y[l] = y[l];}/*训练*/model_ = train(&prob, &param);
}int CxLibLinear::do_predict(const vector<double>& x,double& prob_est)
{//int nr_class=get_nr_class(model_);//double *prob_estimates=NULL;//int n;//int nr_feature=get_nr_feature(model_);//if(model_->bias>=0)//    n=nr_feature+1;//else//   n=nr_feature;//double predict_label;//feature_node* x_test = Malloc(struct feature_node, x.size()+1);//for (unsigned int i = 0; i < x.size(); i++)//{//    if(model_->bias>=0)//    {//     x_test[i].index = n;//     x_test[i].value = model_->bias;//   }// else//  {//     x_test[i].index = i + 1;//        x_test[i].value = x[i];//  }////}//x_test[x.size()].index = -1;////predict_label = predict(model_,x_test);////return (int)predict_label;//数据转换feature_node* x_test = Malloc(struct feature_node, x.size()+1);for (unsigned int i = 0; i < x.size(); i++){x_test[i].index = i + 1;x_test[i].value = x[i];}x_test[x.size()].index = -1;double *probs = new double[model_->nr_class];//存储了所有类别的概率//预测类别和概率int value = (int)predict_values(model_, x_test, probs);for (int k = 0; k < model_->nr_class; k++){//查找类别相对应的概率if (model_->label[k] == value){prob_est = probs[k];break;}}delete[] probs;return value;
}void CxLibLinear::do_cross_validation(const vector<vector<double>>& x, const vector<double>& y, const struct parameter& param, const int & nr_fold)
{if (x.size() == 0)return;/*初始化*/long    len = x.size();long    dim = x[0].size();long    elements = len*dim;//转换数据为liblinear格式prob.l = len;prob.n = dim;prob.y = Malloc(double, prob.l);prob.x = Malloc(struct feature_node *, prob.l);x_space = Malloc(struct feature_node, elements + len);int j = 0;for (int l = 0; l < len; l++){prob.x[l] = &x_space[j];for (int d = 0; d < dim; d++){x_space[j].index = d + 1;x_space[j].value = x[l][d];j++;}x_space[j++].index = -1;prob.y[l] = y[l];}int i;int total_correct = 0;double total_error = 0;double sumv = 0, sumy = 0, sumvv = 0, sumyy = 0, sumvy = 0;double *target = Malloc(double, prob.l);cross_validation(&prob, &param, nr_fold, target);if(param.solver_type == L2R_L2LOSS_SVR ||param.solver_type == L2R_L1LOSS_SVR_DUAL ||param.solver_type == L2R_L2LOSS_SVR_DUAL){for (i = 0; i < prob.l; i++){double y = prob.y[i];double v = target[i];total_error += (v - y)*(v - y);sumv += v;sumy += y;sumvv += v*v;sumyy += y*y;sumvy += v*y;}printf("Cross Validation Mean squared error = %g\n", total_error / prob.l);printf("Cross Validation Squared correlation coefficient = %g\n",((prob.l*sumvy - sumv*sumy)*(prob.l*sumvy - sumv*sumy)) /((prob.l*sumvv - sumv*sumv)*(prob.l*sumyy - sumy*sumy)));}else{for (i = 0; i < prob.l; i++)if (target[i] == prob.y[i])++total_correct;printf("Cross Validation Accuracy = %g%%\n", 100.0*total_correct / prob.l);}free(target);
}int CxLibLinear::load_linear_model(string model_path)
{//释放原来的模型free_model();//导入模型model_ = load_model(model_path.c_str());if (model_ == NULL)return -1;return 0;
}int CxLibLinear::save_linear_model(string model_path)
{int flag = save_model(model_path.c_str(), model_);return flag;
}void CxLibLinear::free_model()
{if (model_ != NULL){free_and_destroy_model(&model_);destroy_param(&param);if (prob.y != NULL){free(prob.y);prob.y = NULL;}if (prob.x != NULL){free(prob.x);prob.x = NULL;}if (x_space != NULL){free(x_space);x_space = NULL;}}
}

main.cpp

#include "stdafx.h"
#include "CxLibLinear.h"
#include <time.h>
#include <iostream>
using namespace std;void gen_train_sample(vector<vector<double>>& x, vector<double>& y, long sample_num, long dim, double scale);void gen_test_sample(vector<double>& x, long sample_num, long dim, double scale);int _tmain(int argc, _TCHAR* argv[])
{//初始化liblinear对象CxLibLinear    linear;linear.init_linear_param(linear.param);/*1、准备训练数据*/vector<vector<double>>    x;    //样本集vector<double>    y;            //样本类别标签集gen_train_sample(x, y, 2000, 288, 1);/*1、交叉验证*/int fold = 10;linear.do_cross_validation(x, y, linear.param, fold);/*2、训练*/linear.train_model(x, y, linear.param);/*3、保存模型*/string model_path = "linear_model.txt";linear.save_linear_model(model_path);/*4、导入模型*/linear.load_linear_model(model_path);/*5、预测*///生成随机测试数据vector<double> x_test;gen_test_sample(x_test, 2000, 288, -1);double prob_est;//预测int value = linear.do_predict(x_test, prob_est);//打印预测类别和概率printf("label: %d ", value);return 0;
}void gen_train_sample(vector<vector<double>>& x, vector<double>& y, long sample_num, long dim, double scale)
{srand((unsigned)time(NULL));//随机数//生成随机的正类样本for (int i = 0; i < sample_num; i++){vector<double> rx;for (int j = 0; j < dim; j++){rx.push_back(scale*(rand() % dim));}x.push_back(rx);y.push_back(1);//printf("y = %d \n",(int)y[i]);}//生成随机的负类样本for (int m = 0; m < sample_num; m++){vector<double> rx;for (int n = 0; n < dim; n++){rx.push_back(-scale*(rand() % dim));}x.push_back(rx);y.push_back(2);//printf("y = %d \n",(int)y[sample_num + m]);}
}void gen_test_sample(vector<double>& x, long sample_num, long dim, double scale)
{srand((unsigned)time(NULL));//随机数//生成随机的正类样本for (int j = 0; j < dim; j++){x.push_back(-scale*(rand() % dim));}
}

封装liblinear为C++类相关推荐

  1. 简单封装浏览器 cookie 工具类

    版权声明:本文首发 http://asing1elife.com ,转载请注明出处. https://blog.csdn.net/asing1elife/article/details/8265571 ...

  2. 封装,多态,类的约束,super()深入了解

    python面向对象的三大特性:继承,封装,多态. 1. 封装: 把很多数据封装到⼀个对象中. 把固定功能的代码封装到⼀个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想. 具体的情况具体分 ...

  3. cookie工具类 java_springboot封装JsonUtil,CookieUtil工具类代码实例

    这篇文章主要介绍了springboot封装JsonUtil,CookieUtil工具类过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Jso ...

  4. 封装SQLDMO操作的类

    封装SQLDMO操作的类,能完成常用的SQL Server 2000管理工作. 使用前请添加 "Microsoft SQLDMO Object Library" COM 引用. 有 ...

  5. php连接数据库封装函数,PHP基于MySQLI函数封装的数据库连接工具类【定义与用法】...

    本文实例讲述了PHP基于MySQLI函数封装的数据库连接工具类.分享给大家供大家参考,具体如下: mysql.class.php: class mysql { private $mysqli; pri ...

  6. python程序如何封装成接口_python接口自动化如何封装获取常量的类

    这篇文章主要介绍了python接口自动化如何封装获取常量的类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 背景: 一.执行case的过程: 首先需 ...

  7. android封装好的Color类中的常量

    通过android封装好的Color类中的常量 public static final int BLACK = 0xFF000000; public static final int DKGRAY = ...

  8. phppage类封装分页功能_PHP封装的page分页类定义与用法完整示例

    本文实例讲述了PHP封装的page分页类定义与用法.分享给大家供大家参考,具体如下: 亲测有效,见下图=========> 1. 测试实例test.php header("Conten ...

  9. 【博主推荐】Python 基于Xlwings、Openpyxl自己重新封装Python操作Excel类

    1.简介:Python操作Excel,常用Xlwings.Openpyxl类,由于其知识琐碎,使用起来不太方便,因此自己把常用用法重新封装一个操作类. 2.应用场景:使用Python操作Excel,读 ...

最新文章

  1. 在origin 2018中同时画两个图,带errorbar和不带errorbar两种情况
  2. DL之U-Net:U-Net算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略
  3. Mac下文件的编码及修改编码
  4. thinkphp5记录
  5. @MapperScan和@ComponentScan使用问题
  6. Mysql 零距离-入门(三)数据类型
  7. SSM整合——实现图书的查询功能
  8. ESP8266 wifi钓鱼
  9. 【MySQL】mysql死锁以及死锁日志分析
  10. python从入门到精通-小白如何系统学习python,从入门到精通?
  11. Python 从入门到进阶
  12. weekend110(Hadoop)的 第七天笔记
  13. iOS面试开发-这样的简历才是面试官想看的
  14. 小程序使用有赞 UI 库
  15. Android下的配置管理之道之对 OTA 更新包进行签名
  16. EDIUS和Premiere两款视频剪辑软件哪个好
  17. windows10配置jdk8和jdk11并存和切换
  18. python自动获取微信公众号最新文章
  19. VSCode中snippets(代码模板)的使用
  20. 静态代码分析工具清单:开源篇(各语言)

热门文章

  1. 【Java 8 新特性】Java Comparator.comparing | 提取对象属性,按照指定规则排序
  2. 使用LIRe来实现基于多特征描述符的图像检索系统
  3. 计算机错误1053,电脑提示Windows Modules Installer服务启动1053错误怎么回事
  4. Carl这个英文名怎么样,有什么具体的含义
  5. php 64位整数,32位和64位PHP和MySQL里的整型范围
  6. CVBS全电视信号的一些基本知识
  7. 谈谈如何高效使用搜索引擎找到自己想要的内容
  8. 3_机器学习数学基础知识
  9. 时代亿信CA认证概述
  10. 广东省计算机应用专业综合理论知识,计算机应用专业综合理论考试大纲.doc