这篇博客是对技术研究任务的记录,当时真的是一头雾水,那是刚开始接触机器学习,博客内容是我将研究报告的内容做简单复制粘贴后仍上来的,这个实现是参考一个外国机器学习网站的demo做的功能添加和修改
(原始链接在此 https://www.pyimagesearch.com/2018/07/09/face-clustering-with-python/)感谢其提供了实现聚类的方向
(你也可以参考此链接 http://www.atyun.com/23521.html)
正文
机器学习处理的问题我们可以概括为分类问题和回归问题,这两个都属于监督学习(在大量的已知实例中得到泛化的能力),人脸聚类属于无监督的学习,也就是我们一开始并不知道我们的人脸集中的任何信息(比如有多少个人的人脸,我需要按照什么标准对这些人脸进行区分等等)。实现人脸聚类的大概思路就是,想方法将人脸图片进行编码,将像素点组成的一张图片转变成一个多维的张量(比如矩阵就是个2D张量,或者叫做二维的张量),由于我们得到的张量是根据人脸图片的像素得来的,所以张量中就隐藏着这张人脸的特征信息,接下来,我们采用某个算法(我们使用DBSCAN算法)去将多维中分布的这些点临近的当做一类,以此得到人脸的聚类。简单概括来说,就是两个过程,编码和分类。
在对人脸进行编码时,我们要考虑到一点——一张图片中人脸只是其中一个部分,照我们的聚类实现方式来看,我们应该更关心一张图片中人脸部分的特征,多余的部分(比如衣服,背景等等)将会影响我们的特征提取,因此,我们应该在对图片编码时先识别人脸在图片中的位置,再进行编码时只对人脸部分进行编码(如下图),这样将提高我们的聚类性能。
实现细节
主要说下两部分,一个是人脸识别,一个是聚类算法,先看人脸识别。在人脸识别这块,采用的是python开源的人脸识别库face_recognition,在这里我将进行说明的是,人脸识别是在整个聚类过程中最耗时的部分,尤其是采用CNN进行人脸识别时。当然我们可以跳过人脸识别,而直接对图片进行编码,但是此时,图片中的无关因素将对结果产生巨大影响。
聚类
采用的是scikit-learn库搭建机器学习应用,在该库中,有三种常用的聚类算法,他们分别是K均值聚类、凝聚聚类、DBSCAN。(更多参见https://scikit-learn.org/stable/modules/clustering.html#clustering)
三者都是无监督的聚类算法,但是K均值聚类、凝聚聚类需要我们提供分类的最终类别个数,DBSCAN则不需要提供,但是可以通过调节参数来大概的控制最终的类别个数
特征数据保存
利用python的pickle库,将得到的序列信息保存到文件,我们将采用字典的形式,将每张人脸图片的特征张量和人脸图片路径对应,同时实现不同特征文件之间的结合,从而避免多次的人脸识别和编码过程
对原始图片的操作
程序运行的大量时间都在进行人脸识别(对于一张1024768的图片,若是彩色,则有1024769*3=2,359,296个数需要处理,同时卷积神经网络同时有多个卷积层池化层等等)。所以适当的降低图片分辨率将可以加快程序执行速度(最好是有GPU加持,速度将大大大提高)。所以我们可以考虑在适当范围内降低图片分辨率,来提高速度