PCA+SVM人脸识别

本例子来自sklearn的demo,我自己在运行demo时候遇到点麻烦,故阅读了下源码,在此总结一些知识点。

首先要说明的是如果自己有先下载好的lfw人脸数据集,那么需要将人脸数据集放在lfw_home路径下,这也是因为datasets.fetch_lfw_people在加载数据集的源码的一个小瑕疵。如下图:
这里写图片描述

PCA+SVM实现人脸识别

PCA主要是通过奇异值分解将数据映射到低纬度的空间(正交去相关)。PCA在数据降维,数据压缩,特征提取有很大贡献。在此,我们利用PCA提取150个主要特征,并将人脸数据全部映射到150维度,通过这150维人脸特征作为训练数据训练基于rbf kernel的SVM,模型差不多有0.85的准确率。

datasets.fetch_lfw_people源码阅读笔记

fetch_lfw_people这个函数是用来加载lfw人脸识别数据集的函数,返回data,images,target,target_names.分别是向量化的人脸数据,人脸,人脸对应的人名编号,人名。

def fetch_lfw_people(data_home=None, funneled=True, resize=0.5,
                     min_faces_per_person=0, color=False,
                     slice_=(slice(70, 195), slice(78, 172)),
                     download_if_missing=True):
    """Loader for the Labeled Faces in the Wild (LFW) people dataset

    This dataset is a collection of JPEG pictures of famous people
    collected on the internet, all details are available on the
    official website:

        http://vis-www.cs.umass.edu/lfw/

    Each picture is centered on a single face. Each pixel of each channel
    (color in RGB) is encoded by a float in range 0.0 - 1.0.

    The task is called Face Recognition (or Identification): given the
    picture of a face, find the name of the person given a training set
    (gallery).

    The original images are 250 x 250 pixels, but the default slice and resize
    arguments reduce them to 62 x 74.

    Parameters
    ----------
    data_home : optional, default: None
        Specify another download and cache folder for the datasets. By default
        all scikit learn data is stored in '~/scikit_learn_data' subfolders.

    funneled : boolean, optional, default: True
        Download and use the funneled variant of the dataset.

    resize : float, optional, default 0.5
        Ratio used to resize the each face picture.

    min_faces_per_person : int, optional, default None
        The extracted dataset will only retain pictures of people that have at
        least `min_faces_per_person` different pictures.

    color : boolean, optional, default False
        Keep the 3 RGB channels instead of averaging them to a single
        gray level channel. If color is True the shape of the data has
        one more dimension than the shape with color = False.

    slice_ : optional
        Provide a custom 2D slice (height, width) to extract the
        'interesting' part of the jpeg files and avoid use statistical
        correlation from the background

    download_if_missing : optional, True by default
        If False, raise a IOError if the data is not locally available
        instead of trying to download the data from the source site.

    Returns
    -------
    dataset : dict-like object with the following attributes:

    dataset.data : numpy array of shape (13233, 2914)
        Each row corresponds to a ravelled face image of original size 62 x 47
        pixels. Changing the ``slice_`` or resize parameters will change the
        shape of the output.

    dataset.images : numpy array of shape (13233, 62, 47)
        Each row is a face image corresponding to one of the 5749 people in
        the dataset. Changing the ``slice_`` or resize parameters will change
        the shape of the output.

    dataset.target : numpy array of shape (13233,)
        Labels associated to each face image. Those labels range from 0-5748
        and correspond to the person IDs.

    dataset.DESCR : string
        Description of the Labeled Faces in the Wild (LFW) dataset.
    """

以上是fetch_lfw_people函数的主要参数,有人脸数据集的路径(若没有,会自动下载保存),每个人对应的最小人脸数,切片参数,缩放比例等等。

这里写图片描述
上图为lfw.py的主要用到的方法
fetch_lfw_people主要的实现思路如下:

1、获取人脸数据集的文件路径,其中check_fetch_lfw函数完成此功能。check_fetch_lfw函数会根据给定的路径判断路径下是否有人脸数据集,若有,返回数据集路径,若没有,那么他会从网上下载,然后自动解压,将解压后的路径返回,并且将压缩包删除。

知识点:os.join,合并路径
用Logger输出日志
用raise 输出异常
用tarfile解压文件

2、 获取人名信息target_names,人名对应的人脸信息faces,target,首先看一下人脸数据集的结构

这里写图片描述这里写图片描述
由上图可以看出lfw_funneled文件夹下包含以人名来命名的文件夹,每个人名的文件夹下都是他的人脸信息。这样的结构化的信息是非常友好的。在这儿_fetch_lfw_people函数负责加载人脸数据集合人脸对应的人名信息。

