opencv7-ml之统计模型
在opencv的ml模块中有个统计模型类,而其他的比如朴素贝叶斯分类器、knn、svm等等其他模型都是基于该模型上派生出来的。所以先介绍下该模型。
该类的定义在文件“opencv\sources\modules\ml\include\opencv2\ml\ml.hpp”中:
class CV_EXPORTS_W CvStatModel
{
public:
CvStatModel();
virtual ~CvStatModel();
virtual void clear();
//save函数用来将整个模型状态保持到指定的XML 或者YAML文件中,并按照具体的类看是使用默认的名字还是指定的名字.
//使用了CxCore中的数据持久性功能。
CV_WRAP virtual void save(const char* filename, const char* name = 0) const;
// load函数从指定的XML或者YAML中装载模型中指定的或者默认名字部分 //而之前的被装载的模型已经通过CvStatModel::clear()初始化了.
CV_WRAP virtual void load(const char* filename, const char* name = 0);
// write函数会以将完整的模型以指定或者默认名字存储到文件中。该函数会被 CvStatModel::save()调用.
virtual void write(CvFileStorage* storage, const char* name) const;
// read函数会从文件中指定的节点上读取整个模型。使用函数GetFileNodeByName()来定位节点。
//之前的模型也是需要被函数 CvStatModel::clear()初始化的.
virtual void read(CvFileStorage* storage, CvFileNode* node);
//下面这几个函数被注释掉是因为它们不存在该模型中,只是对于其他的ml模型
//来说是有的,所以这里就完全不设定该函数,只是虽然各自派生的ml模型有各
//自的这几个函数,可是行为还是很类似的,所以就统一在该基类中介绍了。
// virtual bool train( const Mat& train_data, [int tflag,] ...,
// const Mat& responses, ..., [const Mat& var_idx,] ...,
// [const Mat& sample_idx,] ... [const Mat& var_type,] ...,
// [const Mat& missing_mask,] <misc_training_alg_params> ...
// )=0;
// virtual float predict( const Mat& sample ... ) const=0;
protected:
const char* default_model_name;
};
实现部分:
在文件“\opencv\sources\modules\ml\src\inner_functions.cpp”中
#include "precomp.hpp"
//构造函数,对该类唯一的类成员进行赋值
CvStatModel::CvStatModel()
{
default_model_name = "my_stat_model";
}
//虚析构函数,调用虚函数clear()来执行不同的类的清理工作
CvStatModel::~CvStatModel()
{
clear();
}
void CvStatModel::clear(){}
//写函数,将数据写入到指定的文件中
void CvStatModel::save( const char* filename, const char* name ) const
{
//存储文件的指针初始化
CvFileStorage* fs = 0;
//
CV_FUNCNAME( "CvStatModel::save" );
__BEGIN__;
//打开传入该函数的文件
CV_CALL( fs = cvOpenFileStorage( filename, 0, CV_STORAGE_WRITE ));
if( !fs )
CV_ERROR( CV_StsError, "Could not open the file storage. Check the path and permissions" );
//如果未传入模型的名字,则写入默认的模型名字
write( fs, name ? name : default_model_name );
__END__;
//释放指向文件的指针
cvReleaseFileStorage( &fs );
}
//装载指定文件中的数据
void CvStatModel::load( const char* filename, const char* name )
{
CvFileStorage* fs = 0;
CV_FUNCNAME( "CvStatModel::load" );
__BEGIN__;
CvFileNode* model_node = 0;
CV_CALL( fs = cvOpenFileStorage( filename, 0, CV_STORAGE_READ ));
if( !fs )
EXIT;
if( name )
model_node = cvGetFileNodeByName( fs, 0, name );
else
{
CvFileNode* root = cvGetRootFileNode( fs );
if( root->data.seq->total > 0 )
model_node = (CvFileNode*)cvGetSeqElem( root->data.seq, 0 );
}
read( fs, model_node );
__END__;
//释放指向文件的指针
cvReleaseFileStorage( &fs );
}
//写函数
void CvStatModel::write( CvFileStorage*, const char* ) const
{
OPENCV_ERROR( CV_StsNotImplemented, "CvStatModel::write", "" );
}
void CvStatModel::read( CvFileStorage*, CvFileNode* )
{
OPENCV_ERROR( CV_StsNotImplemented, "CvStatModel::read", "" );
}
该文件中还有大量的数学计算函数,比如矩阵分解,从GMM上采样等等。
备注:好了这里就主要介绍下几个不存在于该类的函数。
1、模型训练函数
bool CvStatModel::train(const Mat& train_data, [int tflag,] ..., const Mat& responses, ..., [const
Mat& var_idx,] ..., [const Mat& sample_idx,] ... [const Mat& var_type,] ...,
[const Mat& missing_mask,] <misc_training_alg_params> ... ) = 0
该函数是通过输入特征向量和对应的输出目标值(responses)来训练模型的。输入和输出的向量/值都是以矩阵的形式传递的。默认情况下输入特征向量是以train_data rows,也就是一个训练样本中所有的成分(特征)是连续存储的。不过一些算法是需要处理它们的转置形式的,只要当基于所有的输入集合中的特征都是连续存储的(个人:其实也就是存储成一个矩阵而不是链表).如果两种布局都支持的话,那么该方法将会有个tflag参数用来指定具体的情况。
• tflag=CV_ROW_SAMPLE 特征向量以行形式存储;
• tflag=CV_COL_SAMPLE 特征向量以列形式存储。
train_data 必须是 CV_32FC1 (32位浮点类型,单通道) 格式的. 而Responses通常存储成1D向量(一行或者一列)形式 ,格式有: CV_32SC1(只在分类的时候用); CV_32FC1, 其中一个输入向量对应着一个目标值.
对于分类问题来说, responses 是离散的标签;
对于回归问题来说,responses 是模型函数需要逼近的值。
一些算法只能用来分类;一些算法只能用来回归;还有一些能用在两方面。对于回归来说,输出变量的类型既可以是通过独立的参数传递也可以是var_type向量的最后一个元素:
• CV_VAR_CATEGORICAL 输出变量是离散的类别标签;
• CV_VAR_ORDERED(=CV_VAR_NUMERICAL) 输出的值是有序的,也就是说两个不同的值可以进行数值对比,当然这是一个回归问题。
输入变量的类型可以通过var_type指定。大多数算法只能处理有序的输入变量。
许多ML模型会在一个特征子集或者是训练集中样本子集上进行训练,为了能够容易的在不同状态间选择,该函数还包含了var_idx 和 sample_idx 这两个参数。前者是用来指定感兴趣的变量(特征);后者是用来指定感兴趣的样本。这两个向量都是整型向量 (CV_32SC1) ,(当然是基于0开始索引的)或者是基于激活的变量/样本的8位 (CV_8UC1)标记。当传递一个NULL指针给这两个参数时,也就意味着所有的变量/样本都会用来训练。
另外,许多算法可以处理缺失的值的情况,也就是说当某个具体的训练样本的特征的值是未知的(比如,忘记测量一个病人在礼拜一时候的体温)参数 missing_mask,是一个与train_data 具有相同size的8位的矩阵,它用来标记缺失的值(即该标记矩阵中非0值)
通常来说,在进入到训练阶段之前的模型的状态是需要调用CvStatModel::clear()来重置的 ;不过某些算法会让你选择是否使用新的训练数据来更新模型的状态而不是重置他们。
float CvStatModel::predict(const Mat& sample, ...) const
该函数用来对一个新的样本进行预测其response。在分类问题中,该方法返回一个类别标签;在回归问题上,盖方法返回一个函数值 。输入的样本必须与传递给train函数中train_data一样大的特征维度。如果var_idx 参数传递给了train,那么记得,也同时只提取必须的特征给该函数。后缀的const表示该预测函数不会影响到模型的内部状态,所以该方法可以安全的在不同的线程中被调用。
opencv7-ml之统计模型的更多相关文章
- 关于ML.NET v0.6的发布说明
ML.NET 0.6版本提供了几项令人兴奋的新增功能: 用于构建和使用机器学习模型的新API 我们主要关注的是发布用于构建和使用模型的新ML.NET API的第一次迭代.这些新的,更灵活的API支持新 ...
- ML(1): 入门理论
机器学习相关的文章太多,选取一篇本人认为最赞的,copy文章中部分经典供自己学习,摘抄至 http://www.cnblogs.com/subconscious/p/4107357.html#firs ...
- [ML] I'm back for Machine Learning
Hi, Long time no see. Briefly, I plan to step into this new area, data analysis. In the past few yea ...
- ANN:ML方法与概率图模型
一.ML方法分类: 产生式模型和判别式模型 假定输入x,类别标签y - 产生式模型(生成模型)估计联合概率P(x,y),因可以根据联合概率来生成样本:HMMs ...
- Spark2 ML 学习札记
摘要: 1.pipeline 模式 1.1相关概念 1.2代码示例 2.特征提取,转换以及特征选择 2.1特征提取 2.2特征转换 2.3特征选择 3.模型选择与参数选择 3.1 交叉验证 3.2 训 ...
- [Machine Learning & Algorithm]CAML机器学习系列2:深入浅出ML之Entropy-Based家族
声明:本博客整理自博友@zhouyong计算广告与机器学习-技术共享平台,尊重原创,欢迎感兴趣的博友查看原文. 写在前面 记得在<Pattern Recognition And Machine ...
- [Machine Learning & Algorithm]CAML机器学习系列1:深入浅出ML之Regression家族
声明:本博客整理自博友@zhouyong计算广告与机器学习-技术共享平台,尊重原创,欢迎感兴趣的博友查看原文. 符号定义 这里定义<深入浅出ML>系列中涉及到的公式符号,如无特殊说明,符号 ...
- 机器学习 - ML
CNCC - 2016 | 机器学习(原文链接) Machine Learning - ML,机器学习起源于人工智能,是AI的一个分支. 机器学习的理论基础:计算学习理论 - Computationa ...
- ML 基础知识
A computer program is said to learn from experience E with respect to some task T and some performan ...
随机推荐
- mysql小试题
1. 用户登录日志表 xes_user_login_logs 如下: (1) 检索登录超过两次的用户ID(sql语句) select user_id from vvt_ceshi group by u ...
- Code Signal_练习题_Knapsack Light
You found two items in a treasure chest! The first item weighs weight1 and is worth value1, and the ...
- Salesforce中如何删除调试日志
大家在新建一个用户跟踪标记的时候可能会遇到以下报错:调试日志已经超过了上限,在编辑跟踪标志前,删除一些调试日志.但是在点击“全部删除”按钮删除所有可见的日志后,还是报同样的错误,这时候,我们打开开发者 ...
- JSP内置对象——response对象
看一个实例: 运行结果: 出现了一个很奇怪的现象,这个outer对象输出的字符串,跑到顶部去了.这个呢也就说明了response对象获得的writer对象的输出总是前于我们的内置对象.(respons ...
- go语言练习:幂、函授接收和返回参数、转义字符、变量和常量
1.实现a^b次方 package main func main() { r2 := power1(2,4) println(r2) } func power1(a uint64, b uint64) ...
- 虚拟机压力测试延迟高的可能原因及 ILPIP 配置 / 查询脚本
测试初期 Client VM 的延迟结果正常: 测试后期 Client VM 的延迟偶尔突增/连接失败,越后期超高延迟(比如 30 秒)出现越多: 问题分析 造成这一现象的根本原因很可能是 SNAT( ...
- 无法将数据库从SINGLE_USER模式切换回MULTI_USER模式(Error 5064),及查找SQL Server数据库中用户spid(非SQL Server系统spid)的方法
今天公司SQL Server数据库无意间变为SINGLE_USER模式了,而且使用如下语句切换回MULTI_USER失败: ALTER DATABASE [MyDB] SET MULTI_USER W ...
- VUE中v-on:click事件中获取当前dom元素
在开发中总是忘记, 特意在此记录 关键字: $event <div class="bed" v-on:click="updateBed(index,$e ...
- Spring中的destroy-method方法
1. Bean标签的destroy-method方法 配置数据源的时候,会有一个destroy-method方法 <bean id = "dataSource" class ...
- Linux下搭建lnmp环境
前提:假设阅读本文的读者已经拥有基本的linux使用技巧,能够解决系统安装问题,以及软件安装的技巧. 注意: 本文所涉及的主要安装包(需要下载使用的)安装包,在本文最后会给出百度云盘链接,需要使用的, ...