Introduction to SupportVector Machines

支持向量机简介

Goal

在本教程中,您将学习如何:

使用 OpenCV 函数 cv::ml::SVM::train构建基于 SVM 的分类器,并使用 cv::ml::SVM::predict测试其性能。

What is a SVM?

支持向量机(A Support Vector Machine) (SVM) 是由分离超平面separatinghyperplane)正式定义的判别分类器discriminative classifier)。换句话说,给定标记的训练数据supervised learning监督学习),该算法输出一个对新示例进行分类的(optimal hyperplane)最佳超平面

超平面在什么意义上是最优的?让我们考虑以下简单的问题:

对于属于两个类别之一的一组线性可分(a linearly separable set)的 2D 点,找到一条分离直线。

笔记

在这个例子中,我们处理笛卡尔平面中的线和点,而不是高维空间中的超平面和向量。这是对问题的简化。重要的是要理解这样做只是因为我们的直觉更好地建立在易于想象的示例中。但是,相同的概念适用于要分类的示例位于维度大于 2 的空间中的任务。

In this example we deal with lines andpoints in the Cartesian planeinstead of hyperplanes and vectors ina high dimensional space. This is asimplification of the problem.It is important to understand that this is doneonly because our intuition is betterbuilt from examples that are easy to imagine. However, the same concepts applyto tasks where the examples to classify liein a space whose dimension is higher than two.

在上图中,您可以看到存在多条直线可以解决问题。他们中的任何一条直线都比其他的更好吗?我们可以直观地定义一个标准来估计线条的价值(the worth of the lines):如果线条太靠近点,则它是坏的,因为它会对噪声敏感并且无法正确概括。因此,我们的目标应该是找到尽可能远离所有点的线

然后,SVM算法的操作基于找到给训练样例提供最大最小距离的超平面。两次,这个距离在 SVM 理论中得到了重要的边际名称。因此,最优分离超平面(optimalseparating hyperplane)最大化了训练数据的边距

How is the optimalhyperplane computed?

让我们介绍用于正式定义超平面的符号:

其中β称为权重向量(the weight vector),β0称为偏差(bias)。

笔记

您可以在本书的第 4.5 节(分离超平面)中找到对此和超平面的更深入描述:T. Hastie、R. Tibshirani 和 J. H. Friedman 的Elementsof Statistical Learning  [250])。

最优超平面可以通过缩放 β 和 β0 以无数种不同的方式表示。按照惯例,在超平面的所有可能表示中,选择的是

其中 x 表示最接近超平面的训练示例。通常,最接近超平面的训练样本称为支持向量。这种表示被称为规范超平面

where x symbolizes the training examples closestto the hyperplane. In general, the training examples that are closest to thehyperplane are called support vectors. Thisrepresentation is known as the canonical hyperplane.

现在,我们使用几何结果给出点 x超平面 (β,β0) 之间的距离

特别是,对于规范超平面分子等于 1,到支持向量的距离为

回想一下上一节中介绍的边距这里表示为 M,是到最近示例的距离两倍

最后,最大化 M的问题等价于最小化受某些约束的函数 L(β)的问题。约束对超平面正确分类所有训练示例xi的要求进行建模。正式地,

其中 yi 表示训练示例的每个标签。

这是一个拉格朗日优化问题,可以使用拉格朗日乘数求解,得到最优超平面的权重向量β偏置β0

Source Code

