深度神经网络帮您解析SNH48成员公式照背后的故事

1,238 阅读8分钟
原文链接: zhuanlan.zhihu.com

Overview

距离上一次我不务正业的文章 【面对塞纳河编程】SNH48 Group第一届人口普查 已经过去了将近半年了。虽然最近很忙,但是还是忍不住想要用知识来搞一些事情。最近一直在做深度学习有关的项目,一直有想法想做一点深度学习 X SNH48 的事情。这次花了一个下午加晚上的时间,我们搞事情的目标对准了SNH48成员的公式照。

众所周知,深度神经网络在图像,自然语言处理上都有很出色的表现。其中在图像方面,通过卷积神经网络,可以有效地提取图像的特征,这些特征可以帮助我们搭建分类模型,或者寻找类似的图片。因此,我们搞事情的思路就是将SNH48成员的照片通过一个已经训练好的深度神经网络,获得成员们的面部特征,看看哪些成员在神经网络看来是长的相似的,又有哪些CP拥有惊人的CP相。

照例,我会先说一些技术方面的细节,对相关领域不是太了解以及想直接看结果的聚聚可以跳到最后的结果分析部分。划重点: 结果在文章最后!

数据获取

成员的公式照全部来自官网。收录了大重组之后Team SII, NII, HII, X 以及部分Team 预备生成员, 共87张公式照。有一些预备生因为时间原因没有整理收入,如果之后有时间我会再加上。

OpenFace

原本想自己搭建一个模型对成员的照片进行训练,但是时间有限,数据的收集也不是很简单的工作。正好前几天发现了CMU的一个图像机器学习项目:OpenFace。OpenFace是一个Python和Torch实现的深度神经网络面部识别项目,其中包含了人脸发现,特征提取,特征神经网络训练,人脸识别这四个功能。

OpenFace的基本框架如下图所示

Python主要负责实现图像的预处理。预处理包括了人脸检查,转换以及剪切,具体的过程如下图所示。OpenFace主要还是运用的是传统的机器视觉的方法,如dlib的人脸发现。

神经网络通过Torch,网络结构和Google的FaceNet结构相同。因为最后我们的目的不是训练分类模型,因此我们关注的重点主要还是在前两个功能,即人脸发现和特征提取。

OpenFace官方推荐使用docker进行安装(首先确保你已经安装了docker)

docker pull bamos/openface

安装结束以后创建一个容器

docker run -p 9000:9000 -p 8000:8000 -t -i bamos/openface /bin/bash 

接着进入OpenFace的根目录

cd /root/openface 

首先我们先创建一个存放训练数据的文件夹

mkdir training-data

然后将收集的成员公式照放到这个目录中,因为我不太熟悉docker的操作,这里我用的是

docker cp PATH/training-data/ yourcontainer:/root/openface/training-data/

其中PATH是训练数据在电脑上的路径,yourcontainer对应的是容器名称。好啦,数据准备好,接下来我们就可以开始愉快地训练啦。首先第一步是人脸检测和位置校正

./util/align-dlib.py ./training-data/ align outerEyesAndNose ./aligned-faces/ --size 96

处理完的人脸会存放在/aligned-faces/ 这个文件夹中。我们可以挑选一个成员来看看处理前后是什么样子

处理的目的主要是抠出人脸,并且将五官矫正到大致一致的位置。最后就可以来提取人脸的特征。

./batch-represent/main.lua -outDir ./generated-embeddings/ -data ./aligned-faces/

所有特征提取完毕后会存放在./generated-embeddings/ 下,reps.csv存放特征,labels.csv存放着对应的特征。从之前介绍的OpenFace的神经网络结构可以知道,最后我们获得的是一个128维的特征。有了这些特征就可以来看看成员公式照之间有着怎样的联系了。

结果分析

神经网络输出的特征的128维,即特征的向量空间是128维。在这里我们通过计算任意两个点之间的欧几里得距离来获得两张人脸的相似度,也就是说它们之间的欧几里得距离越小,两张照片越是相似。

