1. 首页 > 百货 > 包包服装

什么是最好的面部检测器

我正在处理的面部识别问题,需要选择一个面部检测模型。面部检测是面部识别流水线的第一步,准确识别图像中的面部至关重要。Garbage in, garbage out。

然而,众多的选项让我感到不知所措,而且关于这一主题的零散写作还不够详细,无法帮助我决定选择哪种模型。比较各种模型花费了我很多精力,因此我认为传达我的研究可能会帮助处于类似情况的人们。

面部检测器的选择要点是什么?

选择面部检测模型时的主要权衡是准确性和性能之间的平衡。但还有其他因素需要考虑。关于面部检测模型的大多数文章要么是模型创建者写的,通常发表在期刊上,要么是那些在代码中实现模型的人写的。在这两种情况下,作者自然会对他们所写的模型持有偏见。在一些极端情况下,这些文章实际上是该模型的宣传广告。

很少有文章比较不同模型的性能表现。进一步增加混乱的是,每当有人写关于像RetinaFace这样的模型时,他们讨论的是该模型的特定实现。模型本身实际上是神经网络架构,不同的实现可能会导致不同的结果。更复杂的是,这些模型的性能还取决于后处理参数,如置信度阈值、非极大值抑制等。

每个作者都将自己的模型描述为“最好”,但我很快意识到“最好”取决于上下文。没有客观上最好的模型。决定哪个面部检测模型最合适的两个主要标准是准确性和速度。

没有一个模型能同时具备高准确性和高速度,这是一个权衡。我们还必须查看原始准确性之外的指标,大多数基准测试基于原始准确性(正确猜测/总样本量),但原始准确性不是唯一需要关注的指标。假阳性与真阳性的比率以及假阴性与真阴性的比率也是重要的考虑因素。用技术术语来说,这种权衡是精度(最小化假阳性)和召回率(最小化假阴性)之间的权衡。这篇文章深入讨论了这个问题。

测试模型

有一些现有的用于基准测试的面部检测数据集,如WIDER FACE,但我总是喜欢看看这些模型在我的数据上表现如何。所以我随机选取了1064帧电视节目样本来测试这些模型(±3%的误差范围)。在手动标注每张图像时,我尽量选择尽可能多的面部,包括部分或几乎完全遮挡的面部,以给模型带来真正的挑战。因为我最终要对检测到的面部进行面部识别,所以我想测试每个模型的极限。

数据和标注可以从下面链接进行下载:

将各种模型分为两类是有帮助的;那些运行在GPU上的模型和那些运行在CPU上的模型。一般来说,如果你有兼容CUDA的GPU,应该使用基于GPU的模型。我有一个NVIDIA 1080 TI显卡,具有11GB内存,这使我能够使用一些大规模的模型。然而,我的项目规模巨大(我指的是成千上万的视频文件),所以对速度极快的基于CPU的模型很感兴趣。基于CPU的面部检测模型不多,所以我决定只测试最受欢迎的一个:YuNet。由于其速度,YuNet构成了我的基线比较。一个GPU模型必须比其CPU对应的模型准确得多,以证明其较慢的处理速度是合理的。

CPU模型

YuNet是为性能而开发的,其模型大小仅为较大模型的一小部分。例如,YuNet只有75,856个参数,而RetinaFace则有27,293,600个参数,这使得YuNet可以在“边缘”计算设备上运行,而这些设备不足以运行较大的模型。

作为一个CPU模型,YuNet的表现比我预期的要好得多。它能够毫无问题地检测到大面部,但在检测较小面部时有些困难。

能够检测到即使在斜角度的大面部。边界框有些偏差,可能是因为图像需要调整为300x300才能输入到模型中。

YuNet几乎找到了所有面部,但也包括了一些假阳性。

当限制为图像中的最大面部时,准确性大大提高。

如果性能是主要考虑因素,YuNet是一个很好的选择。它甚至足够快,可以用于实时应用,而GPU选项则不能(至少在没有一些严重硬件的情况下)。

YuNet使用固定的300x300输入尺寸,因此时间差异是由于将图像调整为这些尺寸导致的。GPU模型

