精华内容
参与话题
问答
  • 支持向量机SVM、支持向量回归SVR详细推导

    万次阅读 多人点赞 2019-06-30 09:31:52
    文章详细介绍了支持向量机SVM及其拓展,支持向量回归SVR.并从线性分类和非线性分类的角度出发,详细推导了硬间隔、软间隔和核函数的支持向量机。

    目录


    一、SVM简介

    简介:SVM的英文全称是Support Vector Machines,中文叫支持向量机。支持向量机是我们用于分类的一种算法。支持向量也可以用于回归,此时叫支持向量回归(Support Vector Regression,简称SVR)。

    发展历史:1963年,ATE-T Bell实验室研究小组在Vanpik的领导下,首次提出了支持向量机(SVM)理论方法。但在当时,SVM在数学上不能明晰地表示,人们对模式识别问题的研究很不完善,因此SVM的研究没有得到进一步的发展与重视。 1971年,Kimeldorf提出了使用线性不等约束重新构造SV的核空间,使一部分线性不可分的问题得到了解决。20世纪90年代,一个比较完善的理论体系——统计学习理论(Statistical Learning Theory,SLT)形成了,此时一些新兴的机器学习方法(如神经网络等)的研究遇到了一些重大的困难,比如欠学习与过学习问题、如何确定网络结构的问题、局部极小点问题等,这两方面的因素使得SVM迅速发展和完善,并在很多问题的解决中表现出许多特有优势,而且能够推广应用到函数拟合等其他机器学习问题中,从此迅速发展了起来,目前已经成功地在许多领域里得到了成功应用。

    思想:SVM的主要思想可以概括为如下两点:
    (1)它是针对线性可分的情况进行分析的。对于线性不可分的情况,通过使用非线性映射算法将低维输入空间线性不可分的样本转化为高维特征空间,使其线性可分,从而使得在高维特征空间中采用线性算法对样本的非线性特征进行线性分析成为可能。
    (2)它基于结构风险最小化理论,在特征空间中构建最优分类面,使得学习器能够得到全局最优化,并且使整个样本空间的期望风险以某个概率满足一定上界。
      从上面的两点基本思想来看,SVM没有使用传统的推导过程,简化了通常的分类和回归等问题;少数的支持向量确定了SVM 的最终决策函数,计算的复杂性取决于支持向量,而不是整个样本空间,这就可以避免“维数灾难”。少数支持向量决定了最终结果,这不但可以帮助我们抓住关键样本,而且注定了该方法不但算法简单,而且具有较好的“鲁棒”性。

    数学基础:拉格朗日乘子法、对偶问题、KKT条件

    应用:人脸检测、验证和识别,说话人/语音识别,文字/手写体识别 ,图像处理等等

    二、推导过程

    SVM有三宝:间隔、对偶、核技巧。
    遇到的问题大致可以分为线性可分和线性不可分的情况,因此,我将分开介绍:

    1.线性可分

    1.1 硬间隔

    1. 基本模型

    训练样本集D={(x1,y1),(x1,y1),(xm,ym)},yi=1yi=1D=\{(x_{1},y_{1}),(x_{1},y_{1}),……,(x_{m},y_{m})\},y_{i}=1或y_{i}=-1,分类学习的思想:找一个划分超平面,将不同类别的样本分开。

    在这里插入图片描述
    划分的超平面很多,我们去找哪一个?直观上看,我们应该找位于两类训练样本“正中间”的超平面。

    在样本空间中,划分超平面可通过如下线性方程来描述:wTx+b=0{\color{Red} w^{T}x+b=0}
    w=(w1;w2;;wd)w=(w_{1};w_{2};…;w_{d})为法向量,决定了超平面的方向;b为位移项,决定了超平面与原点之间的距离。
    显然,划分超平面可被法向量w和位移b确定,下面我们将其记为(w,b)。 样本空间中任意点x到超平面(w,b)的距离可写为r=wTx+bw{\color{Red} r=\frac{\left | w^{T}x+b \right |}{\left \| w \right \|}}
    假设超平面(w,b)能将训练样本正确分类,即对(xi,yi)D(x_{i},y_{i} )\in D,若yi=+1y_{i}=+1,则wTxi+b>0w^{T}x_{i}+b>0.否则:wTxi+b<0w^{T}x_{i}+b<0,令
    在这里插入图片描述
    对应如下:
    在这里插入图片描述
    问题只与投影方向有关,一旦方向定了,通过缩放w和b,总能使上式成立。所以,求超平面的问题转化为求w和b的问题。

    如下图所示,距离超平面最近的这几个训练样本点使上式的等号成立,它们被称为“支持向量”(support vector),两个异类支持向量机到超平面的距离之和为 :r=wTx+bw{\color{Red} r=\frac{\left | w^{T}x+b \right |}{\left \| w \right \|}}
    在这里插入图片描述
    上图中,两条虚线之间的距离为:γ=2w\gamma =\frac{2}{\left \| w \right \|},将其称之为间隔。欲找到具有“最大间隔”(maximum margin)的划分超平面,也就是找到参数w和b,使得γ最大,即:
    在这里插入图片描述
    上面的约束等价于如下约束:
    在这里插入图片描述
    即支持向量机(Support Vector Machine,简称SVM)的基本型。

    2. 模型求解

    上式中,其中w和b是模型参数。注意到上式本身是一个凸二次规划问题,能直接用现成的优化计算包求解,但我们可以有更高效的办法,可以求出闭式解。
    对式使用拉格朗日乘子法可得到其“对偶问题”(dual problem):
    在这里插入图片描述
    其中α=(α1;α2;;αm)\alpha =(\alpha _{1};\alpha _{2};…;\alpha _{m}),令L(w,b,α)L(w,b,\alpha)对w和b的偏导数等于零得:
    在这里插入图片描述
    将第一个式代入L,即可将L(w,b,α)L(w,b,α)中的w和b消去,再考虑第二个式的约束,就得到对偶问题:
    在这里插入图片描述
    解出α后,求出w和b即可得到模型:
    在这里插入图片描述
    从对偶问题解出的αiα_i是拉格朗日乘子,它恰对应着训练样本(xi,yi)(x_i,y_i)。注意到支持向量机最优化问题中有不等式约束,因此上述过程需满足KKT条件,即要求:
    在这里插入图片描述
    最后一个条件,对任意训练样本(xi,yi)(x_i,y_i),总有αi=0\alpha _{i}=0yif(xi)=1y_{i}f(x_{i})=1.
    则有以下两种情况:
    (1) 若αi=0α_i=0,则该样本将不会在求和中出现,不会对f(x)有任何影响;
    (2) 若αi>0α_i>0,则必有yif(xi)=1y_i f(x_i )=1,位于最大间隔边界上,是一个支持向量。
    在这里插入图片描述
    这显示出支持向量机的一个重要性质:训练完成后,大部分的训练样本都不需保留,最终模型仅与支持向量有关.

    如何求解αiα_i:二次规划问题,通过SMO算法求解。
    基本思路:每次选择两个变量α_i和α_j,并固定其他参数。这样,在参数初始化后,SMO不断执行如下两个步骤直至收敛:
    (1) 选取一对需更新的变量αiα_iαjα_j
    (2) 固定αiα_iαjα_j以外的参数,求解式获得更新后的αiα_iαjα_j.

    分析:KKT条件违背的程度越大,则变量更新后可能导致的且标函数值减幅越大。
    第一个变量:SMO先选取违背KKT条件程度最大的变量。
    第二个变量:应选择一个使且标函数值减小最快的变量,使选取的两变量所对应样本之间的间隔最大。

    为什么更新两个,而非一个?原因是,若仅选择一个,则其可有其他变量导出。因此更新两个。
    在这里插入图片描述
    SMO算法之所以高效,是由于在固定其他参数后,仅优化两个参数的过程能做到非常高效
    之前的优化问题:
    在这里插入图片描述
    仅考虑αiα_iαjα_j时,式中的约束可重写为:
    在这里插入图片描述
    其中c是使i=0mαiyi=0∑_{i=0}^mα_i y_i=0成立的常数。用αiyi+αjyj=cα_i y_i+α_j y_j=c消去上式中的变量αjα_j,则得到一个关于αiα_i的单变量二次规划问题,仅有的约束是αi0α_i≥0
    不难发现,这样的二次规划问题具有闭式解,于是不必调用数值优化算法即可高效地计算出更新后的αiα_iαjα_j.

    确定偏移项b
    対任意支持向量(xi,yk)(x_i,y_k) 都有ysf(xs)=1y_s f(x_s )=1,即
    在这里插入图片描述
    其中S={iαi>0,i=1,2,,m}S=\{i|α_{i}>0,i=1,2,…,m\} 为所有支持向量的下标集,但现实任务中常采用一种更鲁棒的做法:使用所有支持向量求解的平均值
    在这里插入图片描述

    1.2 软间隔

    在现实任务中往往很难确定合适的核函数使得训练样本在特征空间中线性可分。
    缓解该问题的一个办法是允许支持向量机在一-些样本上出错.为此,要引入“软间隔”的概念,如图所示:
    在这里插入图片描述
    在最大化间隔的同时,不满足约束的样本应尽可能少.于是,优化目标可写为:
    在这里插入图片描述
    即,在间隔上加一个损失,允许错分,但是损失应该尽量小。

    (1)0/1损失函数
    在这里插入图片描述
    显然,当C为无穷大时,迫使所有样本均满足约束,于是等价于经典支持向量机方法;
    当C取有限值时,允许一些样本不满足约束。
    然而,l0/1l_{0/1}非凸、非连续,不易直接求解。人们通常用其他一些函数来代替l0/1l_{0/1},称为“替代损失”(surrogate loss),通常是凸的连续函数且是l0/1l_{0/1}的上界。

    (2)hinge损失函数
    若采用hinge损失,则代价函数变成:
    在这里插入图片描述
    引入“松弛变量”(slack variables)ξi0ξ_i≥0,可将重写为:
    在这里插入图片描述
    这就是常用的“软间隔支持向量机”。
    (3)其他损失函数

    在这里插入图片描述
    损失函数:
    在这里插入图片描述
    标准:>0时,尽可能小,<0时,尽可能大。从而保证分类的准确性。

    2.线性不可分(核函数)

    我们假设训练样本是线性可分的,超平面能将训练样本正确分类。然而在现实任务中,原始样本空间内也许并不存在一个能正确划分两类样本的超平面。例如图中的“异或”问题就不是线性可分的.
    在这里插入图片描述
    对这样的问题,可将样本从原始空间映射到一个更高维的特征空间,使得样本在这个特征空间内线性可分。

    例如在图中,若将原始的二维空间映射到一个合适的三维空间,就能找到一个合适的划分超平面。
    在这里插入图片描述
    如何映射?有没有通用的办法?

    幸运的是,如果原始空间是有限维,即属性数有限,那么一定存在一个高维特征空间使样本可分。 令∅(x)表示将x映射后的特征向量,于是,在特征空间中划分超平面所对应的模型可表示为:
    在这里插入图片描述
    其中w和b是模型参数。
    问题转化为:
    在这里插入图片描述
    其对偶问题是:
    在这里插入图片描述
    求解式涉及到计算ϕ(xi)Tϕ(xj)ϕ(x_i )^T ϕ(x_j ),这是样本xix_ixjx_j映射到特征空间之后的内积。
    由于特征空间维数可能很高,甚至可能是无穷维,因此直接计算ϕ(xi)Tϕ(xj)ϕ(x_i )^T ϕ(x_j )通常是困难的。
    为了避开这个障碍,可以设想这样一个函数:
    在这里插入图片描述
    xix_ixjx_j在特征空间的内积等于它们在原始样本空间中通过函数κ(∙,∙ )计算的结果。

    有了这样的函数,我们就不必直接去计算高维甚至无穷维特征空间中的内积。

    于是式可重写为:
    在这里插入图片描述
    于是,求解后即可得到:
    在这里插入图片描述
    这里的函数κ(∙,∙ )就是“核函数”(kernel function)。上式显示出模型最优解可通过训练样本的核函数展开,这一展式亦称“支持向量展式”(support vector expansion)。

    问题:显然,若已知合适映射ϕ(∙)的具体形式,则可写出核函数κ(∙,∙ ),但在现实任务中我们通常不知道ϕ(∙)是什么形式。

    合适的核函数是否一定存在呢?什么样的函数能做核函数呢?
    答案是肯定的。

    定理(核函数) 令χ为输入空间,κ(∙,∙ )是定义在χ×χχ×χ上的对称函数,则κ是核函数当且仅当对于任意数据D={x1,x2,,xm}D=\{x_{1},x_{2},…,x_{m}\},“核矩阵”(kernel matrix)K总是半正定的:
    在这里插入图片描述
    定理表明,只要一个对称函数所对应的核矩阵半正定,它就能作为核函数使用。

    在不知道特征映射的形式时,我们并不知道什么样的核函数是合适的,“核函数选择”成为支持向量机的最大变数。

    通常,可选择如下核函数,选择性能最优者作为某一问题的核函数:
    在这里插入图片描述
    注意:当d=1时,高斯核也成为径向基核函数(RBF)核。

    此外,还可通过函数组合得到,例如:
    (1) 若κ_1和κ_2为核函数,则对于任意正数γ1γ2γ_1、γ_2,其线性组合也是核函数:
    γ1κ1+γ2κ2γ_1 κ_1+γ_2 κ_2

    (2) 若κ_1和κ_2为核函数,则核函数的直积也是核函数;
    κ1κ2(x,z)=κ1(x,z)κ2(x,z)κ_1 ⊗κ_2 (x,z)=κ_1 ( x,z)κ_2 (x,z)

    (3) 若κ_1为核函数,则对于任意函数g(x),也是核函数;
    κ(x,z)=g(x)κ1(x,z)g(z)κ(x,z)=g(x)κ_1 (x,z)g (z)

    3.SVR支持向量回归

    给定训练样本D={(x1,y1),(x1,y1),(xm,ym)},yiRD=\{(x_{1},y_{1}),(x_{1},y_{1}),……,(x_{m},y_{m})\},y_{i}∈R,希望学得一个回归模型,使得f(x)f(x)yy尽可能接近,wwbb是待确定的模型参数。
    在这里插入图片描述
    假设我们能容忍f(x)f(x)yy之间最多有ϵϵ的偏差,即仅当f(x)f(x)yy之间的差别绝对值大于ϵϵ时才计算损失.

    于是,SVR问题可形式化为:
    在这里插入图片描述
    其中C为正则化常数,lϵl_ϵ是图中所示的ϵ -不敏感损失(ϵ -insensitive loss)函数:
    在这里插入图片描述
    引入松弛变量ξiξ_i(ξi)(ξ_i ),可将式重写为:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190630091142826.png
    在这里插入图片描述
    引入拉格朗日乘子μiμ_i
    在这里插入图片描述
    再令L(w,b,α,α^,ξ,ξ^,μ,μ^)L(w,b,\alpha ,\hat{\alpha },\xi ,\hat{\xi },\mu ,\hat{\mu })wwbbξiξ_iξi^\hat{ξ_i } 的偏导为零可得:
    在这里插入图片描述
    上述过程中需满足KKT条件,即要求:
    在这里插入图片描述
    SVR的解形如
    在这里插入图片描述
    能使式中的(αi^αi)0(\hat{\alpha_i}-α_i )\neq 0的样本即为SVR的支持向量,它付必落在ϵ-同隔带之外.显然, SVR的支持向量仅是训练样本的一部分,即其解仍具有稀疏性.

    0&lt;αi&lt;C0&lt;α_i&lt;C,则必有ξi=0ξ_i=0
    在这里插入图片描述
    实践中常采用一中更鲁棒的办法:迭取多个满足条件0&lt;αi&lt;C0&lt;α_i&lt;C的样本求解b后取平均値。

    若考虑特征映射形式,则:
    在这里插入图片描述
    则SVR可表示为:
    在这里插入图片描述
    其中K(xiTx)=(xi)T(xj)K(x_i^T x)=∅(x_i )^T∅(x_j )为核函数。

    展开全文
  • 基于支持向量机的图像分类(下篇:MATLAB实现)

    万次阅读 多人点赞 2018-04-11 00:19:20
    摘要:本文通过图文详细介绍如何利用支持向量机对图像进行分类,经过上篇文章对原理的介绍,这里介绍利用MATLAB编程实现。后续章节将介绍的主要部分有: 图片数据集整理 特征提取 SVM训练与测试 分类结果...

    摘要:本文通过图文详细介绍如何利用支持向量机对图像进行分类,经过上篇文章对原理的介绍,这里介绍利用MATLAB编程实现。后续章节将介绍的主要部分有:

    • 图片数据集整理
    • 特征提取
    • SVM训练与测试
    • 分类结果评价
    • 结果显示

    点我下载:SVM图像分类的MATLAB完整程序及图片集文件


    1. 前言

    机器学习是人工智能研究发展到一定阶段的必然产物。二十世纪八十年代是机器学习成为一个独立学科的学科领域、各种机器学习技术百花绽放的时期。支持向量机于1995年正式发表[Cortes and Vapnik,1995],由于在文本分类任务中的卓越性能[Joachims,1998],很快成为机器学习的主流技术,并直接掀起了“统计学习”(statistical learning)在2000年前后的高潮。——《机器学习》 周志华

    2010年前后,随着计算能力的迅猛提升和大数据的涌现,神经网络研究在“深度学习”的名义下又重新崛起,并迎来又一次发展高潮。近年研究SVM的论文少了很多,SVM的风头很多时候确实已被强势崛起的深度学习浪潮所淹没,95年的SVM比我们年龄还大,有点仿佛英雄迟暮的感觉。不过在我看来,实现简单而且非常强大的分类算法SVM仍然有其研究价值,与神经网络相比SVM亦有过人之处,如特征维数多于样本数的情况,而小样本学习至今仍是深度学习的一大难题。

    当浅层神经网络效果不佳时,人们将目光转向支持向量机,而支持向量机亦不负众望,以不错的成绩让人们对机器学习重拾信心。感谢支持向量机,感谢在神经网络几经起落的时候,支持向量机继往开来、自成一脉,填补了机器学习的一段空窗期,让这条曲折向上的研究之路绵延至今迎来了现在人工智能百花齐放的时代!

    接下来就通过简单的图片分类问题,通过MATLAB程序理解认识一下这一简单而强大的分类算法——支持向量机.


    2. 图片数据集整理

    首先需要准备好分类的数据集,数据的整理是机器学习中的重要一环。这里我们自行整理一个用于分类的图片集,图片集有四类图片,分别为车、猫、花、鱼。从百度上下载这四种图片,并分别存放在四个文件夹中,如下图所示

    70

    四类图片每类分别下载100张左右的图片,这四百张图片作为分类的数据集,以7:3的比例将其分为训练图片集和测试图片集,分别放到picturestestPictures两个文件夹中。这两个文件夹下同上图一样都有car、cat、flw、fsh四个文件夹,值得注意的是测试样本的图片应可能不出现在训练集图片库中。做好以上工作,用于分类的图片集就准备完毕了。

    (当然用于分类的图片集常用的是cafir10图片集,这个数据集是写论文或研究时普遍用到的,可能会在后面的文章中介绍其用法,这里就暂时不使用cafir了。)

    为了便于后面的特征提取等对每张图片进行的操作,这里在程序中有必要将图片文件的存储位置、数量、类别等信息整理到一个数据结构中,新建一个m文件,程序代码如下

    dir=('D:\pictures');
    testdir=('D:\testPictures\test');
    trainingSet = imageSet(dir,'recursive');
    testSet = imageSet(testdir,'recursive');
    

    以上代码中用到imageSet( )函数是一个图片集整理的函数(MATLAB R2016b及以上版本支持),返回的是dir文件路径下文件夹内的文件信息。例如得到的trainingSet为一个1*4的imageSet变量,每个imageSet变量由Description、ImageLocation、Count三个属性组成,分别代表对子文件的描述、文件存储位置和图片数量。如下图所示是testSet(1)内部情况

    70

    3. 主要步骤

    和深度学习的算法相比,传统的机器学习在进行图片分类时输入的不是原始图片而是先进行一个特征提取的步骤。在上篇中已经介绍了特征提取的相关内容,这里用的是方向梯度直方图(HOG)以及灰度共生矩阵(GLCM)。

    70

    3.1 GLCM提取

    MATLAB中灰度共生矩阵的提取可以调用graycomatrix( )函数,不过这里为了取不同方向(0、45、90、135度)的灰度共生矩阵,通过循环计算各个方向的灰度共生矩阵并进行归一化处理(计算对比度、逆差距、熵、自相关),然后取平均值和方差作为最终提取的特征。

    新建一个m文件并命名为getGLCMFeatures,输入以下代码

    function [features] = getGLCMFeatures(image)
    features_all  = [];
    for i = 1:10
        glcm = graycomatrix(image, 'Offset', [0,i]);
        stats = graycoprops(glcm);
        
        glcm45 = graycomatrix(image, 'Offset', [-i,i]);
        stats45 = graycoprops(glcm45);
        
        glcm90 = graycomatrix(image, 'Offset', [-i,0]);
        stats90 = graycoprops(glcm90);
        
        glcm135 = graycomatrix(image, 'Offset', [-i,-i]);
        stats135 = graycoprops(glcm135);
        
        stats7x4 = [stats.Contrast stats.Correlation stats.Energy stats.Homogeneity;
            stats45.Contrast stats45.Correlation stats45.Energy stats45.Homogeneity;
            stats90.Contrast stats90.Correlation stats90.Energy stats90.Homogeneity;
            stats135.Contrast stats135.Correlation stats135.Energy stats135.Homogeneity];
        features_all = [features_all mean(stats7x4,1) std(stats7x4,0,1)];
    end
    features = features_all;
    

    新建的getGLCMFeatures函数输入为彩色图像转换后的灰度图像矩阵,输出为提取后的灰度共生矩阵特征。

    3.2 合并特征

    自己编写一个提取特征的函数命名为extractFeature,这个函数输入为整理过的训练集和测试集,输出为训练集的特征、标签和测试集的特征、标签。这个函数的功能是将HOG特征和前面提取的GLCM特征合并。

    代码第2到13行是为了确定每张图片提取特征后得到的矩阵大小,以方便后面的操作同时也是为了预分配空间以提高代码效率。首先取第一张图片进行灰度化以及阈值分割,将图片大小调整在256*256的范围(统一大小)分别进行HOG和GLCM的特征提取,分别得到两种特征向量,取两个向量的长度之和就是一张图片特征提取后的总长度了。

    function [trainingFeatures,trainingLabels,testFeatures,testLabels]=extractFeature(trainingSet,testSet)
    %% 确定特征向量尺寸
    img = read(trainingSet(1), 1);
    %转化为灰度图像
    img=rgb2gray(img);
    %转化为2值图像
    lvl = graythresh(img);
    img = im2bw(img, lvl);
    img=imresize(img,[256 256]);
    cellSize = [4 4];
    [hog_feature, vis_hog] = extractHOGFeatures(img,'CellSize',cellSize);
    glcm_feature = getGLCMFeatures(img);
    SizeOfFeature = length(hog_feature)+ length(glcm_feature);
    
    %% 构建训练样本特征向量和训练样本标签
    trainingFeatures = [];
    trainingLabels   = [];
    for digit = 1:numel(trainingSet)       
        numImages = trainingSet(digit).Count;
        features  = zeros(numImages, SizeOfFeature, 'single');%初始化特征向量
        % 遍历每张图片
        for i = 1:numImages
            img = read(trainingSet(digit), i);% 取出第i张图片
            
            img=rgb2gray(img);                % 转化为灰度图像
            glcm_feature = getGLCMFeatures(img);  % 提取GLCM特征
           
            lvl = graythresh(img);            % 阈值化
            img = im2bw(img, lvl);            % 转化为2值图像
            img=imresize(img,[256 256]);
            % 提取HOG特征
            [hog_feature, vis_hog] = extractHOGFeatures(img,'CellSize',cellSize);
            % 合并两个特征
            features(i, :) = [hog_feature glcm_feature];
        end
        % 使用图像描述作为训练标签
        labels = repmat(trainingSet(digit).Description, numImages, 1);  
        % 逐个添加每张训练图片的特征和标签
        trainingFeatures = [trainingFeatures; features];
        trainingLabels   = [trainingLabels; labels];       
    end
    
    
    %% 提取测试图片集的特征向量
    testFeatures = [];
    testLabels   = [];
    for digit = 1:numel(testSet)
               
        numImages = testSet(digit).Count;
        %初始化特征向量
        features  = zeros(numImages, SizeOfFeature, 'single');
        
        for i = 1:numImages
            
            img = read(testSet(digit), i);
            %转化为灰度图像
            img=rgb2gray(img);
            glcm_feature = getGLCMFeatures(img);
            %转化为2值图像
            lvl = graythresh(img);
            img = im2bw(img, lvl);
            img=imresize(img,[256 256]);
            [hog_4x4, vis4x4] = extractHOGFeatures(img,'CellSize',cellSize);
            features(i, :) = [hog_4x4 glcm_feature];
        end
        
        % 使用图像描述作为训练标签
        labels = repmat(testSet(digit).Description, numImages, 1);
            
        testFeatures = [testFeatures; features];
        testLabels=[testLabels; labels];
            
    end
    end
    

    代码18-41行是构建训练样本特征向量和训练样本标签,与前面步骤相似,只不过现在是遍历训练集每一张图片,对其进行灰度化、阈值化、调整大小,然后进行特征提取,将HOG特征和GLCM特征合并成一个向量作为特征矩阵的一行即一张图片的特征向量。样本的标签构建则将每张图片所处的文件夹的名字作为该图片的标签,并与特征向量顺序相对应。

    第47-73行是构建测试样本特征向量和训练样本标签,这里将图片集换成了测试集,而步骤与训练集是一致的。

    3.3 SVM训练与测试

    调用前面的特征提取函数得到训练和测试用的特征向量与对应的标签,便可以进行SVM的训练和测试。MATLAB自带的训练svm函数可以用fitcecoc函数,测试可以用predict函数预测结果,训练和测试的代码如下

    % 训练一个svm分类器
    % fitcecoc 使用11的方案
    classifier = fitcecoc(trainingFeatures, trainingLabels);
    save classifier.mat classifier;
    
    % 使用测试图像的特征向量预测样本标签
    predictedLabels = predict(classifier, testFeatures);
    

    代码中classifier为训练得到的SVM分类器,利用该分类器以及测试集特征向量预测测试集的标签predictLabels。后面可以将predictLabels与实际的测试标签进行对比即可评估分类好坏。

    3.4 分类结果评价

    在上一篇文章中提到过了,为了评价分类的好坏可以通过混淆矩阵,通过计算混淆矩阵对角线上的值占每行总数的比值得出分类正确率,其实现代码如下

    %% 评估分类器
    % 使用没有标签的图像数据进行测试,生成一个混淆矩阵表明分类效果
    confMat=confusionmat(testLabels, predictedLabels)
    accuracy=(confMat(1,1)/sum(confMat(1,:))+confMat(2,2)/sum(confMat(2,:))+...
        confMat(3,3)/sum(confMat(3,:))+confMat(4,4)/sum(confMat(4,:)))/4
    

    其结果如下图所示

    70

    3.5 结果显示

    尽管以上代码能得到分类正确率,但我们希望更直观的看到输入一张图片后SVM分类器的分类结果,这里编写一个函数通过图形窗口显示预测结果。新建一个m文件命名为Predict,输入如下代码

    function [] = Predict(imageurl)
    load classifier.mat;
    figure;
    img = imread(imageurl);
    imshow(img);
    
    %提取图像的特征向量
    %转化为灰度图像
    img=rgb2gray(img);
    glcm_feature = getGLCMFeatures(img);
    %转化为2值图像
    lvl = graythresh(img);
    img = im2bw(img, lvl);
    
    % imshow(img);
    % figure
    img=imresize(img,[256 256]);
    [hog_4x4, ~] = extractHOGFeatures(img,'CellSize',[4 4]);
    testFeature = [hog_4x4 glcm_feature];
    
    
    % 使用测试图像的特征向量预测样本标签
    predictedLabel = predict(classifier, testFeature);
    
    str = ['分类结果:' predictedLabel];
    dim = [0.25 0.0004 0.2 0.2];
    annotation('textbox', dim, 'string', str, 'fontsize', 20, 'color', 'g','edgecolor', 'none');
    

    函数输入为图片的存储路径,调用函数则会通过图形窗口显示图片及分类结果,如在命令窗口输入如下代码

    Predict('D:\testPictures\test\car\car9.jpg');
    

    输出结果如下图

    70

    4. 完整代码

    为了方便使用这里贴出完整代码

    主函数:

    clear;
    dir=('D:\pictures');
    testdir=('D:\testPictures\test');
    trainingSet = imageSet(dir,'recursive');
    testSet = imageSet(testdir,'recursive');
    
    [trainingFeatures,trainingLabels,testFeatures,testLabels]=extractFeature(trainingSet,testSet);
    %% 
    %训练一个svm分类器
    %fitcecoc 使用11的方案
    classifier = fitcecoc(trainingFeatures, trainingLabels);
    save classifier.mat classifier;
    
    % 使用测试图像的特征向量预测样本标签
    predictedLabels = predict(classifier, testFeatures);
    
    %% 评估分类器
    %使用没有标签的图像数据进行测试,生成一个混淆矩阵表明分类效果
    confMat=confusionmat(testLabels, predictedLabels)
    accuracy=(confMat(1,1)/sum(confMat(1,:))+confMat(2,2)/sum(confMat(2,:))+...
        confMat(3,3)/sum(confMat(3,:))+confMat(4,4)/sum(confMat(4,:)))/4
    
    Predict('D:\testPictures\test\car\car9.jpg');
    

    getGLCMFeatures.m:

    function [features] = getGLCMFeatures(image)
    features_all  = [];
    for i = 1:10
        glcm = graycomatrix(image, 'Offset', [0,i]);
        stats = graycoprops(glcm);
        
        glcm45 = graycomatrix(image, 'Offset', [-i,i]);
        stats45 = graycoprops(glcm45);
        
        glcm90 = graycomatrix(image, 'Offset', [-i,0]);
        stats90 = graycoprops(glcm90);
        
        glcm135 = graycomatrix(image, 'Offset', [-i,-i]);
        stats135 = graycoprops(glcm135);
        
        stats7x4 = [stats.Contrast stats.Correlation stats.Energy stats.Homogeneity;
            stats45.Contrast stats45.Correlation stats45.Energy stats45.Homogeneity;
            stats90.Contrast stats90.Correlation stats90.Energy stats90.Homogeneity;
            stats135.Contrast stats135.Correlation stats135.Energy stats135.Homogeneity];
        features_all = [features_all mean(stats7x4,1) std(stats7x4,0,1)];
    end
    features = features_all;
    

    extractFeature.m:

    function [trainingFeatures,trainingLabels,testFeatures,testLabels]=extractFeature(trainingSet,testSet)
    %% 确定特征向量尺寸
    img = read(trainingSet(1), 1);
    %转化为灰度图像
    img=rgb2gray(img);
    %转化为2值图像
    lvl = graythresh(img);
    img = im2bw(img, lvl);
    img=imresize(img,[256 256]);
    cellSize = [4 4];
    [hog_feature, vis_hog] = extractHOGFeatures(img,'CellSize',cellSize);
    glcm_feature = getGLCMFeatures(img);
    SizeOfFeature = length(hog_feature)+ length(glcm_feature);
    
    %% 构建训练样本特征向量和训练样本标签
    trainingFeatures = [];
    trainingLabels   = [];
    for digit = 1:numel(trainingSet)       
        numImages = trainingSet(digit).Count;
        features  = zeros(numImages, SizeOfFeature, 'single');%初始化特征向量
        % 遍历每张图片
        for i = 1:numImages
            img = read(trainingSet(digit), i);% 取出第i张图片
            
            img=rgb2gray(img);                % 转化为灰度图像
            glcm_feature = getGLCMFeatures(img);  % 提取GLCM特征
           
            lvl = graythresh(img);            % 阈值化
            img = im2bw(img, lvl);            % 转化为2值图像
            img=imresize(img,[256 256]);
            % 提取HOG特征
            [hog_feature, vis_hog] = extractHOGFeatures(img,'CellSize',cellSize);
            % 合并两个特征
            features(i, :) = [hog_feature glcm_feature];
        end
        % 使用图像描述作为训练标签
        labels = repmat(trainingSet(digit).Description, numImages, 1);  
        % 逐个添加每张训练图片的特征和标签
        trainingFeatures = [trainingFeatures; features];
        trainingLabels   = [trainingLabels; labels];       
    end
    
    
    %% 提取测试图片集的特征向量
    testFeatures = [];
    testLabels   = [];
    for digit = 1:numel(testSet)
               
        numImages = testSet(digit).Count;
        %初始化特征向量
        features  = zeros(numImages, SizeOfFeature, 'single');
        
        for i = 1:numImages
            
            img = read(testSet(digit), i);
            %转化为灰度图像
            img=rgb2gray(img);
            glcm_feature = getGLCMFeatures(img);
            %转化为2值图像
            lvl = graythresh(img);
            img = im2bw(img, lvl);
            img=imresize(img,[256 256]);
            [hog_4x4, vis4x4] = extractHOGFeatures(img,'CellSize',cellSize);
            features(i, :) = [hog_4x4 glcm_feature];
        end
        
        % 使用图像描述作为训练标签
        labels = repmat(testSet(digit).Description, numImages, 1);
            
        testFeatures = [testFeatures; features];
        testLabels=[testLabels; labels];
            
    end
    end
    

    Predict.m:

    function [] = Predict(imageurl)
    load classifier.mat;
    figure;
    img = imread(imageurl);
    imshow(img);
    
    %提取图像的特征向量
    %转化为灰度图像
    img=rgb2gray(img);
    glcm_feature = getGLCMFeatures(img);
    %转化为2值图像
    lvl = graythresh(img);
    img = im2bw(img, lvl);
    
    % imshow(img);
    % figure
    img=imresize(img,[256 256]);
    [hog_4x4, ~] = extractHOGFeatures(img,'CellSize',[4 4]);
    testFeature = [hog_4x4 glcm_feature];
    
    
    % 使用测试图像的特征向量预测样本标签
    predictedLabel = predict(classifier, testFeature);
    
    str = ['分类结果:' predictedLabel];
    dim = [0.25 0.0004 0.2 0.2];
    annotation('textbox', dim, 'string', str, 'fontsize', 20, 'color', 'g','edgecolor', 'none');
    

    5. 结束语

    本博文的完整MATLAB程序文件与图片集文件已经上传,下载即可运行(注意根据实际修改程序中的图片路径哦)下载地址如下

    点我下载:SVM的图像分类MATLAB完整程序及图片集文件

    公众号获取
        本人微信公众号已创建,扫描以下二维码并关注公众号“AI技术研究与分享”,后台回复“SV20180411”即可获取全部资源文件信息。

    watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyODkyMzgz,size_16,color_FFFFFF,t_70

    由于编者能力有限,代码即使经过了多次校对,也难免会有疏漏之处。希望您能热心指出其中的错误,以便下次修改时能以一个更完美更严谨的样子,呈现在大家面前。同时如果有更好的实现方法也请您不吝赐教。

    展开全文
  • 向量

    千次阅读 2013-01-27 15:06:31
    设N维向量A(a1, a2, ... ,an)和向量B(b1,b2...,bn)。 加法 两个向量相加得到一个向量,是各个维度值对应相加,即 A+B=(a1+b1, a2+b2, ... ,an+bn)。 应用如力学上,两个不同方向的力可以组成一个合力。 点乘-数量积-...

    定义

    设N维向量A(a1, a2, ... ,an)和向量B(b1,b2...,bn)。

    加法

    两个向量相加得到一个向量,是各个维度值对应相加,即

    A+B=(a1+b1, a2+b2, ... ,an+bn)。

    应用如力学上,两个不同方向的力可以组成一个合力。

    点乘-数量积-内积

    先看一个应用,一个力对一个物体做的功,力F将物体从L1位置移到了L2位置,设产生的位移为S,则力的功为力F和在力F方向产生的位移,即W=|F|*|S|cos(θ);按照上面的意思,力F在和F垂直方向上是不做功的,虽然|F|*|S|sin(θ)不等于0,也就是一个向量不同维度的分向量点乘是0,所以我们得到以下公式:

    A*B=a1xb1+a2xb2+ ... + anxbn,并且,A*B结果是一个数值不是一个向量。

    叉乘-向量乘-外积

    力矩(力对轴的矩是力对物体产生绕某一轴转动作用的物理量),当我们去转动一个门时,如果力的水平方向和门的水平方向一样,那么我们使用多么大的力都不会使门转动,如果力的水平方向和门的水平方向有一定夹角,那么门就会绕着轴转动。我们也发现,其实力矩也是个向量,因为力和门的夹角不同会造成门逆时针转或者顺时针转,所以力矩的方向或者顺着轴向下,或者顺着轴向上。另外,如果门还没有真正的轴,那么门在力作用下转动的虚拟的轴肯定是力和门都垂直的方向上。

    如图,则力矩M=FxOP=FxOQ + FxQP=FxOQ,|M|=|F|x|OP|xsin(θ)。





    展开全文
  • Meshlab是一个强大的三维模型处理的软件,在三维点云的处理方面也十分强大,不仅仅可以用三维点云重构出三维模型,还可以计算出三维点云每个点的法向量,这在逆向工程和基于三维点云的隐式曲面重建中非常有用。...

    Meshlab是一个强大的三维模型处理的软件,在三维点云的处理方面也十分强大,不仅仅可以用三维点云重构出三维模型,还可以计算出三维点云每个点的法向量,这在逆向工程和基于三维点云的隐式曲面重建中非常有用。

       我的Meshlab的版本是3.3,可以在网上自行下载。

    1.Meshlab读取三维点云

    第一步:打开Meshlab软件

     

    第二步:点击File菜单下的ImportMesh导入txt文档,需要选择你的txt文档中XYZ坐标之间的分隔符,导入成功后会显示你的三维点云数据

     

    2.三维点云重建

    点击下图图标,弹出右侧图层侧边栏

     

    然后点击Fiter菜单下Normals,Curtavures and Oreientation下的Smooths normals on a point set计算三维点云的法向量,如下图

     

    然后设置计算点云法向量的参数,默认就好,如有需要可以自行设置,点击Apply等计算完成然后点击Close关闭对话框

     

    计算完点击法向量之后,点击Filter菜单下Remeshing Simplication and Reconstruction下的Surface Reconstruction:Ball Pivoting进行三维点云重建

     

    然后设置三维点云重建参数,默认就好,也可以自行设置,点击Apply等重建完成,点击close关闭对话框

     

    然后点击下列图标显示重建的三维模型,也可以设置光照等其他参数

     

    以下为三维重建结果

     

     

    3.法向量的导出与计算

    三维点云的法向量的导出与计算有两种方式,一种是在上一节三维重建中我们已经得到了重建后的三维模型,那么每个点都带有法向量,可以直接导出即可,还有一种就是从杂乱的三维点中计算每一个三维点的法向量

    3.1从三维模型中导出三维点云中每个点的法向量

    接着第二节的步骤,点击File菜单下Export Mesh as 

     

    然后在接下来的对话框中选择xyz格式

     

    然后在 接下来的对话框中勾选Normal就可以生成文本格式的三维点以及三维点法向量

     

    以下为文本格式的三维点坐标以及三维点法向量的结果

     

    3.2 直接从三维散乱点云中生成三维点的法向量

    然后点击Filter菜单下Normals,Curtavures and Oreientation下的Compute normals for point set计算三维点云的法向量,如下图

     

    在弹出来的对话框可以自行设置参数,先Apply然后再Close

     

    法向量的导出与3.1中的一样,可以自行参考。

     

    以下为三维点云以及点云的法向量的可视化结果,点云表示为红色的点,法向量表示为绿色的线段

    如果您觉得这篇博文有用,请访问我的个人站:http://www.stubbornhuang.com,更多博文干货等着您。

     

    展开全文
  • 矩阵特征值和特征向量求解

    千次阅读 2018-05-11 13:42:27
    下面以Matlab为例进行讲解求取矩阵特征值和特征向量求解。(Python和C/C++的相应代码在博客的最后给出)当一个计算机专业的人放下手头的工作,转而写博客时。说明他的CSDN账号积分所剩无几了。。。。。。基于Matlab...
  • 最小二乘支持向量机(LSSVM)详解

    千次阅读 2019-02-14 20:51:57
    最小二乘支持向量机(LSSVM)详解 第四十六次写博客,本人数学基础不是太好,如果有幸能得到读者指正,感激不尽,希望能借此机会向大家学习。在《》一文中曾对支持向量机(SVM)以及支持向量回归(SVR)进行了...
  • 向量范数与矩阵范数

    万次阅读 多人点赞 2016-07-18 20:35:26
    1.范数(norm)的意义要更好的理解范数,就要从函数、几何与矩阵的角度去理解。 我们都知道,函数与几何图形往往是有对应的关系,这个很好想象,特别是在三维以下的空间内,函数是几何图像的数学概括,而几何图像是...
  • 阅读文献时,经常看到各种范数,机器...1、向量的范数 向量的1-范数: ;各个元素的绝对值之和; 向量的2-范数:;每个元素的平方和再开平方根; 向量的无穷范数: p-范数:,其中正整数p≥1,并且有 例:...
  • 1.向量概念:  具有方向和大小。没有位置观念。比如下图红圈圈中的两个向量是相同的,因为他们具有相同的方向和大小。一般的2D向量可以写成如[1,3] 2. 3D中的向量 像下图中的向量可以写成[1,-3,7]...
  • 支持向量机(SVM)

    万次阅读 多人点赞 2017-07-05 13:13:01
    支持向量机(Support Vector Machine)是一种十分常见的分类器,曾经火爆十余年,分类能力强于NN,整体实力比肩LR与RF。核心思路是通过构造分割面将数据进行分离。本文主要阐述SVM的基本工作原理和简单应用。 1....
  • 中断向量 每个中断源都有对应的处理程序,这个处理程序称为中断服务程序,其入口地址称为中断向量。所有中断的中断服务程序入口地址构成一个表,称为中断向量表;也有的机器把中断服务程序入口的跳转指令构成一张表...
  • 段落向量与句子向量表达

    万次阅读 热门讨论 2017-05-20 17:08:27
    这是Tomas Mikolov的一篇关于段落向量和句子向量的论文。本文是我翻译加自我理解的结果,如需要更详细的介绍,请看英文文献。摘要许多机器翻译的算法都需要使用固定长度的词向量特征。在到达文本层面时,我我们最...
  • 已知矩阵A,在MATLAB界面输入[x,y]=eig(A),可以得到特征值以及特征向量。其中y为对角阵,每个元素为特征值;x的每一列为特征值所对应的特征向量。 需要进行特征向量标准化时,可以输入x(:,1)/norm(x(:,1))将特征...
  • 支持向量机(预测)

    万次阅读 2017-07-04 11:03:03
    在训练样本时搜索更加有效的那部分数据而不是所有数据,这种数据我们称为“支持向量”。对于支持向量的回归预测,采用不同的核函数会有不用的性能,下面不去介绍具体的算法,而是采用预测波斯顿房价一个案例来介绍三...
  • 向量是由n个实数组成的一个n行1列(n*1)或一个1行n列(1*n)的有序数组; 向量的点乘,也叫向量的内积、数量积,对两个向量执行点乘运算,就是对这两个向量对应位一一相乘之后求和的操作,点乘的结果是一个标量。 ...
  • 环境: Win10 +Anaconda(自带Python3.6) IDE: Pycharm (其Interperter使用的是Anaconda自带的Python3.6) 安装Gensim库: 在Anaconda Prompt中输入: pip install gensim 等待其显示安装完毕即可 ...
  • 数学基础 —— 向量运算(叉乘)

    万次阅读 2016-08-05 17:17:57
    向量的叉乘,求通知垂直两个向量向量,即c垂直于a,同时c垂直于b(a与c的夹角为90°,b与cc的夹角为90°) c = a×b = (a.y*b.z-b.y*a.z , b.x*a.z-a.x*b.z , a.x*b.y-b.x*a.y) 以上图为例a(1,0,0),b(0,1,0),...
  • 在三维空间中,两个向量的乘积(向量积,外积,乘积,区别于两个向量的数乘:内积,点积)表示两个向量的扭矩,而三个向量的混合积A×B·C,则表示由三个向量A,B,C所构成的平行六面体的面积。而且在混合积中A,B,C的...
  • 比如 行向量 A = [a,b,c],行向量B=[x,y,z];向量A叉乘B结果为一个垂直于A和B的向量;而向量A的转置乘以B得到是一个矩阵: ae,af,ag be,bf,bg ce,cf,cg 我之前把上面两种方法混淆了,当然现在也是不懂。懂...
  • 参考的是《游戏和图形学的3D数学入门教程》,非常不错的书,推荐阅读,老外很喜欢把一个东西解释的很详细。...向量的规范化就是把向量的摸变为1,即变成单位向量。下面公式中的 ||v|| 就是一个向量的长度,关
  • RT,我在求一个超大矩阵(10021\*10021的稀疏图的邻接矩阵)的特征值和特征向量遇到如下问题: (1)特征值和特征向量计算时间过长,虽然可以运行出来,但是需要处理大约50分钟,这里使用matlab自带的eig函数运算,...
  • 向量向量空间

    千次阅读 2017-12-29 10:08:28
    本章介绍线性代数的基本概念,主要内容包括向量向量组、向量空间等。
  • 向量范数

    万次阅读 多人点赞 2019-06-04 11:03:05
    声明: 仅个人小记 效果展示 绘制∥v⃗∥p=1\left \| \vec{v}\right \|_p = 1∥v∥p​=1的图像如下 当 p = 0 ...向量范数定义 总体定义 ∥v⃗∥p=(∣v1∣p+∣v2∣p+...+∣vn∣p)1p\left \| \vec{v}\righ...
  • (1) 向量向量积 两个向量a和b的叉积(向量积)可以被定义为: 在这里θ表示两向量之间的角夹角(0° ≤ θ ≤ 180°),它位于这两个矢量 所定义的平面上。 向量积的模(长度)可以解释成以a和b为邻边...
  • SVM支持向量机原理及核函数

    万次阅读 多人点赞 2018-04-07 20:21:18
    SVM支持向量机原理详解及核函数 核函数的选择 分割超平面: 支持向量: 间距: SVM算法的原理就是找到一个分割超平面,它能把数据正确的分类,并且间距最大!
  • 向量和行向量看待矩阵乘法

    万次阅读 多人点赞 2017-07-24 19:19:14
    前言: 主要是引入一个新的看待矩阵乘法的角度觉得这个挺重要的,故做记录列向量角度,矩阵左乘AB = C 结合上图,我们可以知道,结果矩阵C中的第 j 列完全可以表示为矩阵A中列向量的线性组合,具体怎样的线性组合...
  • 矩阵特征值和特征向量详细计算过程(转载)

    万次阅读 多人点赞 2018-09-02 09:43:47
    1.矩阵特征值和特征向量定义&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A为n阶矩阵,若数λ和n维非0列向量x满足Ax=λx,那么数λ称为A的特征值,x称为A的对应于特...
  • 向量向量求导

    千次阅读 2016-01-15 16:28:32
    上面这个的推导过程 已知 参考资料 https://en.wikipedia.org/wiki/Matrix_calculus关于参考资料链接里的不易理解的Denominator-layout notation和Numerator-layout notation: 其他
  • Numpy, 向量向量

    2015-12-04 05:53:37
    请问怎么用numpy生成一个比如10个长度的向量,每个元素分别都是10元素的向量?谢谢。

空空如也

1 2 3 4 5 ... 20
收藏数 114,165
精华内容 45,666
关键字:

向量