利用PCA进行人脸特征降维提取,手把手实现(代码不能运行你捶我!!!)-- Python, Sklearn, numpy

        还记得前几天我们进行了PCA原理的讲解吗?本来在原理上应该没有太多问题,但是选择的案例貌似有点太抽象了。因此,这里我从对人脸数据进行降维与特征提取作为例子,重新写了一段代码,意在帮助大家更好了解PCA。这里附上链接和邮箱.

email:yuhan.huang@whu.edu.cn

源代码ipynb,强烈推荐看这个icon-default.png?t=O83Ahttps://github.com/pilipala5/sklearn/blob/master/code/7_InformationInPCA.ipynb

PCA原理与基本实现icon-default.png?t=O83Ahttps://blog.csdn.net/m0_62716099/article/details/141813685

背景

        至于为什么用这个例子呢?那自然是拥有其具体意义的。比如,如果我需要对于一个位图进行聚类分析。那么我当然是需要用到一个图像中的尽可能多的数据信息。但是一个栅格图像,其数据量是非常大的。在你的代码没有非常好的优化(或者使用比较好的分布式计算)的话,运行自然是非常慢。

        我举个例子吧。如果对于100个点数据进行聚类分析,那么就是100 * 2 = 200个数据,但是如果是100个 28 * 28的图像呢? 那么就是 100 * 28 * 28 * 波段数。这个时间损耗显然就陡然增加上去了。这个时候如果我利用PCA降维,把28 * 28 * 波段数的维度降下来,降到 3 或者 5,那么是不是就很好进行计算了呢? 这就是PCA在这种问题的意义所在。当然其应用情景很多,想到了的同学也可以发在评论区进行补充说明。

代码实现

        首先我们当然需要导入所需要的包。这里我们对于数据进行简单的解释说明,我们利用的是sklearn本身所存储的数据集fetch_olivetti_faces,里面有400张图像,每一张图像一个波段,大小为64 * 64。这里我们只进行特征的降维,并从图像的角度进行一下简单的分析。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.datasets import fetch_olivetti_faces

        然后我们导入数据集,由于我们只进行降维,所以其中的标签数据我们并不需要太多考虑。这里需要注意,导入的数据集是字典的形式,'data'是(400, 4096)格式的数据,而'images'是(400, 64, 64)形状。有相关经验的同学一下就明白了,data就是把images展平了!在降维的时候,受到sklearn中PCA函数规范要求的影响,我们用data数据进行降维,然后重新把形状设为(64, 64)

faces = fetch_olivetti_faces(data_home='./Data/OlivettiFaces')
data = faces.data   # (400, 4096)
imgs = faces.images # (400, 64, 64) -> 64 * 64 = 4096

        然后我们大概保留50%的信息,并对PCA模型进行拟合。并打印出信息量,看是否吻合。这里看不懂的去看一下PCA的官方文档吧。真的很建议。

        哦,额外说一句,n_components这个参数设置为[0, 1]之间的小数的话,就是代表信息量的比例,经验所谈,svd_solver在这个时候最好设置为"full"

        这里我打印出来的结果是0.5077,满足我的要求。

pca = PCA(n_components=0.5, svd_solver="full")  # save 50% information
pca.fit(data)
print(sum(pca.explained_variance_ratio_))

        然后我们把照片打印出来对比着看一下哈。

# show origin imgs and processed imgs(number = 5)
data = data[:5, :]  # (5, 4096)

pca_data = pca.transform(data) # (5, 4)
pca_imgs = pca.inverse_transform(pca_data) # (5, 4096)

_, axs = plt.subplots(2, 5, figsize=(8, 4))
for i, (img, pca_img) in enumerate(zip(data, pca_imgs)):
    axs[0, i].imshow(img.reshape([64, 64]), cmap='grey'); axs[1, i].imshow(pca_img.reshape([64, 64]), cmap='grey') 

        结果如图所示:

        我们明显可以看见,经历PCA降维后再逆转恢复的特征数据,也存在明显的模糊,这是说明PCA的信息损失是不可逆的!而其这种模糊的操作也很想低通滤波,可以将噪声点过滤出去,因此如果我们需要进行噪声点的去除,也可以考虑进行PCA降维后,再进行逆转换

        此外再进行额外的分析,我们可以看见PCA降维后逆转的人脸,眼部特征几乎没有损失。这说明人脸识别中眼部特征是最重要的。这也与我们日常生活相符合。目前大多数的人脸检测技术还是依靠的是眼部虹膜识别。

------------------------------------------------------------------------------------------------------------   分割线 :)

        再额外提一嘴,我们可以看一下PCA中特征矩阵(4, 4096)的可视化。

V = pca.components_
for i in range(V.shape[0]):
    plt.subplot(1, V.shape[0], i+1); plt.imshow(V[i].reshape([64, 64]), cmap='grey')

        这里有的同学可能疑惑,这四个图像分别代表什么?

        我是这么理解的,这个V的形状是(4, 4096), 而我们原本的特征F是(400, 4096),因此,在变换降维的过程中,实际的矩阵运算就是 F @ V.T,我觉得可以理解成两个向量之间的相关性吧。就计算出了四个最典型的脸部特征,并把原来的脸部特征和这四个特征进行比对,得到4个值。

        我是这么理解的,这个真的只是我自己的思考,若有不同的见解,欢迎交流讨论~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

香蕉也是布拉拉

随缘打赏不强求~ 谢谢大家

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值