从可视化来说,高维的数据观察起来并不是很直观。为了能够在二维的图像上展现结果,我们需要先将特征降维。常用的降维方法有PCA,t-SNE等等。因为在我们的特征空间中,我们比较关注的是不同点之间的距离,因此在这个问题我用了MDS(多维缩放)来降维。MDS能够在降维的过程中将数据的差异性保留下来,即降维让高维空间中的距离关系与低位空间中的距离关系保持不变。

因为一共有87位成员,在一张图上展示会显得比较拥挤,因此我分了不同队伍来展示公式照之间的相似性。首先我们来看组阁之后的S队

其中公式照最接近的居然是邵雪聪&孙芮,袁雨桢&刘增艳。来看看三哥和coco的公式照

Emm. 一言难尽。我还是不去评论深度智障网络的表现了。我们再来看看N队的吧

陆婷!!你看见了吗!!叉叉没有说错!!叉叉的话是有理论支持的!!你就是和张雨鑫长得像!!不要躲避这个赤裸裸的现实了!

下面是人员大调整的H队

源源和姜杉以及lyt紧紧地贴在了一条直线上。想写一本书《人工智障:从入门到放弃》。

最后是X队

X队没什么可说的。李晶和孙亚萍贴的这么近可能是因为身材吧。不对,我们好像只输入了公式照。emmm,也许这就是人工智能厉害的地方吧!

不过因为我们是将高维数据降维到二维必然会损失一些信息,二维的图像只能作为一个可视化的参考。我同时计算87位成员两两之间在高维空间的欧几里得距离,特此排出了公式照最像成员Top5

这里的Similarity对应的是欧氏距离,因此Similarity越小代表两张公式照越相近。刘炅然和江真仪居然是最像的,这倒也是大大出乎我的意料

看了两个人的公式照,正义在高P之下,某种程度上来说,两个人长的还真的是有点像。特别是笑容的这个角度,都有种蒙娜丽莎上身的感觉。

有最像排名,当然我们还有最不像的公式照排名

雨伞和孔姐,也确实不是一个风格的。不过鱼哥是咋了,和艾斯过不去了?小小婷和问言的差距,可能主要还是胶原蛋白之间的差距。

接着我们将所有公式照的特征向量做了一个平均,获得了一张SNH48成员公式照的平均脸。通过计算和平均脸之间的欧式距离,我们可以获得长相最平均的成员排名

momo荣登榜首!而且是压倒性的优势!果然成员们更多还是像momo这样温柔软萌的呢!

同时,我们还有长相和平均差异最大成员排名

最后最后,还有最刺激的。我带着非常主观的个人感情色彩,挑选了12对河内大热(我认为的)CP,算一算哪对CP最有CP相。

CP排行榜 揭晓如下!

看见了吗?看见了吗?马鹿!什么叫压倒性优势夺冠!马鹿gay,准备起飞。算了,这也算是日常操作了,坐下吧坐下吧。从这个角度来说,有些CP能火不是没有道理的。CP御三家哪一家不是在河内名噪一时。说到CP,我忍不住想夹带一点私货:朋友,九笨了解一下?

写在最后

写这篇文章纯属在花式赶Deadline之中的摸鱼娱乐,有很多地方从理论上来说还是不非常严谨,如果有错误的地方欢迎大家指正。和之前一样,输出的特征向量,成员之间相似度的表格,收集的公式照,以及我做数据处理和可视化的代码都放在了我的GitHub,如果有兴趣对这些数据再进行挖掘的,欢迎去fork一个玩玩,如果觉得有意思的,能给个Star就更好啦~ 地址在这里 GitHub:TheSuguser/SNH48facesimilarity

如果你有什么想要了解的,比如某两位成员之间的相似度,或者你觉得什么可以再挖掘的,欢迎在评论里告诉我!我会再更新在文章里的。就是这样!希望你看的愉快~

Reference

FaceNet: A Unified Embedding for Face Recognition and Clustering

OpenFace: A general-purpose face recognition library with mobile applications