本文翻译自OpenCV 2.4.9官方文档《opencv2refman.pdf》。
Originally, support vector machines (SVM) was a technique for building an optimal binary (2-class) classifier. Later the technique was extended to regression and clustering problems. SVM is a partial case of kernel-based methods. It maps feature vectors into a higher-dimensional space using a kernel function and builds an optimal linear discriminating function in this space or an optimal hyper-plane that fits into the training data. In case of SVM, the kernel is not defined explicitly. Instead, a distance between any 2 points in the hyper-space needs to be defined. The solution is optimal, which means that the margin between the separating hyper-plane and the nearest feature vectors from both classes (in case of 2-class classifier) is maximal. The feature vectors that are the closest to the hyper-plane are called support vectors, which means that the position of other vectors does not affect the hyper-plane (the decision function). SVM implementation in OpenCV is based on LibSVM.
通常来说,支持向量机(SVM)是一种用来构建一个最优二进制分类器(只分为两类)。后来,这项技术被延伸到回归与集群问题。SVM是以核函数方法为基础的众多方法之一,它通过核函数将特征向量映射到高维空间,并在这个空间创造一个最优线性分类函数,或者创造一个适合所有训练数据的最优超平面。在SVM中,核函数定义的并不明确,除此之外,在超平面上任意两点之间的距离都需要被定义。 解决方法是最优的,意味着分割超平面与两个分类(即二类分类器)上距离最近的特征向量之间的距离是最大的。距离超平面最近的特征向量被称为支持向量,就是说其它向量的位置都不会影响超平面(即决策函数)。 SVM在OpenCV中的实现是基于LibSVM的。
struct CvParamGrid 该结构体代表了统计模型参数的对数网格范围,它通过更新模型参数来优化统计模型准确度,准确度通过交叉验证的计算进行估计。
网格决定了统计模型参数值的迭代序列,如下所示:
其中n是一个最大索引号,满足:
网格已经经过对数化,所以step一定大于1。
CvParamGrid的构造函数。
整个构造函数初始化了对应的数据成员,默认的构造函数创造的虚拟网格如下:
CvParamGrid::CvParamGrid()
{
min_val = max_val = step = 0;
}
检测网格的有效性。
如果网格有效的,则返回true;如;如果无效,则返回false。当且仅当下列情况时,网格是有效的:
struct CvSVMParams SVM训练参数。结构体将被初始化,并传递给CvSVM的训练函数。
CvSVMParams的构造函数。
SVM公式类型。可能取值如下:
其他具体解释见LibSVM。
SVM核函数类型。可能取值如下:
核函数的参数degreedegree,用于多项式核。
核函数的参数γ\gamma,用于多项式核 / RBF核 / Sigmoid核。
核函数的参数coef0coef0,用于多项式核 / Sigmoid核。
SVM最优问题的参数CC,用于 C_SVC / EPS_SVR / NU_SVR 分类器。
SVM最优问题的参数ν\nu,用于 NU_SVC / ONE_CLASS / NU_SVR 分类器。
SVM最优问题的参数ϵ\epsilon,用于 EPS_SVR 分类器。
C_SVC问题中的最优权重,它被分配给特定的分类。这些权重与因子C做乘运算,所以第 i 个分类的的参数C值应该为:
因此,这些权重对其他分类的误分类惩罚有一定影响,权重越大,对应分类的数据误分类的惩罚越大。
SVM训练迭代的迭代终止标准,用于解决带有约束条件的二次最优规划问题。你也能明确公差与 / 或迭代最大次数。
默认的构造函数使用下列取值初始化该结构体:
CvSVMParams::CvSVMParams() :
svm_type(CvSVM::C_SVC), kernel_type(CvSVM::RBF), degree(0),
gamma(1), coef0(0), C(1), nu(0), p(0), class_weights(0)
{
term_crit = cvTermCriteria( CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
}
支持向量机。
注: · (Python) 使用SVM的数字识别例程可以在路径 opencv_source/samples/python2/digits.py 下找到; · (Python) 使用SVM的网格寻找数字识别可以在路径 opencv_source/samples/python2/digits_adjust.py 下找到; · (Python) 使用SVM的视频数字识别例程可以在路径 opencv_source/samples/python2/digits_video.py 下找到;
默认构造函数与训练构造函数。
构造函数与CvStatModel::CvStatModel()
有相同的形式。可以在本文档的CvStatModel::train()
寻找参数的具体含义。
本文注:
下面从CvStatModel::train()
中找到参数列表:
对于其中参数,解释如下:
通过使用一组输入特征向量并输出相应值(或响应)的方法,训练函数训练了统计模型。输入 / 输出向量(或输入 / 输出值)都以矩阵形式传递。默认情况下,输入特征向量被存入train_data的列中,所有训练向量的组成(即特征)被连续存储。然而当全部输入集的各特定特征值(特征 / 输入变量)的所有值都是连续存储的情况下,一些算法可以处理转置表达式。如果两种布局都支持,训练方法包含的tflag参数起作用,该参数用来明确数据存储方向,具体如下:
训练数据train_data必须使用CV_32FC1格式(32位浮点数,单通道)。返回数据responses通常以一维向量(一行或一列)的形式存储,向量中的数据格式为CV_32SC1(仅在分类问题中)或CV_32FC1,返回数据的每个值与训练数据的每个向量一一对应。相反的,某些类似于各种类型的神经网络,返回数据的类型都为向量形式。 对于分类问题,返回值是离散的分类标签;对于回归问题,返回值是被估计函数的值。一些算法只能处理分类问题,一些算法只能处理回归问题,也有一些算法可以处理两种问题。对于后者,输出参数的类型可以通过两种方式传递:一种是单独的参数,另一种是向量var_type的最后一个元素:
输入变量的类型可以通过输入参数var_type指定。大多数算法仅仅可以处理连续输入变量。 很多 ML (机器学习)模型可以用一个指定的特征子集与 / 或指定的训练集的样本子集进行训练。为了使其对我们更加简单,训练方法train函数通常包含参数var_idx和sample_idx,前者(即var_idx)用来指定该兴趣的变量(特征),后者(即sample_idx)指定感兴趣的样本。两个向量可以使用整数 (CV_32SC1) 向量(基于0的索引列表),也可以使用8位 (CV_8UC1)的活动变量 / 样本。我们也可以传递NULL空指针来代替众多参数,这样的话所有的变量 / 样本都被用来训练。 此外,当已知训练样本的已知特征存在未知值时,一些算法可以处理丢失的量(例如,我们星期一忘记测量病人A的体温)。参数missing_mask是一个与train_data有相同尺寸的8位矩阵,它被用来标记丢失的值(即用非零值进行标记)。 通常,先前的模型统计在运行训练函数之前都被CvStatModel::clear()清除了,然而一些算法可以选择使用新训练数据更新模型统计,而不是重置它。
训练一个SVM。
该函数用来训练一个 SVM 模型,它继承了CvStatModel::train()函数的参数列表,但对下列进行了限制:
所有其他参数都被收集进入CvSVMParams结构体。
用最优参数训练SVM。
train_auto()函数通过从CvSVMParams中选择最优参数C, gamma, p, nu, coef0, degree,自动训练 SVM 模型。当测试集误差的交叉验证估计值达到最小值时,参数被认为是最优的。 如果不需要优化某参数,相应的网格步长应该被设置为任意小于等于1的值。例如为了避免gamma选取最优值,则设置 gamma_grid.step = 0,并令gamma_grid.min_val, gamma_grid.max_val设置为任意值。这种情况下,params.gamma的值将被输入参数gamma赋值。 最后,如果需要优化某参数,但相应网格是位置的,我们可以调用函数CvSVM::get_default_grid()。如果要生成一个网格,以gamma为例,则调用函数:CvSVM::get_default_grid(CVSVM::GAMMA)。 train_auto()函数可以被用来处理分类问题 (param.svm = CvSVM::C_SVC 或 param.svm = CvSVM::NU_SVC),也可以处理回归问题 (param.svm = CvSVM::EPS_SVR 或 param.svm = CvSVM::NU_SVR)。如果有param.svm_type = CvSVM::ONE_CLASS,则不会生成最优值,且普通带有确定参数的 SVM 将被执行。
预测输入样本的返回值。
如果我们通过了一个样本,那么预测结果就会返回。如果我们想要得到几个样本的返回值,那么我们应该用矩阵results来保存预测结果。 该函数与 TBB 库并行运行。
生成一个 SVM 参数的网格。
param_id SVM 参数的 ID,必须从下列表中取值:
网格将根据该 ID 参数生成。
该函数根据 SVM 算法的指定参数而生成一个网格,该网格会传递给函数CvSVM::train_auto()。
返回当前 SVM 参数。
在使用函数CvSVM::train_auto()自动训练时,该函数被用来获取最优参数。
取得若干支持向量与特定的向量。
i:特定的支持向量的序列;
该方法用来取得一组支持向量。
返回已使用特征的数量(即变量数量);