https://github.com/opencv/opencv/tree/4.x/samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>using namespace cv;
using namespace cv::ml;int main(int, char**)
{//设置训练数据//! [setup1]int labels[4] = {1, -1, -1, -1};float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };//! [setup1]//! [setup2]Mat trainingDataMat(4, 2, CV_32F, trainingData);//训练数据按行排列Mat labelsMat(4, 1, CV_32SC1, labels);//标签(4个样本)4行1列//! [setup2]//训练SVM//! [init]Ptr<SVM> svm = SVM::create();svm->setType(SVM::C_SVC);svm->setKernel(SVM::LINEAR);svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));//! [init]//! [train]svm->train(trainingDataMat, ROW_SAMPLE, labelsMat);//! [train]// 可视化数据int width = 512, height = 512;Mat image = Mat::zeros(height, width, CV_8UC3);//初始化为黑色背景图512x512// 显示 SVM 给出的决策区域 Show the decision regions given by the SVM//! [show]Vec3b green(0,255,0), blue(255,0,0);for (int i = 0; i < image.rows; i++)//图像的行 对应y坐标{for (int j = 0; j < image.cols; j++)//图像的列 对应x坐标{Mat sampleMat = (Mat_<float>(1,2) << j,i);//像素坐标float response = svm->predict(sampleMat);//预测像素坐标 j,i 的响应if (response == 1)  //正样本  1  绿色image.at<Vec3b>(i,j)  = green;else if (response == -1) //负样本 -1 蓝色image.at<Vec3b>(i,j)  = blue;}}//! [show]// 显示训练使用的数据//! [show_data]int thickness = -1;//填充圆圈circle( image, Point(501,  10), 5, Scalar(  0,   0,   0), thickness );//黑色圆圈 1circle( image, Point(255,  10), 5, Scalar(255, 255, 255), thickness );//白色圆圈 -1circle( image, Point(501, 255), 5, Scalar(255, 255, 255), thickness );//白色圆圈 -1circle( image, Point( 10, 501), 5, Scalar(255, 255, 255), thickness );//白色圆圈 -1//! [show_data]// 显示支持向量 Show support vectors//! [show_vectors]thickness = 2;Mat sv = svm->getUncompressedSupportVectors();for (int i = 0; i < sv.rows; i++)//遍历所有支持向量{const float* v = sv.ptr<float>(i);//支持向量 的x坐标指针circle(image,  Point( (int) v[0], (int) v[1]), 6, Scalar(128, 128, 128), thickness);//灰色圆}//! [show_vectors]imwrite("result.png", image);        // 保存图像imshow("SVM Simple Example", image); // 显示waitKey();return 0;
}

Explanation

  • 设置训练数据

本练习的训练数据一组标记的 2D 点组成,这些点属于两个不同类别之一;其中一类由一个点组成,另一个由三个点组成。

int labels[4]= {1, -1, -1, -1}; //标签:正、负float trainingData[4][2]= { {501, 10}, {255, 10}, {501, 255}, {10, 501} };//样本数据

之后将使用的函数 cv::ml::SVM::train要求将训练数据存储为浮点数的 cv::Mat 对象。因此,我们从上面定义的数组中创建这些对象:

Mat trainingDataMat(4, 2, CV_32F, trainingData);
Mat labelsMat(4, 1, CV_32SC1, labels);
  • 设置 SVM 的参数

在本教程中,我们在最简单的情况下介绍了 SVM 的理论,即训练样本被分成两个线性可分的类。然而,SVM 可以用于各种各样的问题(例如,非线性可分数据的问题、使用核函数来提高示例维度的 SVM 等)。因此,我们必须在训练 SVM 之前定义一些参数。这些参数存储在cv::ml::SVM 类的对象中。

Ptr<SVM> svm= SVM::create();
svm->setType(SVM::C_SVC);
svm->setKernel(SVM::LINEAR);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));

这里:

  • Type of SVM支持向量机的类型。我们在这里选择可用于 n 类分类( n-classclassification)(n ≥ 2)的类型C_SVC。这种类型的重要特征是它处理类的不完美分离(即当训练数据是非线性可分离的)。这个特性在这里并不重要,因为数据是线性可分的,我们选择这种 SVM 类型只是因为它是最常用的

  • Type of SVM kernel. SVM 内核的类型。我们没有讨论核函数,因为它们对我们正在处理的训练数据不感兴趣。不过,现在让我们简要解释一下核函数背后的主要思想。它是对训练数据进行的映射,以提高其与线性可分数据集的相似性。这种映射包括增加数据的维数,并使用核函数有效地完成。我们在这里选择类型LINEAR,这意味着不进行任何映射。此参数使用 cv::ml::SVM::setKernel定义。

  • Termination criteria of the algorithm. 算法的终止标准。SVM 训练过程以迭代方式求解受约束的二次优化问题。在这里,我们指定了最大迭代次数容差误差,因此即使尚未计算出最佳超平面,我们也允许算法以更少的步数完成。 此参数在结构cv::TermCriteria 中定义。Here we specify a maximum number ofiterations and a tolerance error so we allow the algorithm to finish in lessnumber of steps even if the optimal hyperplane has not been computed yet.

  • Train the SVM 训练 SVM 我们调用方法cv::ml::SVM::train来构建 SVM 模型(build the SVM model)。

