函数 CvSVM::train 要求训练数据储存于float类型的 Mat 结构中,因此我们定义了以下矩阵: Mat trainingDataMat(3, 2, CV_32FC1, trainingData); Mat labelsMat (3, 1, CV_32FC1, labels); 2. 设置SVM参数
此教程中,我们以可线性分割的分属两类的训练样本简单讲解了SVM的基本原理。然而,SVM的实际应用情形可能复杂得多 (比如非线性分割数据问题,SVM核函数的选择问题等等)。总而言之,我们需要在训练之前对SVM做一些参数设定。这些参数保存在类 CvSVMParams 中。 CvSVMParamsparams;
params.svm_type=CvSVM::C_SVC;
params.kernel_type=CvSVM::LINEAR;
params.term_crit=cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
o
SVM类型. 这里我们选择了 CvSVM::C_SVC 类型,该类型可以用于n-类分类问题 (n 2)。这个参数定义在 CvSVMParams.svm_type 属性中. Note
CvSVM::C_SVC 类型的重要特征是它可以处理非完美分类的问题 (及训练数据不可以完全的线性分割)。在本例中这一特征的意义并不大,因为我们的数据是可以线性分割的,我们这里选择它是因为它是最常被使用的SVM类型。
SVM 核类型. 我们没有讨论核函数,因为对于本例的样本,核函数的讨论没有必要。然而,有必要简单说一下核函数背后的主要思想,核函数的目的是为了将训练样本映射到更有利于可线性分割的样本集。映射的结果是增加了样本向量的维度,这一过程通过核函数完成。此处我们选择的核函数类型是CvSVM::LINEAR 表示不需要进行映射。该参数由 CvSVMParams.kernel_type 属性定义。 o 算法终止条件. SVM训练的过程就是一个通过 迭代 方式解决约束条件下的二次优化问题,这里我们指定一个最大迭代次数和容许误差,以允许算法在适当的条件下停止计算。该参数定义在 cvTermCriteria 结构中。
3. 训练支持向量机
o
调用函数 CvSVM::train 来建立SVM模型。 CvSVM SVM; SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params); 4. SVM区域分割
函数 CvSVM::predict 通过重建训练完毕的支持向量机来将输入的样本分类。本例中我们通过该函数给向量空间着色,及将图像中的每个像素当作卡迪尔平面上的一点,每一点的着色取决于SVM对该点的分类类别:绿色表示标记为1的点,蓝色表示标记为-1的点。
Vec3b green(0,255,0), blue (255,0,0);
for (int i =0; i Mat sampleMat= (Mat_ if (response ==1) image.at if (response ==-1) image.at 5. 支持向量 这里用了几个函数来获取支持向量的信息。函数 CvSVM::get_support_vector_count 输出支持向量的数量,函数 CvSVM::get_support_vector 根据输入支持向量的索引来获取指定位置的支持向量。通过这一方法我们找到训练样本的支持向量并突出显示它们。 int c =SVM.get_support_vector_count(); for (int i =0; i < c; ++i) { constfloat* v =SVM.get_support_vector(i); // get and then highlight with grayscale circle( image, Point( (int) v[0], (int) v[1]), 6, Scalar(128, 128, 128), thickness, lineType); } 结果 程序创建了一张图像,在其中显示了训练样本,其中一个类显示为白色圆圈,另一个类显示为黑色圆圈。 ? 训练得到SVM,并将图像的每一个像素分类。分类的结果将图像分为蓝绿两部分,中间线就是最优分割超平面。 ? 最后支持向量通过灰色边框加重显示。 ? 支持向量机对线性不可分数据的处理 目标 本文档尝试解答如下问题: 在训练数据线性不可分时,如何定义此情形下支持向量机的最优化问题。 ? 如何设置 CvSVMParams 中的参数来解决此类问题。 ? 动机 为什么需要将支持向量机优化问题扩展到线性不可分的情形?在多数计算机视觉运用中,我们需要的不仅仅是一个简单的SVM线性分类器,我们需要更加强大的工具来解决 训练数据无法用一个超平面分割 的情形。 我们以人脸识别来做一个例子,训练数据包含一组人脸图像和一组非人脸图像(除了人脸之外的任何物体)。这些训练数据超级复杂,以至于为每个样本找到一个合适的表达 (特征向量) 以让它们能够线性分割是非常困难的。 最优化问题的扩展 还记得我们用支持向量机来找到一个最优超平面。既然现在训练数据线性不可分,我们必须承认这个最优超平面会将一些样本划分到错误的类别中。在这种情形下的优化问题,需要将 错分类(misclassification) 当作一个变量来考虑。新的模型需要包含原来线性可分情形下的最优化条件,即最大间隔(margin), 以及在线性不可分时分类错误最小化。 我们还是从最大化 间隔 这一条件来推导我们的最优化问题的模型(这在 前一节 已经讨论了): 在这个模型中加入错分类变量有多种方法。比如,我们可以最小化一个函数,该函数定义为在原来模型的基础上再加上一个常量乘以样本被错误分类的次数: 然而,这并不是一个好的解决方案,其中一个原因是它没有考虑错分类的样本距离同类样本所属区域的大小。因此一个更好的方法是考虑 错分类样本离同类区域的距离: 这里为每一个样本定义一个新的参数 ,这个参数包含对应样本离同类区域的距离。下图显示了两类线性不可分的样本,以及一个分割超平面和错分类样本距离同类区域的距离。 Note 图中只显示了错分类样本的距离,其余样本由于已经处于同类区域内部所以距离为零。 红色和蓝色直线表示各自区域的边际间隔,每个 表示从错分类样本到同类区域边际间隔的距离。 最后我们得到最优问题的最终模型: 关于参数C的选择,明显的取决于训练样本的分布情况。尽管并不存在一个普遍的答案,但是记住下面几点规则还是有用的: C比较大时分类错误率较小,但是间隔也较小。在这种情形下,错分类对模型函数产生较大的影响,既然优化的目的是为了最小化这个模型函数,那么错分类的情形必然会受到抑制。 ? C比较小时间隔较大,但是分类错误率也较大。在这种情形下,模型函数中错分类之和这一项对优化过程的影响变小,优化过程将更加关注于寻找到一个能产生较大间隔的超平面。 ? 源码 你 可 以 从 OpenCV 源 码 库 文 件 夹 samples/cpp/tutorial_code/gpu/non_linear_svms/non_linea r_svms 下载源码和视频,或者 从此处下载. 1 2 3 4 5 6 7 8 9 10 #include #include #include #define NTRAINING_SAMPLES 100 // Number of training samples per class #define FRAC_LINEAR_SEP 0.9f // Fraction of samples which compose the linear separable part usingnamespace cv; usingnamespacestd; int main() { // Data for visual representation constint WIDTH =512, HEIGHT =512; Mat I = Mat::zeros(HEIGHT, WIDTH, CV_8UC3); //--------------------- 1. Set up training data randomly 百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库支持向量机的介绍(2)在线全文阅读。
相关推荐: