一个不太专业的实践分享:从面部图像猜专业

点击上方关注,All in AI中国

几个月前,我读了一篇题为“深度神经网络比人类更准确地检测面部图像的性取向”的论文,引起了很多争议。虽然我不想评论论文的方法和质量(已经完成,例如在Jeremy Howard的一篇文章中),但我发现它其实非常有趣。简而言之,研究人员从约会网站收集了面部图片,并建立了一个机器学习模型来对人们的性取向进行分类,并且他们的方法达到了相当令人印象深刻的准确性。

这篇文章总结了以下结果:

人工智能分辨不出你是不是同性恋...但它可以告诉你,你的行走的印象。

事实上,我们经常看到那些看起来非常“刻板”的人。我尝试了更多这样的场景,并得出结论,另一个经常发现这种现象的环境是大学校园。你去校园逛逛,看看学生,他们身上呈现出来的“印象”是不同的,有的像是一个法学院学生,有的像一个计算机科学书呆子,有的像一个运动员等。有时我很好奇,甚至想冲上去问问他们我的假设是否正确。

在阅读了上述论文之后,我想知道某些机器学习模型是否能够量化这些潜在的假设,并找出一个看起来刻板的学生的专业。

虽然我在机器学习方面只有一点基础知识,特别是在使用深度神经网络的图像分类方面,但我把构建一个根据学者面部图像分辨他们的专业的分类器作为我的一个个人的挑战。

请不要认真对待这篇文章。我不是机器学习专家或专业科学家。我的方法或实施可能存在一些错误。但是,我很想听听您的想法和反馈。

途径

我的第一个(也是最后一个)方法是(1.)收集学生或其他学者的面部图片,(2)根据他们的专业给他们贴上有限的班级标签,最终(3.)使用卷积神经网络(CNN)作为分类器。我想到了研究领域,他们的学生可能看起来有点刻板,并提出了四个课程:

  • 计算机科学(~cs)
  • 经济学(〜经济学)
  • (德语)语言学(〜德语)
  • 机械工程(〜机械)

获取数据

第一个先决条件是训练数据 - 像往常一样,在进行机器学习时。因为我的目标是训练卷积神经网络(CNN),所以应该有很多数据。

虽然在我的校园里走动并向学生询问他们的专业和他们的脸部图片会是一个很有趣的方法,但我可能不会得到大量的数据。相反,我决定从大学网站抓取图片。几乎每所大学的每个部门都在其网站上有一个名为“工作人员”,“人员”,“研究人员”等的页面。这些一般并不是学生,通常是教授、研究助理和博士候选人的特别名单,我认为这些图片作为训练数据足以。

我使用Python和Selenium WebDriver编写了一堆爬虫脚本来抓取57个不同的网站,包括以下大学各部门的网站:

  • 卡尔斯鲁厄理工学院
  • 慕尼黑大学
  • 慕尼黑大学
  • 维尔茨堡大学
  • 锡根大学
  • 拜罗伊特大学
  • 费伯大学
  • 海德堡大学
  • 埃尔兰根大学
  • 班贝格大学
  • 曼海姆大学

经过一些手动数据清理(删除没有面部的图片)后,我最终得到了来自四个不同类别的1369个标记图像。虽然这不是用于训练CNN的数据,但我决定尝试一下。

例子

图片

摘录后包含所有原始图像的文件夹的摘录:

一个不太专业的实践分享:从面部图像猜专业

标签

index.csv的摘录,包含每个图像的标签和元数据:

一个不太专业的实践分享:从面部图像猜专业

预处理数据

在将图像用作学习算法的训练数据之前,需要应用一些预处理。主要是,我做了两个主要的预处理步骤。

  1. 将图像裁剪为面部 - 如您所见,图像是从不同的角度拍摄的,其中一些包含大量背景,有一些不居中等。为了获得更好的训练数据,图片必须仅裁剪为面部和没有其他的。
  2. 缩放 - 所有图片都有不同的分辨率,但最终需要具有完全相同的大小才能用作神经网络的输入。

为了实现这两个预处理步骤,我使用了一个很棒的,开源的,基于OpenCV的Python工具,名为autocrop,使用以下命令:

autocrop -i raw -o preprocessed -w 128 -H 128 > autocrop.log

这将检测原始文件夹中每张图片中的面部,将图片裁剪到该面部,将生成的图像重新缩放为128 x 128像素,并将其保存到预处理文件夹。当然,有些图片中的算法无法检测到脸部。这些都被记录到stdout并持久保存到autocrop.log。

另外,我写了一个解析自动裁剪的脚本。日志获取失败的图像,然后将图像分成训练(70%)、测试(20%)和验证(10%)并将它们复制到兼容的文件夹结构中到Keras ImageDataGenerator读取训练数据所需的格式。

一个不太专业的实践分享:从面部图像猜专业

建立模型

代码