person_names, file_paths = [], []   #人名集合和人脸图片路径
# 将每个人名文件下的人脸图片路径保存到paths
    for person_name in sorted(listdir(data_folder_path)):
        folder_path = join(data_folder_path, person_name)
        if not isdir(folder_path):
            continue
        paths = [join(folder_path, f) for f in listdir(folder_path)]
        n_pictures = len(paths)
        if n_pictures >= min_faces_per_person:
            person_name = person_name.replace('_', ' ')
            # 这儿用extend是因为extend可以一次性添加多个元素,append一次只能添加一个
            person_names.extend([person_name] * n_pictures)
            file_paths.extend(paths)

    n_faces = len(file_paths)
    if n_faces == 0:
        raise ValueError("min_faces_per_person=%d is too restrictive" %
                         min_faces_per_person)
    # 通过unique函数得到所有不同人名
    target_names = np.unique(person_names)
    # searchsorted是寻求插入位置的函数,在这儿巧妙的将person_names数字化,target代表person_names中每各名字在target_names的位置
    target = np.searchsorted(target_names, person_names)
    # 加载人脸,slice_是对人脸切片,lolor用来指定加载彩色还是黑白图片,resize为缩放比例
    faces = _load_imgs(file_paths, slice_, color, resize)

    # shuffle the faces with a deterministic RNG scheme to avoid having
    # all faces of the same person in a row, as it would break some
    # cross validation and learning algorithms such as SGD and online
    # k-means that make an IID assumption
    # 这儿就是打乱人脸顺序的工作了
    indices = np.arange(n_faces)
    np.random.RandomState(42).shuffle(indices)
    faces, target = faces[indices], target[indices]
    return faces, target, target_names

知识点:注释地方都是
以上源码非常精简高效,很值得学习。

加载图片_load_imgs

_load_imgs要说的不多,主要是作者在考虑到py兼容问题时候考虑的很细致

# Try to import imread and imresize from PIL. We do this here to prevent
    # the whole sklearn.datasets module from depending on PIL.
    try:
        try:
            from scipy.misc import imread
        except ImportError:
            from scipy.misc.pilutil import imread
        from scipy.misc import imresize
    except ImportError:
        raise ImportError("The Python Imaging Library (PIL)"
                          " is required to load data from jpeg files")

接下来就是根据slice数据对图片切片,然后在resize

特征脸可视化

挑选了前11个主要特征脸,可视化效果图如下:
这里写图片描述

参考文献:http://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html
http://scikit-learn.org/stable/auto_examples/applications/face_recognition.html#sphx-glr-auto-examples-applications-face-recognition-py

  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
人脸识别是一项典型的模式识别任务,PCA+SVM是其中一种常用的方法,下面是一个简单的PCA+SVM人脸识别程序的示例: 1. 数据集准备 首先需要准备一个人脸数据集,一般包括训练集和测试集,每个样本都是一个人的人脸图像。可以使用公开数据集如AT&T人脸数据集、LFW人脸数据集等。 2. 特征提取 对于每个人脸图像,需要提取出其特征向量。PCA(Principal Component Analysis)是一种常用的特征提取方法,可以将高维的图像数据转换为低维的特征向量。具体步骤如下: (1)将所有训练样本按列组成一个矩阵X; (2)对X进行中心化处理,即将每一列都减去其均值; (3)对中心化后的X求协方差矩阵C; (4)对C进行特征值分解,得到特征值和特征向量; (5)选择前k个特征向量组成投影矩阵W; (6)对每个样本进行投影,得到其k维特征向量。 3. 训练模型 使用SVM(Support Vector Machine)作为分类器,对训练集进行分类器训练。SVM是一种二分类模型,可以将多分类问题转化为多个二分类问题。具体步骤如下: (1)将每个样本的特征向量和标签组成训练数据; (2)使用训练数据训练SVM分类器。 4. 测试模型 使用测试集对训练好的模型进行测试,计算分类准确率。 5. 代码实现 以下是一个简单的PCA+SVM人脸识别程序的Python实现代码: ``` python import numpy as np from sklearn.decomposition import PCA from sklearn.svm import SVC # 加载训练集和测试集 train_data = np.load('train_data.npy') train_label = np.load('train_label.npy') test_data = np.load('test_data.npy') test_label = np.load('test_label.npy') # 特征提取:使用PCA将图像数据转换为特征向量 pca = PCA(n_components=100) train_feature = pca.fit_transform(train_data) test_feature = pca.transform(test_data) # 训练模型:使用SVM进行分类器训练 svm = SVC(kernel='rbf', C=1, gamma='scale') svm.fit(train_feature, train_label) # 测试模型:使用测试集进行预测 predict_label = svm.predict(test_feature) accuracy = np.mean(predict_label == test_label) print('Accuracy:', accuracy) ``` 上述代码中,train_data和test_data分别是训练集和测试集的图像数据,train_label和test_label分别是训练集和测试集的标签,即对应的人脸ID。PCA的n_components参数设为100表示将图像数据转换为100维的特征向量。SVM的kernel设置为rbf表示使用高斯核函数,C为惩罚参数,gamma为核函数参数。最后计算分类准确率并输出。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值