机器学习系列(二十一)——PCA降噪与人脸识别

作者: Ice_spring | 来源:发表于2019-07-15 16:14 被阅读1次

    PCA实现降噪

    仍然以手写识别数据集为例,这次我们使用sklearn中小的手写数字数据集,并为数据集人工加入高斯噪音:

    from sklearn import datasets
    digits = datasets.load_digits()
    
    X = digits.data
    y = digits.target
    
    noisy_digits = X +np.random.normal(0,4,size=X.shape)
    

    接下来将这些加了噪音的数据图像绘制出来,为了可视化方便,0-9每个数字取10个样本,共绘制100个图像:

    '''0-9每个样本取10个'''
    example_digits = noisy_digits[y==0,:][:10]
    for num in range(1,10):
        X_num = noisy_digits[y==num,:][:10]
        example_digits = np.vstack([example_digits,X_num])
    
    '''手写数字数据可视化函数'''
    def plot_digits(data):
        fig, axes = plt.subplots(10,10,figsize=(10,10),
                                subplot_kw={'xticks':[],'yticks':[]},
                                gridspec_kw=dict(hspace=0.1,wspace=0.1))
        for i,ax in enumerate(axes.flat):
            ax.imshow(data[i].reshape(8,8),\
                     cmap='binary',interpolation='nearest',clim=(0,16))
        plt.show()
    
    plot_digits(example_digits)
    

    绘制结果如下:

    带噪声的数字可视化

    接下来对数据进行降噪,所谓降噪其实就是提取前k个比较重要的主成分,丢弃原数据集中部分信息而已:

    '''降噪'''
    pca = PCA(0.5)#目测噪音大,保留0.5信息
    pca.fit(noisy_digits)
    pca.n_components_ //out:12
    

    这里目测噪声很大,于是丢弃50%的信息,认为它们是噪音,此时数据为12维,再将数据还原为64维,得到的就是降噪之后的数据,并绘制降噪后的图像:

    '''去噪音后的特征数据'''
    X_components = pca.transform(example_digits)
    '''去噪音后恢复64维'''
    filtered_digits = pca.inverse_transform(X_components)
    plot_digits(filtered_digits)
    

    绘制结果如下:

    降噪后数字可视化

    可以看到,效果比之前好很多。实际中,要丢弃的信息量比例(噪音)要视情况而定,一般来说数据降噪后都会比未降噪的数据表现要好,但也不一定,有些性质较好的数据集降噪确实会损失有用信息。


    PCA与人脸识别

    在PCA的学习中我们知道,在PCA提取的主成分中,按重要性程度是依次递减的,如果对人脸数据提取主成分后,主成分的每一个向量叫做特征脸
    X= \begin{pmatrix} X_{1}^{(1)} , X_{2}^{(1)},...,X_{n}^{(1)}\\X_{1}^{(2)} ,X_{2}^{(2)},...,X_{n}^{(2)}\\...\\X_{1}^{(m)} , X_{2}^{(m)},...,X_{n}^{(m)} \end{pmatrix} , W_{k}= \begin{pmatrix} W_{1}^{(1)} , W_{2}^{(1)},...,W_{n}^{(1)}\\W_{1}^{(2)} ,W_{2}^{(2)},...,W_{n}^{(2)}\\...\\W_{1}^{(k)} , W_{2}^{(k)},...,W_{n}^{(k)} \end{pmatrix}

    上面的矩阵X是人脸数据集,Wk是主成分,为什么称Wk的每个向量为特征脸呢?以一个真实的人脸数据集来看一下:

    import numpy as np
    import matplotlib.pyplot as plt
    '''人脸识别数据'''
    from sklearn.datasets import fetch_lfw_people
    '''导入数据'''
    faces = fetch_lfw_people()
    faces.keys()
    

    第一次导入数据可能需要下载,而且速度比较慢,这里给出下载好的数据百度云链接,链接: https://pan.baidu.com/s/1MRdDrlFZBAll9svkekUDmg 提取码: 8m9p。下载后将文件拷贝到scikit_learn_data的lfw_home文件夹下即可。

    数据基本信息
    '''随机绘制36个脸'''
    random_indexes = np.random.permutation(len(faces.data))
    X = faces.data[random_indexes]
    example_faces = X[:36,:]
    '''绘图函数'''
    def plot_faces(faces):
        fig, axes = plt.subplots(6,6,figsize=(10,10),subplot_kw={'xticks':[],'yticks':[]},
                                gridspec_kw=dict(hspace=0.1,wspace=0.1))
        for i,ax in enumerate(axes.flat):
            ax.imshow(faces[i].reshape(62,47),cmap='bone')
        plt.show()
    plot_faces(example_faces)
    

    绘制结果:

    接下来进行PCA提取主成分并绘制这些主成分:

    from sklearn.decomposition import PCA
    pca = PCA(svd_solver='randomized')#由于数据多,随机方式求解PCA
    pca.fit(X)
    '''特征脸'''
    plot_faces(pca.components_[:36,:])
    

    绘制结果:

    特征脸

    这就是按照重要程度绘制出来的该数据集的人脸特征,其实也很好理解,人脸识别中第一重要的是人脸的基本轮廓,所以排在前面特征的和人脸轮廓有关,之后特征一步步细化到人脸的一些部位比如眼睛鼻子嘴巴等。一个真实的人脸可以看作这些特征的线性组合。
    关于人脸识别还有很多有意思的探索,有兴趣的可以自己在这个数据集上通过机器学习做更多探索。

    相关文章

      网友评论

        本文标题:机器学习系列(二十一)——PCA降噪与人脸识别

        本文链接:https://www.haomeiwen.com/subject/ljcnkctx.html