custom_model.ipynb(https://muetsch.io/html/custom_model.html)

我决定从简单开始,看看是否可以从数据中学到任何东西。 我在Keras中定义了以下简单的CNN架构:

一个不太专业的实践分享:从面部图像猜专业

我使用Keras的ImageDataGenerator(很棒的工具!)将图像读入NumPy数组,将它们重新缩放为(64,63,3)(64 x 64像素,RGB)的形状,并使用旋转等变换执行一些数据增强、缩放、水平翻转等,以扩大我的训练数据,并希望建立更强大、更少过度装配的模型。

我让模型训练了100个epoch,使用具有默认参数和分类交叉熵损失的Adam优化器,32和3x增量的批处理大小(使用转换将训练数据放大三倍)。

结果(准确率为57.1%)

在74个epoch之后达到0.66的最大验证准确度。测试精度为0.571。考虑到一个非常简单的模型是从头开始训练的,只有不到1000个训练样例,我对这个结果印象深刻。这意味着该模型平均每秒钟都能准确预测学生的专业。正确分类的先验概率为0.25,因此该模型至少可以学到一些东西。

方法2:微调VGGFace

代码

vggfaces_bottleneck_model.ipynb(https://muetsch.io/html/vggfaces_bottleneck_model.html)

faces_finetuned_model.ipynb(https://muetsch.io/html/vggfaces_finetuned_model.html)

作为从头开始训练的简单定制CNN模型的替代方案,我希望遵循微调现有预训练模型权重的常用方法。这种方法的基本思想是不要“重新发明轮子”,而是利用之前已经学到的东西,只是稍微使“知识”(以权重的形式)适应某个问题。图像中的潜在特征(学习算法之前已经从一大组训练数据中提取出来)可以被利用。 “使用Keras中预先训练的模型进行图像分类”可以很好地概述微调的工作原理以及它与传递学习和自定义模型的区别。期望是我的给定分类问题可以用更少的数据更准确地解决。

我决定采用以VGGFace为基础训练的VGG16模型架构(使用keras-vggface实现)并按照本指南对其进行微调。 VGGFace是牛津大学出版的数据集,包含超过330万张面部图像。因此,我预计它会提取非常强大的面部特征,非常适合面部分类。

第1步:迁移学习以初始化权重

我的实现包括两个步骤,因为建议这样做

为了进行微调,所有层都应该从训练有素的权重开始。

在第一步中,迁移学习用于为一组新添加的、定制的、完全连接的分类层找到适当的权重。这些在稍后的步骤2中用作初始权重。为了执行此初始化,使用预先训练的VGGFace模型,其中最终分类层被切除,用于为每个图像提取128个瓶颈特征。随后,另一个由完全连接的层组成的微小模型在这些特征上进行训练,以执行最终分类。权重将持久保存到文件中,并在步骤2中再次加载。

模型架构如下所示:

一个不太专业的实践分享:从面部图像猜专业

第2步:微调

在第二步中,预训练的VGGFace模型(第一层n - 3层冻结)与步骤1中预训练的顶层组合使用,以微调我们特定分类任务的权重。它采用小批量(128,128,3)形张量(128 x 128像素,RGB)作为输入,并预测我们四个目标类别中的每一个的概率。

组合模型的体系架构如下所示:

一个不太专业的实践分享:从面部图像猜专业

top是步骤1中描述的模型,vggface_vgg16是VGG16模型,如下所示:

一个不太专业的实践分享:从面部图像猜专业

我再次使用Keras ImageDataGenerator来加载数据,扩充(3x)并调整其大小。按照建议、随机梯度下降使用较小的学习率(10 ^ -4)来仔细调整权重。该模型在32个图像的批次上训练了100个epoch,并且再次使用分类交叉熵作为损失函数。

结果(准确率为54.6%)

在38个epoch之后,达到了0.64的最大验证准确度。测试精度为0.546,这是一个非常令人失望的结果,考虑到即使我们简单的定制CNN模型也能达到更高的精度。也许模型的复杂性对于少量的训练数据来说太高了?

检查模型

为了更好地了解模型的表现,我简要地检查了几个标准。这是我的发现的简短摘要。

代码

  • inspection.ipynb(https://muetsch.io/html/inspection.html)

类分配

我看到的第一件事是类分布。四个研究主要科目如何在我们的数据中表示,模型预测了什么?

一个不太专业的实践分享:从面部图像猜专业

显然,该模型略微忽略了德语语言学家的类别。这也是我们训练数据最少的类。可能我应该收集的更多。

虚假分类的例子

我想知道这个模型做错了什么,做对了什么。因此,我看了顶部(关于信心)五(1)个假阴性,(2)假阳性和(3)真阳性。

以下是经济分类的摘录:

一个不太专业的实践分享:从面部图像猜专业

第一行显示了经济学家的例子,模型并没有认识到这一点。中间一行描述了模型“认为”经济学家的样子,但实际上是具有不同专业的学生/研究人员的例子。

最后,底行显示了良好匹配的示例,即模型对其实际类别具有很高置信度的人员。

混淆矩阵

为了查看模型不确定的职业,我计算了混淆矩阵。

一个不太专业的实践分享:从面部图像猜专业

一个不太专业的实践分享:从面部图像猜专业

传说:

  • 0 = cs,1 = econ,2 =德国,3 =机械
  • 更亮的颜色〜更高的价值

我们可以从混淆矩阵中读到的是,例如,该模型倾向于将经济学家经常归类为机械工程师。

结论

首先,这不是一项科学研究,而是我的一个小型业余爱好项目。此外,它没有很多现实世界的重要性,因为人们可能很少只将学生分为四类。

虽然结果不是很壮观,但我仍然对它们感到非常高兴,至少我的模型能够比随机猜测做得更好。鉴于四个班级的准确率为57%,你可以肯定地说,在某种程度上,只能从他们的脸部形象中学习一个看起来典型的人的学习专业。当然,这只能在有限的背景下和一系列的限制范围内成立,但对我来说仍然是一个有趣的见解。

此外,我很确定该模型仍有很大的改进空间,可以产生更好的性能。这可能包括:

  • 来自更广泛来源的更多训练数据
  • 更彻底的预处理(例如过滤掉秘书的图像)
  • 不同的模型架构
  • 超参数调整
  • 手动特征工程
  • ...

来源:https://towardsdatascience.com/detecting-academics-major-from-facial-images-58cf33d6f284

一个不太专业的实践分享:从面部图像猜专业

相关推荐