精华内容
下载资源
问答
  • 我们的人脸识别系统采用 Eigenface 技术得到的人脸特征向量表示人脸,然后转化为两类问题,利用支持向量机进行分类。
  • 支持向量机的人脸识别

    千次阅读 2018-10-04 15:08:55
    支持向量机(Support Vector Machine)是人工神经网络出现之前最常用的算法 **支持向量机要解决的问题:**什么样的决策边界才是最好的呢? 优化的目标:找到一条线,使得离该线最近的点,比如二分类的两种点,每个...

    支持向量机(Support Vector Machine)是人工神经网络出现之前最常用的算法
    **支持向量机要解决的问题:**什么样的决策边界才是最好的呢?
    在这里插入图片描述
    优化的目标:找到一条线,使得离该线最近的点,比如二分类的两种点,每个最近的点能够离决策边界最远。
    在这里插入图片描述
    求什么样的w和b使得之前的等式最小,意思就是说找到离直线距离最近的点,然后在让这个点到直线的距离求最大值。
    化简后:
    在这里插入图片描述
    第二步就是利用拉格朗日乘数法化简后,什么样的阿尔法使得距离最大。
    将其反转后式子如上图,转换为求最小值的问题。
    下面是一个案例,以一个简单实例来看,求解支持向量。
    在这里插入图片描述
    求解后得到的结果如上图。真正发挥作用的点就是支持向量
    在这里插入图片描述
    最终的决策边界是由阿尔法不等于0的样本点构成,就那一两个样本,如果阿尔法等于0,那么W所在的那一项的xy无论取什么值,都等于0,所以这个点就没有意义。
    也就是说,对于支持向量机的机制,分类是由少数几个样本决定的。在这里插入图片描述
    软间隔:有时候数据中有一些噪音点,如果考虑这个不好的点,数据的线就不行了。为了解决该问题,才会引入松弛因子
    在这里插入图片描述
    C是我们可以指定的一个数。
    为了让整体方程尽可能小,当C值大时,松弛因子必须小才能保证整体较小,意味着分类严格不能有错误。
    而当C值小时,松弛因子可以稍微大一点,意味着可以有更大的错误容忍。
    支持向量机的一个优点:
    对于低维度不可分的问题,可以通过函数转换成高维度,这样对于一个平面内的不可分割问题,就会转换成空间问题,然后用一个面就能分割了。
    在这里插入图片描述
    这种方法被称为核变换。
    利用核函数进行核变换,时间复杂度是o(n^2)
    常用的叫做高斯核函数,能把低维度变成高维度,把线性向量机变成非线性的。
    在这里插入图片描述
    核函数可以将一个不可分割的数据集变得可分割。

    代码实现:利用支持向量机分类数据,并且探索不同的核函数,不同的C值和不同的gamma对分类结果的影响。

    %matplotlib inline
    import numpy as np
    from scipy import stats
    import matplotlib.pyplot as plt
    from sklearn.datasets.samples_generator import make_blobs
    #模拟随机产生个数据,数据的样本数量是8,中心点是2,密集度是0.6
    x,y= make_blobs(n_samples=80,centers=2,random_state=0,cluster_std=0.60)
    #cluster_std的意思是,簇的分散程度,越大表示数据越分散,越小表示越集中。
    plt.scatter(x[:,0],x[:,1],c=y,s=50)
    

    画图如下:
    在这里插入图片描述
    x的部分数据:

    array([[  1.65991049e+00,   3.56289184e+00],
           [  1.60841463e+00,   4.01800537e-01],
           [  2.77180174e-01,   4.84428322e+00],
           [  9.14338767e-01,   4.55014643e+00],
           [  2.15527162e+00,   1.27868252e+00],
           [  3.18515794e+00,   8.90082233e-02],
           [  1.81336135e+00,   1.63113070e+00],
           [  2.18023251e+00,   1.48364708e+00],
           [  2.42371514e+00,   1.45098766e+00],
           [  2.13141478e+00,   1.13885728e+00],
           [  4.88382309e-01,   3.26801777e+00],
           [  2.23421043e+00,   1.69349520e+00],
    

    y的数据:

    array([0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1,
           0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1,
           1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0,
           1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1])
    

    建立模型

    #导入向量机模型
    from sklearn.svm import SVC #Support vector classifier
    model = SVC(kernel='linear')#构造了一个最基本的线性支持向量机
    model.fit(x,y)
    

    绘图函数

    #绘图函数
    def plot_function(model,ax=None,plot_support=None):
        if ax is None:
            ax = plt.gca()
        xlim = ax.get_xlim()
        ylim = ax.get_ylim()
        x = np.linspace(xlim[0],xlim[1],30)
        y = np.linspace(ylim[0],ylim[1],30)
        Y,X = np.meshgrid(y,x)
        xy = np.vstack([X.ravel(),Y.ravel()]).T
        P = model.decision_function(xy).reshape(X.shape)
        ax.contour(X,Y,P,colors='k',levels=[-1,0,1],alpha=0.5,linestyles=['--','-','--'])
        
        if plot_support:
            ax.scatter(model.support_vectors_[:,0],
                      model.support_vectors_[:,1],
                      s=300,linewidth=1,facecolors='none');
        ax.set_xlim(xlim)
        ax.set_ylim(ylim) 
        
    

    画图:

    plt.scatter(x[:,0],x[:,1],c=y,s=50)
    plot_function(model)
    

    结果如下:
    在这里插入图片描述
    从图中可以看出,对于一个能够分开有明确边界的二维数据,可以用线性的进行分类,并且能够构造出较好的支持向量

    中间这条线是决策边界,两个边界上的点就是支持向量, 在scikit-Learn中,他们存储在supportvectors(一个属性)

    model.support_vectors_
    #支持向量所在的位置
    #只要支持向量没有变,那么决策边界就不会变,那么新的数据点肯定在这个分区里
    

    支持向量的输出结果:

    array([[ 2.33812285,  3.43116792],
           [ 0.44359863,  3.11530945],
           [ 1.35139348,  2.06383637],
           [ 1.53853211,  2.04370263]])
    

    接下来是对于完全穿插的点,利用线性进行分类

    from sklearn.datasets.samples_generator import make_circles
    x,y = make_circles(100,factor=.1,noise=.1)
    #做一个圆形的数据样本
    clf = SVC(kernel='linear').fit(x,y)
    plt.scatter(x[:,0],x[:,1],c=y,s=50)
    plot_function(clf,plot_support=False)
    

    画图如下:
    在这里插入图片描述
    如图可以看出,如果以这种样本,线性支持向量机就不行了,分不开了,只能用核函数
    核函数的画图理解:

    from mpl_toolkits import mplot3d
    r = np.exp(-(x**2).sum(1))
    def plot_3D(elev=30,azim=30,x=x,y=y):
        ax = plt.subplot(projection='3d')
        ax.scatter3D(x[:,0],x[:,1],r,c=y,s=50)
        ax.view_init(elev=elev,azim=azim)
        ax.set_xlabel('x')
        ax.set_ylabel('y')
    plot_3D(elev=45,azim=45,x=x,y=y)
    

    在这里插入图片描述
    也就是说,对于低维度不可分割的样本,转换成更高的维度。

    #加入径向基函数
    clf = SVC(kernel='rbf',C=1E6)
    #高斯算法提升维度有很多种,rbf只是其中一种
    clf.fit(x,y)
    plt.scatter(x[:,0],x[:,1],c=y,s=50)
    plot_function(clf)
    

    画图如下:
    在这里插入图片描述
    高斯核函数能够把线性变成非线性的决策边界。
    这样就能够把样本的分的越明显。
    所以对于不容易分类的样本,只要提高维度就行。
    C值对支持向量的影响:

    x,y= make_blobs(n_samples=80,centers=2,random_state=0,cluster_std=0.80)
    #生成数据点
    fig,ax = plt.subplots(1,2,figsize=(16,6))
    fig.subplots_adjust(left=0.0625,right=0.95,wspace=0.1)
    for axi,C in zip(ax,[10,0.1]):
        model = SVC(kernel='linear',C=C).fit(x,y)
        axi.scatter(x[:,0],x[:,1],c=y,s=50)
        plot_function(model,axi)
        axi.scatter(model.support_vectors_[:,0],
                   model.support_vectors_[:,1],
                   s=300,lw=1,facecolors='none');
        #axi.set_title('C = {0:.1f}',format(C),size=14)
    

    在这里插入图片描述
    如图所示:如果C值过大容忍度就小,不能有错误点,反之亦然。
    gamma值对最终结果的影响

    x,y= make_blobs(n_samples=80,centers=2,random_state=0,cluster_std=1.1)
    #cluster_std是离散程度,超过1,就完全接触了
    #生成数据点
    fig,ax = plt.subplots(1,2,figsize=(16,6))
    fig.subplots_adjust(left=0.0625,right=0.95,wspace=0.1)
    for axi,gamma in zip(ax,[10,0.1]):
        model = SVC(kernel='rbf',gamma=gamma).fit(x,y)
        axi.scatter(x[:,0],x[:,1],c=y,s=50,cmap='autumn')
        plot_function(model,axi)
        axi.scatter(model.support_vectors_[:,0],
                   model.support_vectors_[:,1],
                   s=300,lw=1,facecolors='none');
    

    画图如下:
    在这里插入图片描述
    gamma值越高,模型的映射维度越高,结果更加精确,但是曲线不规则,有可能过拟合,gamma值越小,模型映射的维度降低,但是不容易分开。
    利用支持向量机对人脸识别的实现

    from sklearn.datasets import fetch_lfw_people
    #导入人脸识别数据
    faces = fetch_lfw_people(min_faces_per_person=60)
    #取出对于每一个人来说,最小人脸大于60的人
    print(faces.target_names)#取出这些人的名字
    print(faces.images.shape)#取出图片个数,像素大小
    #注释:自动下载非常慢,先让他自动下载成压缩包,只要压缩包出现就停止,然后网上下载lfw这个压缩包和lfw-funnel.gz,建立一个名字为lfw_funneled的文件夹,然后把lfw的照片全部拷贝过去
    
    

    输出如下:

    ['Ariel Sharon' 'Colin Powell' 'Donald Rumsfeld' 'George W Bush'
     'Gerhard Schroeder' 'Hugo Chavez' 'Junichiro Koizumi' 'Tony Blair']
    (1348, 62, 47)
    

    打印出人脸看看

    fig,ax=plt.subplots(3,5)
    for i,axi in enumerate(ax.flat):
        axi.imshow(faces.images[i],cmap='bone')#打印出一部分人脸看看
        axi.set(xticks=[],yticks=[],xlabel=faces.target_names[faces.target[i]])
    

    照片的一个像素点表示一个维度,一共2914维度,需要降维。

    from sklearn.svm import SVC
    from sklearn.decomposition import PCA
    from sklearn.pipeline import make_pipeline
    
    pca = PCA(n_components=150,whiten=True,random_state=42)
    #把维度降低到150维
    svc = SVC(kernel='rbf',class_weight='balanced')
    model = make_pipeline(pca,svc)
    #捆绑在一起,意思是SVC和PCA合并在了一起,就是降维的svc
    

    进行数据切分,划分出训练集和测试集。
    直观的观察下数据:
    faces.data.shape#数据的维度 打印结果(1348,2914)
    faces.data#数据就是矩阵,行是图片的个数,列是像素点的个数。类似于KNN的手写识别

    array([[ 114.        ,  122.33333588,  134.        , ...,    2.66666675,
               4.33333349,    5.        ],
           [  42.        ,   62.        ,   73.        , ...,  254.        ,
             252.        ,  249.        ],
           [  73.66666412,   78.66666412,   71.        , ...,  195.33332825,
             233.66667175,  233.33332825],
           ..., 
           [  29.66666603,   30.33333397,   30.        , ...,  135.33332825,
             141.        ,  145.        ],
           [  55.66666794,   60.        ,   69.66666412, ...,   22.        ,
              15.        ,    8.        ],
           [ 137.        ,   55.33333206,   43.        , ...,   42.33333206,
              46.        ,   47.        ]], dtype=float32)
    

    faces.target()#姓名转换成的数字,以方便做矩阵预算
    输出结果:array([1, 3, 3, …, 7, 3, 5], dtype=int64)
    CV验证,获得最好的C和gamma

    param_grid = {'svc__C':[1,5,10],'svc__gamma':[0.0001,0.0005,0.001]}#选取要循环的参数,就是要测试的参数
    grid = GridSearchCV(model,param_grid=param_grid,cv=5)#选择模型,选择CV,就是交叉验证,如果不进行结果不准确
    grid.fit(x_train,y_train)
    grid.grid_scores_, grid.best_params_, grid.best_score_
    

    结果如下:

    ([mean: 0.19090, std: 0.16492, params: {'svc__C': 1, 'svc__gamma': 0.0001},
      mean: 0.59050, std: 0.10427, params: {'svc__C': 1, 'svc__gamma': 0.0005},
      mean: 0.78042, std: 0.01349, params: {'svc__C': 1, 'svc__gamma': 0.001},
      mean: 0.64985, std: 0.06542, params: {'svc__C': 5, 'svc__gamma': 0.0001},
      mean: 0.79426, std: 0.01482, params: {'svc__C': 5, 'svc__gamma': 0.0005},
      mean: 0.80712, std: 0.01576, params: {'svc__C': 5, 'svc__gamma': 0.001},
      mean: 0.79327, std: 0.01480, params: {'svc__C': 10, 'svc__gamma': 0.0001},
      mean: 0.78536, std: 0.01664, params: {'svc__C': 10, 'svc__gamma': 0.0005},
      mean: 0.79525, std: 0.01796, params: {'svc__C': 10, 'svc__gamma': 0.001}],
     {'svc__C': 5, 'svc__gamma': 0.001},
     0.80712166172106825)
    
    from sklearn.metrics import confusion_matrix,classification_report,recall_score,accuracy_score
    #CV验证可以把最优的模型直接拿出来
    model = grid.best_estimator_
    #拿到最好的模型后,进行预测
    y_pred=model.predict(x_test)
    cnf_matrix =confusion_matrix(y_test,y_pred)
    #把小数位数改为2位
    np.set_printoptions(precision=2)
    print(accuracy_score(y_test,y_pred))
    cnf_matrix
    

    输出结果和混淆矩阵如下

    0.747774480712
    Out[29]:
    array([[ 13,   1,   1,   1,   0,   0,   0,   0],
           [  0,  51,   0,   2,   0,   0,   0,   1],
           [  1,   0,  23,   6,   3,   1,   0,   0],
           [  4,   4,   3, 105,   5,   4,   1,  10],
           [  0,   0,   0,   2,  18,   3,   1,   3],
           [  1,   1,   0,   4,   3,   7,   2,   0],
           [  1,   1,   0,   1,   1,   0,  10,   1],
           [  0,   5,   1,   2,   3,   1,   0,  25]], dtype=int64)
    

    导入分类报告

    from sklearn.metrics import classification_report
    #导入分类报告
    print(classification_report(y_test,y_pred,target_names=faces.target_names))
    

    结果如下:

                       precision    recall  f1-score   support
    
         Ariel Sharon       0.65      0.81      0.72        16
         Colin Powell       0.81      0.94      0.87        54
      Donald Rumsfeld       0.82      0.68      0.74        34
        George W Bush       0.85      0.77      0.81       136
    Gerhard Schroeder       0.55      0.67      0.60        27
          Hugo Chavez       0.44      0.39      0.41        18
    Junichiro Koizumi       0.71      0.67      0.69        15
           Tony Blair       0.62      0.68      0.65        37
    
          avg / total       0.76      0.75      0.75       337
    

    精度(precision) =正确预测的个数(TP)/被预测正确的个数(TP+FP)
    召回率(recall)=正确预测的个数(TP)/预测个数(TP+FN)

    展开全文
  • 支持向量机与人脸识别

    千次阅读 2013-12-02 16:33:48
    [摘要]: 支持向量机(Support Vector Machine,SVM)是机器学习中的一个新模型,能非常成功地处理回归问题(时间序列分析)和模式识别(分类问题、判别分析)等诸多问题,并可推广于预测和综合评价等领域。本文对它的基本...
     
    

    [摘要]: 支持向量机(Support Vector Machine,SVM)是机器学习中的一个新模型,能非常成功地处理回归问题(时间序列分析)和模式识别(分类问题、判别分析)等诸多问题,并可推广于预测和综合评价等领域。本文对它的基本思想、方法进行了介绍, 并简要介绍了如何利用SVM进行人脸识别,希望使读者对这一领域有一个基本的了解。

        [关键词]:支持向量机;KKT条件;人脸识别

    引言

        基于数据的机器学习是现代智能技术中的重要方面。研究从观测数据(样本)出发寻找规律。利用这些规律对未来数据或无法观测的数据进行预测。包括贝叶斯学习、神经网络等在内,现有机器学习方法共同的重要理论基础之一大数定理:当样本数且趋近于无穷时,对样本的估计趋近于数据的真实分布。传统统计学研究的是样本数且趋近于穷大时的渐近理论,现有学习方法也多是基于此假设。但在实际问题中。样本数往往是有限的,因此一些理论上很优秀的学习方法实际中表现却可能不尽人意。

        与传统统计学相比,统计学习理论(Statistical Learning Theory,SLT)是一种研究有限样本情况下统计及机器学习规律的理论。V. Vapnik 等人从六、七十年代开始致力于此方面的研究,到九十年代中后期,随着其理论的不断发展和成熟,也由于神经网络等学习方法在理论上缺乏实质性进展,统计学习理论开始受到越来越广泛的重视。

        统计学习理论是建立在一套较坚实的理论基础之上的,为解决有限样本学习问题提供了一个统一的框架。它能将很多现有方法纳入其中,有望帮助解决许多原来难以解决的问题(比如神经网络结构及参数选择问题);同时。在这一理论基础上发展了一种新的通用学习方法:支持向量机(Support Vector Machine,SVM)。它己表现出很多优秀的性能,已经成为当今机器学习领域的研究热点,并将有力地推动机器学习理论和技术的发展。

    SVM理论基础

           机器学习的目的是根据给定的训练样本求对某系统输入输出之间依赖关系的估计,使它能够对未知输出作出尽可能准确的预测。可以一般地表示为:变量y 与x 存在一定的未知依赖关系,即遵循某一未知的联合概率F (x , y) ,(xy之间的确定性关系可以看作是其特例) ,机器学习问题就是根据n个独立同分布观测样本在一组函数{f(x ,w)}中求一个最优的函数 对依赖关系进行估计, 使期望风险最小。 其中, {f (x ,w)}称作预测函数集,w为函数的广义参数, {f (x,w)}可以表示任何函数集;L (y , f (x ,w)) 为由于用f (x ,w)对y进行预测而造成的损失,不同类型的学习问题有不同形式的损失函数。预测函数也称作学习函数、学习模型或学习机器。

        SVM 是从线性可分情况下的最优分类发展而来的。基本思想可用下图的二维情况说明。图中方块和圆球代表两类样本A+和A-,中间虚线为分类面。

    在图中所示的两条实线是分类面两侧分别为过各类中离分类面最近的样本平行于分类面的超平面,它们叫做支撑面,它们之间的距离叫做分类间隔(margin)。支撑面上的样本叫做支持向量,这也是支持向量机名字的由来。所谓最优分类面就是要求分类面不但能将两类正确分开(训练错误率为0),而且使分类间隔最大。分类面方程为<w,x>+b=0

    考虑一个用某特征空间的超平面对给定训练数据集做二值分类的问题。对于给定样本点:(1)

    在特征空间中构造分类平面: <w,x>+b=0        (2)在给定约束:(3)

    则方程为<w×x>+b= +1和<w×x>+b= -1的两个平面分别为正例样本和负例样本的支撑面(如前图所示)。

        在给定此约束的情况下,可以计算出,根据几何知识可知,分类间隔为2/‖w‖。根据SVM 对最优分类平面的定义,可以看出对该平面的求解问题可以建模为:在满足条件式(3)的情况下,计算能使2/‖w‖最大化的分类平面的法向量w0b。综合上面所有的讨论,我们有了以下目标函数:(4)因为限定条件的关系,上面的最佳化问题有点棘手,还好我们可以利用拉格朗日乘子方法将上面的式子转成一个二次方程式,找出可以使L为最小值的w, b, αi。  (5)符合条件的极值点会出现在:

    时,

     时,

        接下来我们要求解L的最小值,所以分别对w及对b求偏导:(6)代回上面的式(5)得到(7)我们把上面的条件综合一下得到(8)

     

    上面这些条件又被称为KKT条件(Karush-Kuhn -Tucker conditions)。

        支持向量就是那些满足KKT条件的点,并且它们对应的 会大于0。在我们求得支持向量以后,我们就可以用下式它们来判断新加入的点是属于哪一个集合(9)

    SVM与人脸识别

        SVM在解决小样本、非线性及高维模式识别问题中表现出许多特有的优势。已经应用于手写体识别、三维目标识别、人脸识别、文本图像分类等实际问题中,性能优于已有的学习方法,表现出良好的学习能力。从有限训练样本得到的决策规则对独立的测试集仍能够得到较小的误差。下面以人脸识别为例说明SVM的应用。

        LIBSVM 是台湾大学林智仁(Chih-Jen Lin)教授等开发设计的一个操作简单、易于使用、快速有效的通用SVM 软件包,利用它我们可以很简单的解决人脸识别问题。

        这次实验使用耶鲁大学的人脸库,这个库包含15个人的脸,每个人有11张照片,每张照片在不同的光照条件下拍摄,脸上的表情不同,背景不同……等等。下面是其中一个人的照片:

     

     

    我们取前8张作为训练样本,后3张作为测试样本。在训练之前我们先做一些预处理:

        1.     把照片缩小到20×20。根据实验,20×20分辨率的照片已经足够了;

        2.     用PCA做特征提取,也就是提取特征脸,下面简述特征脸的提取:

        a)     先将每个人脸相加求平均,求得一张平均脸

       b)     再对每张脸求与平均脸的差异,将每张脸减平均脸,得到一个向量       

        c)     把所有向量排成一个矩阵A

        d)    矩阵A乘上自己的转置变成协方差矩阵

     

        e)求解这个协方差矩阵的特征向量,我们只取前14个特征向量,将原来的人脸照片投影到这14个特征向量上,所以每张脸会有14个维度的数据然后采用libsvm训练:

        1.     把所有照片的数据都用libsvm要求的格式排好。

        2.     用svmscale把数据正则化到[-1, 1]范围内。

    svmscale -l -1 -u 1 -s range TrainingSet.txt > TrainingSet.scale

        3.     训练,产生一个名字为TrainingSet.scale.model的文件。

    svmtrain TrainingSet.scale

        4.     用svmpredict来检验训练的结果是否达到我们的要求。

    svmpredict TrainingSet.scale TrainingSet.scale.model out

        最后显示的结果为:

    Accuracy = 94.1667% (113/120) (classification)

    Mean squared error = 3.95 (regression)

    Squared correlation coefficient = 0.804937 (regression)

        正确率为94.1667%,这次训练的结果不错。

    讨论

        由于支持向量机建立了一套较好的有限样本下机器学习的理论框架和通用方法, 既有严格的理论基础, 又能较好地解决小样本、非线性、高维数和局部极小点等实际问题, 因此成为九十年代末发展最快的研究方向之一, 其核心思想就是学习机器要与有限的训练样本相适应。 本文对它们的基本思想、方法进行了介绍, 希望使读者对这一领域有一个基本的了解。支持向量机虽然已经提出多年, 但从它自身趋向成熟和被广泛重视到现在毕竟还不长, 其中还有很多尚未解决或尚未充分解决的问题, 在应用方面的研究更是刚刚开始。 我们认为, 支持向量机模型与应用是一个十分值得大力研究的领域。

     

    转自:http://www.cnblogs.com/cvlabs/archive/2010/04/13/1711470.html

    展开全文
  • SVM向量机算法原理 SVM寻找区分两类的超平面(hyper plane), 使边际(margin)最大 线性可分SVM——线性 SVM——非线性 SVM 1、线性可分SVM,表示可以用一根线非常清晰的划分两个区域;线到支持向量的距离 d 就是最小...

    SVM向量机算法原理

    SVM寻找区分两类的超平面(hyper plane), 使边际(margin)最大
    线性可分SVM——线性 SVM——非线性 SVM
    1、线性可分SVM,表示可以用一根线非常清晰的划分两个区域;线到支持向量的距离 d 就是最小的。
    2、线性 SVM,表示用一根线划分区域后,可能存在误判点,但还是线性的;线到支持向量的距离不一定是最小的,但忽略其他非规则的支持向量。
    3、非线性 SVM,表示使用核函数之后,把低维的非线性转换为高维线性

    线性可区分

    在这里插入图片描述在这里插入图片描述

    线性不可区分的情况

    在这里插入图片描述
    在这里插入图片描述
    SVM是一种分类算法,一种前馈网络类型,

    SVM推导

    最初分类函数、最大化margin、拉格朗日
    SVM推导过程同样分为线性与非线性
    线性可分支持向量机
    SVM利用间隔最大化求得最优超平面,解唯一。其分类决策函数为
    f ( x ) = s i g n ( w ⋅ x + b ) f(x)=sign(w⋅x+b) f(x)=sign(wx+b)
    非线性可分支持向量机
    在计算得到核函数之前,需要完成两步:
    1.首先使用一个非线性映射将数据变换到一个特征空间F;
    2. 然后在特征空间使用线性学习器分类;
    其分类决策函数为
    f ( x ) = ∑ i = 1 N w i ⋅ Φ ( x i ) + b f(x) = \sum_{i=1}^{N} w_i \cdot \Phi(x_i) +b f(x)=i=1NwiΦ(xi)+b
    其中 Φ ( x i ) \Phi(x_i) Φ(xi)就是将样本映射到高维空间的映射函数。

    支持向量机代码

    需要的模型

    import matplotlib.pyplot as plt
    from sklearn.model_selection import train_test_split
    from sklearn.datasets import fetch_lfw_people
    from sklearn.model_selection  import GridSearchCV
    from sklearn.metrics import classification_report
    from sklearn.svm import SVC
    from sklearn.decomposition import PCA
    

    train_test_split是用来分割数据集的,将数据分为训练数据和测试数据

    fetch_lfw_people就是我们用到的人脸数据集

    GridSearchCV是寻找合适的SVM参数组合的

    classfusion_report和confusion_matrix是后面用来给模型打分的

    RandomizedPCA就是我们用来降维的

    数据

    # 下载数据集--户外脸部数据集lfw(Labeled Faces in the Wild)
    lfw_people = fetch_lfw_people(min_faces_per_person=70, resize=0.4)
    
    # 函数定义
    Signature: fetch_lfw_people(data_home=None, funneled=True, resize=0.5, min_faces_per_person=0, color=False, slice_=(slice(70, 195, None), slice(78, 172, None)), download_if_missing=True)
    Docstring:
    Loader for the Labeled Faces in the Wild (LFW) people dataset
    # minfaces_per_person:int,可选默认无,提取的数据集仅保留包含min_faces_per_person不同图片的人的照片
    # resize调整每张人脸图片的比例,默认是0.5
    

    显示图片以及数据格式

    plt.imshow(lfw_people.images[6],cmap='gray')
    plt.show()
    n_samples, h, w = lfw_people.images.shape   #实例数(图片数)、h、w
    print(n_samples)
    print(h)
    print(w)
    lfw_people.data.shape     ## 图像的维度   对于图像维度较小  对于SVM算法 维度较高
    
    #X矩阵用来装特征向量,得到数据集的所有实例
    #每一行是一个实例,每一列是个特征值
    X=lfw_people.data
    #X矩阵调用shape返回矩阵的行数和列数,
    X.shape[1] #返回矩阵的列数,对应的特征向量的维度或者特征点多少
    
    #获取特征结果集,提取每个实例对应的每个人脸
    #y为classlabel目标分类标记,即不同人的身份
    lfw_people.target
    target_names = lfw_people.target_names  ## 类别的数量  以人名组成列表返回
    target_names
    n_classes = lfw_people.target_names.shape # 维度 多少行
    n_classes
    n_classes = n_classes[0]
    n_classes
    
    
    print("Total dataset size:")       #数据信息
    print("n_samples:%d"% n_samples)   #数据个数
    print("n_features:%d"% n_features) #特征个数,维度
    print("n_classes:%d"% n_classes)   #结果集类别个数,即多少个人
    

    拆分数据为训练集和测试集

    x_train, x_test, y_train, y_test = train_test_split(lfw_people.data, lfw_people.target) # 拆分函数,可以增加test_size=0.25参数,表示随机抽取25%的测试集,还有其他参数可供选择
    

    支持向量机SVM

    model = SVC(kernel='rbf', class_weight='balanced')  # 自动输出SCV的各种默认参数
    model.fit(x_train, y_train)
    

    输出

    SVC(C=1.0, cache_size=200, class_weight='balanced', coef0=0.0,
      decision_function_shape='ovr', degree=3, gamma='auto', kernel='rbf',
      max_iter=-1, probability=False, random_state=None, shrinking=True,
      tol=0.001, verbose=False)
    

    单纯的SVM算法输出

    predictions = model.predict(x_test)
    print(classification_report(y_test, predictions, target_names=lfw_people.target_names))
    # 相对于SVM算法较大的维度,得到的精度很低,因此需要对图像进行降维 
    

    PCA降维

    # 100个维度
    n_components = 100
    pca = PCA(n_components=n_components, whiten=True).fit(lfw_people.data)
    x_train_pca = pca.transform(x_train)  # tranform对数据进行降维
    x_test_pca = pca.transform(x_test)
    
    x_train_pca.shape # 降维后的维度
    

    再次利用SVM进行建模 得到结果

    model = SVC(kernel='rbf', class_weight='balanced')
    model.fit(x_train_pca, y_train)
    
    predictions = model.predict(x_test_pca)
    print(classification_report(y_test, predictions, target_names=target_names))
    

    调参进一步优化

    # 调参的方法可以通用
    # 调参的方法 把参数全部设置 算法自动进行调参 'C' 'gamma' 5个参数逐个进行调参   
    #c是一个对错误的部分的惩罚
    #gamma的参数对不同核函数有不同的表现,gamma表示使用多少比例的特征点
    #使用不同的c和不同值的gamma,进行多个量的尝试,然后进行搜索,选出准确率最高模型
    param_grid = {'C': [0.1, 1, 5, 10, 100],
                  'gamma': [0.0005, 0.001, 0.005, 0.01], }
    #调用SVM进行分类搜索哪对组合产生最好的归类精确度
    #ernel:rbf高斯径向基核函数   class_weight权重
    #把所有我们所列参数的组合都放在SVC里面进行计算,最后看出哪一组函数的表现度最好
    model = GridSearchCV(SVC(kernel='rbf', class_weight='balanced'), param_grid)
    model.fit(x_train_pca, y_train)
    print(model.best_estimator_)
    

    输出结果

    #进行评估准确率计算
    predictions = model.predict(x_test_pca)
    #通过classification_report方法进行查看,可以得到预测结果中哪些是正确
    print(classification_report(y_test, predictions, target_names=target_names))
    

    再次调参

    param_grid = {'C': [0.1, 0.6, 1, 2, 3],
                  'gamma': [0.003, 0.004, 0.005, 0.006, 0.007], }
    model = GridSearchCV(SVC(kernel='rbf', class_weight='balanced'), param_grid)
    model.fit(x_train_pca, y_train)
    print(model.best_estimator_)
    

    输出结果

    predictions = model.predict(x_test_pca)
    print(classification_report(y_test, predictions, target_names=target_names))
    

    最后画图,验证最终测试结果

    # 画图,34列
    #将测试标记过进行展示,即先弄一个通用的图片可视化函数:
    def plot_gallery(images, titles, h, w, n_row=3, n_col=5):
        #建立图作为背景
        #自定义画布大小
        plt.figure(figsize=(1.8 * n_col, 2.4 * n_row))
        #位置调整
        plt.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, hspace=.35)  # 图片显示效果的设置
        for i in range(n_row * n_col):
            #设置画布划分以及图像在画布上输出的位置
            plt.subplot(n_row, n_col, i + 1)
            #在轴上显示图片
            plt.imshow(images[i].reshape((h, w)), cmap=plt.cm.gray)
            #整个画板的标题
            plt.title(titles[i], size=12)
            #获取或设置x、y轴的当前刻度位置和标签
            plt.xticks(())
            plt.yticks(())
    
    # 获取一张图片title
    #预测函数归类标签和实际归类标签打印      
    #返回预测人脸姓和测试人脸姓的对比title
    def title(predictions, y_test, target_names, i):
        #rsplit(' ',1)从右边开始以右边第一个空格为界,分成两个字符
        #组成一个list
        #此处代表把'姓''名'分开,然后把后面的姓提出来
        #末尾加[-1]代表引用分割后的列表最后一个元素
        #对比rsplit与split的区别
        pred_name = target_names[predictions[i]].split(' ')[-1]
        true_name = target_names[y_test[i]].split(' ')[-1]
        return 'predicted: %s\ntrue:      %s' % (pred_name, true_name)
    
    # 获取所有图片title
    prediction_titles = [title(predictions, y_test, target_names, i) for i in range(len(predictions))] # list中的循环
    
    # 画图
    plot_gallery(x_test, prediction_titles, h, w)
    
    #打印原图和预测的信息
    eigenface_titles =["eigenface %d" % i for i in range (eigenfaces.shape[0])]
    #调用plot_gallery函数打印出实际是谁,预测的谁,以及提取过特征的脸
    plot_gallery(eigenfaces, eigenface_titles, h, w)
    
    plt.show()
    

    最终的测试结果

    引用博客
    SVM算法详细推导过程

    展开全文
  • PCA+支持向量机-人脸识别(五)

    千次阅读 2015-01-08 16:40:01
    对于上篇中数据库ORL人脸库和AR人脸库(下载地址在上篇中有),在上篇中讨论的单纯的PCA算法对两个数据库进行了准确率计算,本篇为了提高识别准确率,特采用一种新方法,并结合PCA一起实现识别,实验结果发现该方法...

    一):实验准备

      本篇可以接上篇:PCA实验人脸库-人脸识别(四)

    对于上篇中数据库ORL人脸库和AR人脸库(下载地址在上篇中有),在上篇中讨论的单纯的PCA算法对两个数据库进行了准确率计算,本篇为了提高识别准确率,特采用一种新方法,并结合PCA一起实现识别,实验结果发现该方法能明显提高两者数据库的识别率。

    二):关于支持向量机

    一直以来感觉支持向量机是一个神奇的算法,当然里面的原理相应来说也比较难懂,感觉能把支持向量机原理理解并讲明白的估计对其他大多数的算法似乎都能理解,对于使用级的,这里能大概明白并会用支持向量机工具箱的就可以了。

    关于原理,贴几个比较好的,学了一段时间感觉稍微能明白点,如果一点原理都不懂,硬着头皮先看吧,总会明白的。

    大神博客:支持向量机通俗导论(理解SVM的三层境界)

    一个SVM网站:

    http://see.xidian.edu.cn/faculty/chzheng/bishe/index.htm

    一个系列SVM知识集合:

    http://www.blogjava.net/zhenandaci/category/31868.html

    支持向量机SVM(Support Vector Machine)

    三):关于支持向量机工具箱—LIBSVM

    LIBSVM工具箱是台湾国立大学的一些人研究制作的,这里面把SVM的用法都集成化了,想怎么用,用哪个核函数等等只需要修改相应的参数就可以了,可以说使用起来非常方便的。像LIBSVM在matlab下的工具箱只有四个函数,其中通常情况下就用其中的两个函数,svmtrain训练模型函数和svmpredict预测数据函数,至于选择SVM算法中的哪个核函数直接写相应的参数就可以了。虽然新版的matlab也集成了SVM函数,但是感觉使用起来特麻烦,需要自己规定核函数,核函数参数等等。况且matlab自带的算法功能少,有些问题不适用。

    关于LIBSVM在matlab下的使用,Matlab下安装LIBSVM:Matlab安装使用libsvm

    LIBSVM使用

    其他平台:libsvm使用步骤:libsvm使用步骤


    四):LIBSVM中函数的简短说明

    目前版LIBSVM(3.2.0)在matlab下编译完后只有四个函数,libsvmread,Libsvmwrite,svmtrain(matlab自带的工具箱中有一个同名的函数),svmpredict

      libsvmread主要用于读取数据,这里的数据是非matlab下的.mat数据,比如说是.txt,.data等等,这个时候需要使用libsvmread函数进行转化为matlab可识别数据,比如自带的数据是heart_scale数据,那么导入到matlab有两种方式,一种使用libsvmread函数,在matlab下直接libsvmread(heart_scale);第二种方式为点击matlab的‘导入数据’按钮,然后导向heart_scale所在位置,直接选择就可以了。个人感觉第二种方式超级棒,无论对于什么数据,比如你在哪个数据库下下载的数据,如何把它变成matlab下数据呢?因为有的数据libsvmread读取不管用,但是‘导入数据’后就可以变成matlab下数据。

    libsvmwrite写函数,就是把已知数据存起来,使用方式为:libsvmwrite('filename',label_vector, instance_matrix);

    label_vector是标签,instance_matrix为数据矩阵(注意这个数据必须是稀疏矩阵,就是里面的数据不包含没用的数据(比如很多0),有这样的数据应该去掉再存)。

    svmtrain训练函数,训练数据产生模型的,一般直接使用为:

    model=svmtrain(label,data,cmd); label为标签,data为训练数据(数据有讲究,每一行为一个样本的所有数据,列数代表的是样本的个数),每一个样本都要对应一个标签(分类问题的话一般为二分类问题,也就是每一个样本对应一个标签)。cmd为相应的命令集合,都有哪些命令呢?很多,-v,-t,-g,-c,等等,不同的参数代表的含义不同,比如对于分类问题,这里-t就表示选择的核函数类型,-t=0时线性核。-t=1多项式核,-t=2,径向基函数(高斯),-t=3,sigmod核函数,新版出了个-t=4,预计算核(还不会用);-g为核函数的参数系数,-c为惩罚因子系数,-v为交叉验证的数,默认为5,这个参数在svmtrain写出来使用与不写出来不使用的时候,model出来的东西不一样,不写的时候,model为一个结构体,是一个模型,可以带到svmpredict中直接使用,写出来的时候,出来的是一个训练模型的准确率,为一个数值。一般情况下就这几个参数重要些,还有好多其他参数,可以自己参考网上比较全的,因为下面的这种方法的人脸识别就用到这么几个参数,其他的就不写了。

    svmpredict训练函数,使用训练的模型去预测来的数据类型。使用方式为:

    [predicted_label,accuracy,decision_values/prob_estimates]= svmpredict(testing_label_vector,testing_instance_matrix,model,'libsvm_options')

    或者:

    [predicted_label]=svmpredict(testing_label_vector,testing_instance_matrix, model, 'libsvm_options')

    第一种方式中,输出为三个参数,预测的类型,准确率,评估值(非分类问题用着),输入为测试类型(这个可与可无,如果没有,那么预测的准确率accuracy就没有意义了,如果有,那么就可以通过这个值与预测出来的那个类型值相比较得出准确率accuracy,但是要说明一点的是,无论这个值有没有,在使用的时候都得加上,即使没有,也要随便加上一个类型值,反正你也不管它对不对,这是函数使用所规定的的),再就是输入数据值,最后是参数值(这里的参数值只有两种选择,-p和-b参数),曾经遇到一个这样的问题,比如说我在训练函数中规定了-g参数为0.1,那么在预测的时候是不是也要规定这个参数呢?当你规定了以后,程序反而错误,提醒没有svmpredict的-g参数,原因是在svmtrain后会出现一个model,而在svmpredict中你已经用了这个model,而这个model中就已经包含了你所有的训练参数了,所以svmpredict中没有这个参数,那么对于的libsvm_options就是-p和-b参数了。对于函数的输出,两种方式调用的方法不一样,第一种调用把所有需要的数据都调用出来了,二第二种调用,只调用了predicted_label预测的类型,这里我们可以看到,在单纯的分类预测模型中,其实第二种方式更好一些吧,既简单有实用。

    致此,四个函数在分类问题中的介绍大概如此,当然还有很多可以优化的细节就不详细说了,比如可以再使用那些参数的时候,你如果不规定参数的话,所有的-参数都是使用默认的,默认的就可能不是最好的吧,这样就涉及到如何去优化这个参数了。


    五):SVM+PCA识别人脸的实现步骤

    5.1:人脸数据库的准备

    这里还是以AR人脸库 和ORL人脸库来作为样本进行检测,对于上一篇的单纯PCA方法可以看出,pca方法对于ORL人脸库的识别率已经很高了,但是对于AR人脸库的识别率那是相当的低,原因在那里说了,ORL人脸库样本间差异小,而AR人脸库样本间的差异大。这里使用SVM来挑战AR这个样本差异大的人脸库。首先也是对样本进行分类,随机抽取一些作为训练集,另一些作为测试集。同样使到函数[train_face,test_face] = imgdata(filedata,num) 具体程序见上篇:PCA实验人脸库-人脸识别(四)

    5.2:对训练集与测试集进行降维

    为什么需要降维?原始一张图片转化成一行数据后有10000多维,对于这个维度来说,里面很多维可能都是无关的,这样去进行SVM训练虽然也可以,可是会导致效率低下,速度上没测试,维度高势必计算量也会增加的。所以适当的降维取其主成分从理论上来讲非常合适。首先对训练集进行降维,同样直接使用上篇的[img_new,img_mean,V] = PC
    A(img,k)函数。降维得到训练集的特征向量V后,用这个V去乘以测试集就可以把也降维了。这里有上篇的具体程序假设得到了[img_new,img_mean,V]这三个参数,现在怎么去给测试集也去降维呢?

    简短程序如下:

    [train_facepca,train_mean,V] = PCA(train_face,k);
    num_test = size(test_face,1);
    img_mean_all = repmat(train_mean,num_test,1);%复制m行平均值至整个矩阵
    test_face = double(test_face) - img_mean_all;
    test_facepca = test_face*V;
    

    得到的test_facepca就是降维后的测试数据。

    5.3:对训练集与测试集进行数据归一化

    数据归一化的目的就是去除不同数量级之间的不匹配关系,有的数据集归不规范化对结果影响不大,而有的影响就很大,这里我试了不规范化的数据,对结果的影响确实很大。所以正常来说最好都规范化一下吧,大部分情况规范化总是好的。这里就是对上述得到的降维后的训练集train_facepca和test_facepca进行规范化。程序如下:

    <span style="font-size:14px;">function scaledface = scaling( faceMat,lowvec,upvec )
    %特征数据规范化
    %输入——faceMat需要进行规范化的图像数据,
    upnew=1;
    lownew=-1;
    [m,n]=size(faceMat);
    scaledface=zeros(m,n);
    for i=1:m
        scaledface(i,:)=lownew+(faceMat(i,:)-lowvec)./(upvec-lowvec)*(upnew-lownew);
    end</span>

    这样把所有数据规范化到-11之间了。整个规范化程序为:

    %% 对训练集于测试集都进行数据归一化
    low = min(train_facepca);
    up = max(train_facepca);
    scaled_trainface = scaling(train_facepca,low,up);
    scaled_testface = scaling(test_facepca,low,up);

    5.4:对训练集训练得到模型

    由于libsvm处理的分类问题是两类问题,而我们这里可以看到,有50个不同的人脸,每个人又有26张样本,按照分类来说,就是每一张图片对应于50个类中的一个类。这就是50类分类问题了。那么如何由两类问题转化成50类问题呢?这里就把50个类划分成很多个2类问题,每两两一分,比如1-2,1-3,1-4...1-50;2-3,2-4,2-5...2-50,等等等等最后是49-50;这么些类,总共就有50*49/2个两类分类了,对每一个两类问题,都训练一次,产生一个model,就有50*49/2个model,每一类都和其他的49个类有一次联系吧。现在假设来了一个样本,比如是第10类吧,那么把这个样本依次带到所有的model中,循环50*49/2次,对于每一个model都会出现一个预测的类吧,比如现在理论上是第10类,依次带1-2,可能结果是个预测是个1(因为是在1-2两个类中预测,不是1就是2),1-3可能结果是个3,等等,当到了10-1(其实是1-10)至10-50这些个含有10的类时,由于样本本身是10,那么这些结果预测出来的肯定(90%以上)是10吧,这样把所有的二分类分循环完,也就是50*49/2次后,我们就可以统计出这个10落在第1类可能是30次,第二类可能是20次,第三类可能是27次等等等等,直到第10类是50次(接近50),在往后11类可能是30次,等等等等,第50类可能是10次。这样我们只要统计出这些个数中的最大者,那么这个类就是最大者对应的那个类了。

    这个过程就是这样,现在的问题是怎么得到这些model?每一个model需要其中两类的训练集,每一个训练集又可能不止一个样本,并且好要标签标上类型。

    我是这样处理的,比如现在求model{1,2},就是1与2类做一个model,每类假设选3个样本,这样训练样本就有6个样本,对应的标签分别是[1;1;1;2;2;2]就可以了吧。然后把这个标签价样本拿去svmtrain训练,好了,1-3,1-4等等等等都采用同样的方法就可以得到所有的model了。具体程序如下:

    %---------------------
    %     img_new--输入的train_face脸
    %     num:每个类(人)中选取num个样本
    function model = Model_Find(img_new,num)
    %  用法:   model = Model_Find(img_new,num);
    m = size(img_new,1);
    class_all = m/num;  %总共的类数
    %%  将训练集划分成SVM能够处理的形式(包括标签与数据)
    for i = 1:class_all-1    %1到k-1
        for j = i+1:class_all  %2到k
            train_label_all{i,j} = [i*ones(1,num),j*ones(1,num)]';%标上标签
            train_data_all{i,j} = [img_new((i-1)*num+1:i*num,:);img_new((j-1)*num+1:j*num,:)];
        end   %把对应的类上的数据提取出来
    end
    %%  调用SVM分类,对于k类共需要k*(k-1)/2 次划分
    for i = 1:class_all-1
        for j = i+1:class_all
            model{i,j} = svmtrain(train_label_all{i,j},train_data_all{i,j},'-t 0');
        end   %训练得到所有的model
    end

    5.5:对测试集进行测试得到准确率

      有了上面的model,用这些model去分类测试集就可以了。先写一个子程序,来处理随机来了一个样本时它是属于哪个类的,在处理所有的测试样本。

    function class = find_class(model,test)
    class_all = size(model,2); %注意model的大小为k*(k+1)
    belong = zeros(1,class_all);
    for i = 1:class_all-1
        for j = i+1:class_all
            predict = svmpredict(1,test,model{i,j});
    %标签任意写假设为1,因为需要预测的就是标签分类,不需要知道test的标签
            belong(predict) = belong(predict) + 1;
         end
    end
    class = find(belong == max(belong));
    %如果存在多个最大值,取第一个为准
    %调试半天终于知道错误了,这个必须考虑
    m = size(class,2);
    if m > 1
        class = class(1);
    End

    这个函数中的test可以认为是scaled_testface中的任意一行(一个样本),只对这个样本进行分类。

    基于此,再对所有的scaled_testface一一进行分类并计算准确率:

    function accurary = facefind_svm(model,test_facepca,num)
    % num:训练集中的每个人选取num个样本
    %  用法:   class = facefind_svm(model,test_face,img_mean,V);
    test_num = size(test_facepca,1); 
    for i = 1:test_num
        class(i) = find_class(model,test_facepca(i,:));
    end
    %%
    numtrue = 0;
    for i = 1:test_num
        if ceil(i/(26-num)) == class(i) 
            numtrue = numtrue+1;
        end
    end
    accurary = numtrue/test_num;

    六):整体main程序

    clc,clear;
    load('face_AR_50.mat');
    %%定义每个人选取num个样本,划分样本
    num = 3;
    [train_face,test_face] = imgdata(filedata,num);
    %% 对训练集于测试集求取PCA,都转化到PCA数据
    k = 140;  %降维数
    [train_facepca,train_mean,V] = PCA(train_face,k);
    num_test = size(test_face,1);
    img_mean_all = repmat(train_mean,num_test,1);%复制m行平均值至整个矩阵
    test_face = double(test_face) - img_mean_all;
    test_facepca = test_face*V;
    %% 对训练集于测试集都进行数据归一化
    low = min(train_facepca);
    up = max(train_facepca);
    scaled_trainface = scaling(train_facepca,low,up);
    scaled_testface = scaling(test_facepca,low,up);
    %% 训练与计算准确率
    model = Model_Find(scaled_trainface,num);
    accurary = facefind_svm(model,scaled_testface,num);

    七):实验结果记录

      首先贴一下上一次PCA方法下对AR数据库的识别结果:

    (AR人脸库(包含50位男性和50位女性每人26张人脸共2600张人脸图片 ),这里只选取了50位男性样本)

    每个人选取num个样本降维数k准确率accuracy
    num=5K=400.28
    num=10K=400.44
    num=15K=400.54

    可以看出效果是很差的。


        现在来看一下PCA+SVM的效果;

    实验中存在的可变变量:

    svmtrain 参数 :-t参数(这个是选择核函数的)其他的-g等等参数都是采   用默认的。

          系统参数:  num:每个人选取num个样本(最大26)

                       K :PCA中的降维数

    首先k一定,k选30;

    accuracynum=15;k = 30num=10;k = 30num=8;k = 30num=2;k = 30
    -t=00.840.790.64380.3717
    -t=10.27820.25380.190.10
    -t=20.650.64380.52100.3083
    -t=30.680.61750.48860.3458


    最好的,并且在num=15的时候准确率达到0.84,相比同等条件下的PCA只有0.54左右。
    从上面可以看出,核函数参数-t=0,也就是选择线性核函数的时候的效果始终是

    由此也可以断定线性核函数非常适合这个人脸识别库。下面就选的-t=0不变,改变降维数k看看结果如何:

    accuracyk = 50k = 80k = 140
    num=150.93090.96180.9618
    num=100.87130.90750.9238
    num=80.84220.80290.9267
    num=50.75520.81430.8400
    num=30.61830.67650.8052
    num=20.49170.6217维度过大

    从上述可以看到,在num=15,k = 140的时候准确率可以达到0.9618,应该很高了。另外,每次实验的数据会不一样,原因在于样本的选择是随机的。Num在往上加就没有试验了,每个人总共才26个样本,用到15个作为训练已经很多了。再看看在num=3的时候,最大准确率也可以达到0.8052,也就是说每个人26个样本中用3个就可以使准确率达到0.8052,这是PCA怎么也不可能达到的。而且这个AR数据库的差异性在以前讨论过的很大,在这种情况下支持向量机的优点显而易见。(上述最后一个维度过大的原因在于这个时候最大降维为50*2=100)


    相关代码下载: http://download.csdn.net/detail/on2way/8689529

    展开全文
  • 人脸识别之特征向量

    千次阅读 2015-02-08 10:27:25
    最近在学习人脸识别算法,看了Opencv自带的Eigenfaces人脸识别算法,算法的主要思想是利用PCA(Principal Component Analysis)将人脸图像数据高维空间映射到底维空间,将待识别图像低维空间数据与训练样本低维空间...
  • 一 背景 1.1 支持向量机简介 支持向量机(Support Vector Machine,SVM)...到目前为止,支持向量机已应用于孤立手写字符识别、网页或文本自动分类、说话人识别、人脸检测、性别分类、计算机入侵检测、基因分类、...
  • 与一维稀疏表示中将图像块转换为列向量不同,本文考虑到二维图像列与列之间的近邻关系,对图像块进行二维稀疏表示;在字典训练中,对每组图像块的每一列训练高、低分辨率字典,提出二维K-SVD算法对字典进行训练,减少字典...
  • 人脸识别是机器视觉中非常火的一个领域了,在近十几年来发展迅猛,而本文介绍的方法是基于稀疏表示分类(Sparse Representation based classification,SRC)的人脸识别,稀疏表示理论非常强大,突破了传统采样定了...
  • 基于稀疏表示人脸识别

    千次阅读 2016-03-12 17:12:43
    本文简单介绍了稀疏表示理论,然后从人脸识别领域的运用给出了代码示例。 稀疏表示理论 理论 稀疏表示求解 稀疏表示用于人脸识别 理论 代码 参考文献稀疏表示理论理论为了简单说明,采用一维信号进行讲解。一维离散...
  • 由于Gabor特征对表情、光照和姿态等变化具有一定的鲁棒性,提出一种基于Gabor特征和支持向量引导字典学习(GSVGDL)的稀疏表示人脸识别算法。先提取图像的Gabor特征,然后用增广Gabor特征矩阵来构造初始字典。字典...
  • 这篇是本博客第二篇文章的续文,即关于SVM和SRC做人脸识别我所做的代码实现(Matlab)。虽然说目前绝大部分都是用深度学习来做人脸识别,而且效果一骑绝尘,但是某些特定条件下(比如小样本)传统方法依然是值得大家...
  • 利用Prewitte算子将人脸图像转换成特征图像以保护更多的局部信息,并将特征图像划分为多个区域特征向量表示人脸,通过调整二次直方图距离中的权系数矩阵以降低干扰因素的影响,利用改进的距离测度计算特征图像间的...
  • 稀疏表示的本质就是稀疏正规化约束下的信号分解。提出一种改进的正交匹配追踪算法,使运算量较高的矩阵...将此算法应用于稀疏表示人脸识别,探讨并验证了稀疏阀值的设置和训练字典的选择对人脸识别率和识别速度的影响。
  • 具体而言,通过引入字典学习的对偶形式,表示了基向量与原始图像特征之间的明确关系,这也增强了可解释性。 因此,可以将SRC或CRC视为所提出算法的特殊情况。 然后采用逐块坐标下降算法和拉格朗日乘数来优化相应的...
  • 基于支持向量机(SVM)的人脸识别

    万次阅读 多人点赞 2016-05-06 10:47:07
    本博客包含本人学习SVM和PCA的笔记,简要的说明其原理和方法步奏,人脸识别程序的解释说明,一并奉上完整的Matlab代码和相关的学习资料。感觉自己在这上面花了不少时间但停留在一个较浅层次的了解上,希望后面学习...
  • SR(稀疏表示人脸识别

    千次阅读 2018-01-10 15:14:29
    稀疏表示的实现例子:https://www.cnblogs.com/denny402/p/5016530.html 思路分析: (大概率不对) 1、利用PCA得到的特征向量做字典 2、取训练集乘以该特征向量,得到在字典空间下的系数 3、测试集乘以该...
  • 基于多类最大散度差的人脸表示方法rar,最大散度差 Fisher鉴别准则 特征向量 特征提取 人脸识别
  • VAE网络一个特性是会把人脸编码成一个含有200个分量的向量,反过来说在特定分布范围内的含有200个分量的向量就对应一张人脸。由于向量之间可以进行运算,这就意味着我们把两张不同人脸A,B分布转换成两个不同向量z_A,...
  • 首先对Retinex算法的不足进行改进,并应用于人脸图像预处理中,消除光照对人脸识别的干扰,然后采用稀疏表示提取人脸特征向量,并采用投票方式实现人脸识别,最后通过3个标准人脸数据库对方法的性能进行测试。...
  • (SRC)基于稀疏表示人脸识别

    千次阅读 2014-12-06 19:07:19
    本文主要记录自己在学习稀疏表示人脸识别中的应用所遇到的问题作一简单的总结。 1. 问题背景  信号的稀疏表示并不是新的东西。我们很早就一直在利用这一特性。例如,最简单的JPEG图像压缩算法。原始的...
  • 从产品经理角度如何看待人脸识别算法 大家都知道人脸识别算法是从深度学习发展起来后达到可以商用的水平,大家肯定也都听过卷积神经网络(CNN)的大名,那卷积神经网络究竟是啥玩意儿呢? 咱们去百度一下,看到了...
  • 支持向量机(SVM)算法应用——人脸识别

    千次阅读 多人点赞 2018-07-26 11:34:49
    # 当import 一个模块比如如下模块cross_validation时,会有删除横线,表示该模块在当前版本可能已经被删除,在新版本中改为model_selection模块 # DeprecationWarning: This module was deprecated in version 0.18...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,338
精华内容 7,335
关键字:

向量表示人脸