Dlib是一个C++实现,带有Python包装器,保持了准确性、性能和便利性之间的平衡。Dlib可以直接通过Python安装,也可以通过Face Recognition Python库访问。然而,Dlib的准确性和性能在upsampling参数上有很强的权衡。当上采样次数设置为0时,模型速度更快但准确性较低。

无上采样

上采样=1

Dlib模型的准确性随着进一步的上采样而增加,但任何高于上采样=1的值都会导致我的脚本崩溃,因为它超出了我的GPU内存(顺便说一下,我的内存是11GB)。

Dlib的准确性相对于其(缺乏)速度来说有些令人失望。然而,它在最小化假阳性方面表现非常好,这是我的优先事项。面部检测是我面部识别流水线的第一部分,因此最小化假阳性数量将有助于减少下游的错误。为了进一步减少假阳性数量,我们可以使用Dlib的置信度输出来过滤低置信度的样本。

假阳性和真阳性之间的置信度差异很大,我们可以利用这一点来过滤前者。我们可以查看置信度分布来选择一个更精确的阈值,而不是选择一个任意的阈值。

95%的置信度值在0.78以上,因此排除低于该值的所有内容可以将假阳性数量减少一半。

虽然通过置信度过滤减少了假阳性数量,但并没有提高整体准确性。我会考虑在最小化假阳性数量是主要关注点时使用Dlib。但除此之外,Dlib在准确性上并没有比YuNet大幅增加,无法证明其更高的处理时间是合理的;至少对我的用途来说是这样。

OpenCV面部检测模型的主要吸引力在于其速度。然而,其准确性令人失望。虽然与其他GPU模型相比,它速度非常快,但即使是Top 1准确性也仅略好于YuNet的整体准确性。我不清楚在什么情况下我会选择OpenCV模型进行面部检测,尤其是因为它很难正常工作。

Pytorch-MCNN

MTCNN模型的表现也很差。尽管它的准确性略高于OpenCV模型,但速度要慢得多。由于其准确性低于YuNet,没有 compelling reason to select MTCNN。

RetinaFace

RetinaFace以其作为开源面部检测模型中最准确的声誉而闻名。测试结果支持了这一声誉。

它不仅是最准确的模型,而且许多“错误”实际上并不是实际错误。RetinaFace真的测试了“假阳性”这个类别,因为它检测到了一些我没有看到的面部,没有标注的因为我认为它们太难了,或者没有考虑是“面部”。

它在这张《Seinfeld》片段中的镜子中检测到了部分面部。

它在《Modern Family》的背景图像中找到了面部。

它在识别人脸方面如此出色,以至于找到了非人脸。

学习到RetinaFace并不算太慢是一个惊喜。虽然它不如YuNet或OpenCV快,但与MTCNN相当。虽然它在低分辨率下比MTCNN慢,但它扩展得相对较好,可以同样快速地处理更高分辨率。RetinaFace击败了Dlib(至少在需要上采样时)。它比YuNet慢得多,但准确性显著提高。

通过过滤掉较小的面部,可以排除RetinaFace识别的许多“假阳性”。如果我们删除最低四分位的面部,假阳性率会大幅下降。

最低四分位的边界是0.0035

虽然RetinaFace非常准确,但其错误确实有特定的偏差。虽然RetinaFace容易识别小面部,但它在检测较大、部分遮挡的面部时存在困难,这在查看面部尺寸相对于准确性时尤为明显。

这对我的用途来说可能是个问题,因为图像中面部的大小与其重要性密切相关。因此,RetinaFace可能会错过最重要的情况,例如以下示例。

RetinaFace未能检测到这张图像中的面部,但YuNet做到了。

结论

根据我的测试(我想强调这些测试并不是世界上最严格的测试;所以要保留一点怀疑态度),我只会考虑使用YuNet或RetinaFace,具体取决于我的主要关注点是速度还是准确性。可能在我绝对想要最小化假阳性数量时会考虑使用Dlib,但对于我的项目来说,只能选择YuNet或RetinaFace。

完整的项目代码在这里:

本网站的文章部分内容可能来源于网络和网友发布,仅供大家学习与参考,如有侵权,请联系站长进行删除处理,不代表本网站立场,转载者并注明出处:https://www.jmbhsh.com/baobaofuzhuang/36102.html

联系我们

QQ号:***

微信号:***

工作日:9:30-18:30,节假日休息