svm->train(trainingDataMat, ROW_SAMPLE, labelsMat);
  • SVM 分类的区域Regionsclassified by the SVM

方法 cv::ml::SVM::predict用于使用经过训练的 SVM对输入样本进行分类。在此示例中,我们使用此方法根据 SVM 所做的预测为空间着色。换句话说,遍历图像,将其像素解释为笛卡尔平面上的点。每个点的颜色取决于 SVM 预测的类别; 如果是标签为 1 的类,则为绿色;如果是标签为 -1 的类,则为蓝色。

Vec3b green(0,255,0), blue(255,0,0);for (int i = 0; i < image.rows; i++){for (int j = 0; j < image.cols; j++){Mat sampleMat = (Mat_<float>(1,2) << j,i); //像素坐标赋值给1行2列的Matfloat response = svm->predict(sampleMat);if (response == 1)image.at<Vec3b>(i,j)  = green;else if (response == -1)image.at<Vec3b>(i,j)  = blue;}}
  • 支持向量Support vectors

我们在这里使用了几种方法来获取有关支持向量的信息。方法 cv::ml::SVM::getSupportVectors 获取所有支持向量。我们在这里使用这种方法来查找作为支持向量的训练示例并突出显示它们。

thickness = 2;Mat sv = svm->getUncompressedSupportVectors();for (int i = 0; i < sv.rows;i++)//遍历支持向量{const float* v = sv.ptr<float>(i);//第i+1个支持向量的x坐标指针circle(image,  Point((int) v[0],(int) v[1]), 6, Scalar(128, 128, 128), thickness);}

Results

该代码会打开一个图像并显示两个类的训练示例。一类的点用白色圆圈表示,黑色的点用于另一类。

SVM 被训练并用于对图像的所有像素进行分类。这导致图像在蓝色区域绿色区域中的划分。两个区域之间的边界是最优分离超平面

最后,支持向量训练示例周围使用灰色环显示。

参考:

https://docs.opencv.org/4.5.5/d1/d73/tutorial_introduction_to_svm.html

【opencv-ml】支持向量机简介相关推荐

  1. Python,OpenCV基于支持向量机SVM的手写数字OCR

    Python,OpenCV基于支持向量机SVM的手写数字OCR 1. 效果图 2. SVM及原理 2. 源码 2.1 SVM的手写数字OCR 2.2 非线性SVM 参考 上一节介绍了基于KNN的手写数 ...

  2. Interview之AI:人工智能领域岗位求职面试—人工智能算法工程师知识框架及课程大纲(AI基础之数学基础/数据结构与算法/编程学习基础、ML算法简介、DL算法简介)来理解技术交互流程

    Interview之AI:人工智能领域岗位求职面试-人工智能算法工程师知识框架及课程大纲(AI基础之数学基础/数据结构与算法/编程学习基础.ML算法简介.DL算法简介)来理解技术交互流程 目录 一.A ...

  3. OpenCV SVM支持向量机和KNearest数字识别的实例(附完整代码)

    OpenCV SVM支持向量机和KNearest数字识别的实例 OpenCV SVM支持向量机和KNearest数字识别的实例 OpenCV SVM支持向量机和KNearest数字识别的实例 #inc ...

  4. OpenCV Java开发简介

    OpenCV Java开发简介 OpenCV Java开发简介 我们将在本指南中做什么 获得适当的OpenCV 下载 构建 Java示例与Ant Java和Scala的SBT项目 运行SBT样本 Op ...

  5. 机器学习和ML.NET简介-第1部分

    介绍 如今,机器学习正变得越来越流行,并且已在广泛的行业以及我们的日常生活中使用.在本文中,我们将学习如何使用Microsoft ML.NET(机器学习.NET)开发机器学习应用程序.如果我们具有机器 ...

  6. opencv机器学习ml模块简介

    本文不涉原理,只介绍如何使用! ml模块为opencv的机器学习(machine learning,ml)代码库,包含各种机器学习算法: 0, class CvStatModel ; class Cv ...

  7. SVM 支持向量机简介和sklearn中参数设置详解

    1.SVM简介 SVM方法建立在统计学VC维和结构风险最小化原则上,既可以用于分类(二/多分类).也可用于回归和异常值检测.SVM具有良好的鲁棒性,对未知数据拥有很强的泛化能力,特别是在数据量较少的情 ...

  8. 在 Google Colab 中使用 OpenCV 进行图像处理简介

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 在这篇文章中,我们将实现如何使用 OpenCV 在 google ...

  9. OpenCV的支持向量机SVM的程序

    步骤: 1,生成随机的点,并按一定的空间分布将其归类 2,创建SVM并利用随机点样本进行训练 3,将整个空间按SVM分类结果进行划分,并显示支持向量 [cpp] view plaincopy #inc ...

  10. OpenCV主成分分析(PCA)简介

    OpenCV主成分分析PCA 主成分分析(PCA) 目标 什么是PCA? 特征向量和特征值如何计算? 整理数据集 计算经验均值 计算与平均值的偏差 找到协方差矩阵 查找协方差矩阵的特征向量和特征值 源 ...

最新文章

  1. 支持国内版Office 365的PowerShell模块现已发布
  2. java list 最小值_Java 实例 – 查找 List 中的最大最小值
  3. Oracle PL/SQL编程之基础
  4. 《Netkiller Spring Cloud 手札》之 Master / Slave 主从数据库数据源配置
  5. Hadoop专业解决方案-第1章 大数据和Hadoop生态圈
  6. 教资计算机科学与技术教资,教资笔试查成绩啦!广师大未来教师们又前进一步...
  7. java爬取网页并保存_第九讲:Python爬取网页图片并保存到本地
  8. 【转载】DNN6开源CMS
  9. 【Keras】Win10系统 + Anaconda+TensorFlow+Keras 环境搭建教程
  10. linux整行剪切_云计算人员如何提高效率 要掌握哪些Linux命令
  11. 初中生学计算机应用有什么好方面,计算机有哪些专业 初中毕业学习相关专业有发展吗...
  12. python 穷举法 算24点(史上最简短代码)
  13. nginx系列第一篇:nginx源码下载,编译和安装
  14. 概率论与数理统计(一):教你一步步推贝叶斯公式
  15. 关于初级安全工程师的培训思路或大纲整理
  16. php kingeditor 相对路径,kindeditor上传图片生成绝对地址
  17. 窄带包络解调python实现_对数据包络分析法DEA的再理解,以及python 实现
  18. 在java中gc是啥_java中,什么是GC?GC的基本原理。
  19. ZF和MMSE准则线性预编码的比较
  20. springboot项目制作漂亮的banner

热门文章

  1. NLP:不要重新造轮子
  2. Word目录怎么自动生成?Word文档怎么自动生成目录列表
  3. word流程图怎么使箭头对齐_在Word中画流程图时箭头怎么对齐到框的中间啊?
  4. mysql中数据字典的定义,数据字典
  5. 如何0代码快速搭建教育平台,实现线上直播教学【内附源码/Demo】
  6. mysql中的分隔符有哪些_MySQL中的分隔符
  7. 简单好用的洗鼻子方法?
  8. vue 按钮控制鼠标滚轮放大缩小
  9. SAR图像超分辨技术
  10. 实现平方根函数sqrt