基于facenet+faiss开发构建人脸识别系统

news2024/9/22 19:46:25

facenet是一款非常经典的神经网络模型,它可以直接学习从人脸图像到欧几里德空间的映射(直接将人脸映射到欧几里得空间)。在欧几里德空间中,距离直接对应于人脸相似性的度量。一旦这个空间产生,使用标准技术,将FaceNet嵌入作为特征向量,就可以很容易地实现人脸识别、验证和聚类等任务。作者使用经过训练的深度卷积网络来直接优化嵌入本身,而不是像以前的深度学习方法那样使用中间瓶颈层。为了训练,作者使用了一种新的online triplet mining方法生成的粗略对齐的匹配/非匹配的人脸块的 triplets。该方法的好处是更大的recognition performance:实现了最先进的人脸识别性能,每一张脸仅使用128字节(128维空间向量)。

在之前的一些项目就有使用到facenet模型,用于人脸识别本质上来说是借助于facenet模型将输入的标准的人脸图像数据转化为了128维的向量,之后通过对向量的计算,比如:相似度计算、距离计算,转化为了人脸识别的计算,当然了后面也可以使用机器学习模型来接收facenet的输出向量做进一步的预测都是可以的,我们之前的项目采用的是向量直接匹配计算的方式,由于当时数据量不大,所以向量的匹配计算等价于暴力搜索,但是一旦数据量激增,这种方式带来的时间成本就是难以接受的了。

最近正好在用faiss,就有一个想法,想要将facenet模型和faiss做一个集成来开发一套高性能的人脸识别系统,我将整体的构思绘制如下图所示:

 整体的思路还是比较清晰明了的。

接下来先简单回顾一下相关技术原理。

Facenet是一种用于人脸识别和人脸验证的深度学习模型,通过将人脸图像转换成高维空间中的嵌入向量来表示每个人脸。该模型由Google的研究科学家Florian Schroff、Dengyong Zhou和Christian Szegedy于2015年提出。

Facenet模型的构建原理基于卷积神经网络(Convolutional Neural Network, CNN)。下面是Facenet模型的主要构建原理:

  1. 输入图像:首先,将人脸图像作为输入提供给Facenet模型。

  2. 卷积神经网络(CNN):Facenet模型通过多个卷积层和池化层来提取图像中的特征。卷积层用于捕获空间特征,如边缘和纹理等。池化层用于减小特征图的尺寸并保留重要的特征。

  3. Triplet Loss:Facenet模型使用三元组损失函数(Triplet Loss)来学习一个紧凑的人脸嵌入向量空间。Triplet Loss的目标是使同一人的嵌入向量之间的距离尽可能小,不同人的嵌入向量之间的距离尽可能大。这样可以使得不同人的嵌入向量在空间上得到有效的分离。

Facenet算法的优点:

  1. 高准确率:Facenet模型在人脸识别和人脸验证任务上取得了非常出色的准确率,甚至在大规模人脸识别数据集上也表现优异。

  2. 基于嵌入向量的表示:Facenet将人脸图像转换为紧凑的嵌入向量,使得不同人的人脸之间能够得到有效的分离,并且嵌入向量具有良好的可比性。

  3. 大规模训练:Facenet模型可以通过使用大规模的人脸图像数据集进行训练,从而获得更好的泛化能力。

Facenet算法的缺点:

  1. 高计算资源需求:由于Facenet模型的深度和复杂性,需要大量的计算资源来进行训练和推理。这使得在某些设备或场景下应用Facenet模型变得困难。

  2. 影响因素敏感:Facenet模型对输入图像的光照、角度和尺度等因素敏感。在实际应用中,需要考虑这些因素对人脸识别或验证的影响。

Faiss是一种用于高效相似性搜索的库,由Facebook人工智能研究实验室开发。它基于近似最近邻(Approximate Nearest Neighbor, ANN)算法,旨在解决大规模数据集的相似性搜索问题。Faiss可以在GPU和CPU上运行,并提供了多种近似搜索算法和索引结构。

Faiss的主要构建原理是使用索引结构对数据进行预处理,以便于在搜索时快速定位到相似的数据点。下面是Faiss的主要特点和优势:

  1. 高效:Faiss通过高度优化的算法和索引结构,实现了非常高效的相似性搜索。它可以处理包含数百万或上亿个数据点的大规模数据集。

  2. 支持多种索引算法:Faiss提供多种索引算法,包括快速扫描、k-means、倒排文件等等。这些算法可以针对不同的数据特点和搜索需求选择最合适的索引结构,以提高搜索性能。

  3. 可扩展性:Faiss可以在单个GPU或多个GPU上运行,并且支持分布式计算。这使得它能够有效地处理大规模数据集并实现快速搜索。

  4. 索引更新和存储:Faiss允许动态地更新索引结构,可以添加、删除或修改数据点。此外,Faiss还提供了存储和加载索引结构的功能,方便在不同环境中使用。

  5. 多种语言支持:Faiss支持多种编程语言接口,如C++、Python等,使得它在不同的开发环境下都易于使用和集成。

Faiss算法的一些缺点包括:

  1. 近似性:Faiss提供的是近似最近邻搜索,并不保证精确的最近邻搜索结果。虽然近似搜索能够在处理大规模数据时显著提高搜索速度,但在对结果的准确性有严格要求的应用中,可能需要使用精确搜索算法。

  2. 参数调优:Faiss中的索引算法有多个参数需要调整,以获得最佳的搜索性能。对于不熟悉Faiss的用户来说,可能需要一些实验和调优才能找到最优的配置。

  3. 存储需求:基于索引结构的相似性搜索常常需要占用较大的存储空间,尤其是当数据集非常大时。这可能对存储资源造成压力。

接下来我们来实现自己的想法,facenet本身模型网上有开源的,这里我就不再自己训练了,直接使用了网上开源的模型,自己搜索就有很多的,选择合适自己使用的即可,接下来就是要实现人脸向量数据库的构建,核心实现如下所示:

def batch2Vec(picDir="datasets/", save_path="faceDB.json"):
    """
    批量数据向量化处理
    """
    feature=[]
    person={}
    count=0
    for one_person in os.listdir(picDir):
        oneDir=picDir+one_person+"/"
        print("one_person: ", one_person, ", one_num: ", len(os.listdir(oneDir)), ", count: ", count)
        for one_pic in os.listdir(oneDir):
            one_path=oneDir+one_pic
            one_vec=sinleImg2Vec(pic_path=one_path)
            if one_person in person:
                person[one_person].append([one_pic, one_vec])
            else:
                person[one_person]=[[one_pic, one_vec]]
            feature.append([one_path, one_vec])
        count+=1
    print("feature_length: ", len(feature))
    with open(save_path, "w") as f:
        f.write(json.dumps(feature))
    with open("person.json", "w") as f:
        f.write(json.dumps(person))

之后我们就可以基于人脸向量数据库来构建faiss索引,输入单个查询向量来进行计算了,核心实现如下所示:

#检索计算
start=time.time()               
distances, indexs = index.search(query, topK)
print("distances_shape: ", distances.shape)
print("indexs_shape: ", indexs.shape)
end=time.time()
delta=round(end-start, 4)
#对比可视化
plt.clf()
plt.figure(figsize=(36,6))
plt.subplot(1,6,1)
plt.imshow(Image.open(pic_path))
plt.title("OriginalImage\nSearchTime: "+str(delta)+"s")
indexs=indexs.tolist()[0]
print("indexs: ", indexs)
for i in range(len(indexs)):
    one_ind=indexs[i]
    plt.subplot(1,6,i+2)
    plt.imshow(Image.open(images[one_ind]))
    one_dis= distance(query, vectors[one_ind])
    plt.title("Top"+str(i)+" SearchImage\nDis is: "+str(round(one_dis, 4)))
plt.savefig("compare.jpg")

接下来我们看下实际结果详情。

查询输入:

 检索输出如下:
 

 查询输入:

 检索输出:

 查询输入:

 检索输出:

 查询输入:

 检索输出:

 整体体验下来感觉精度和速度还是非常不错的,可见这个流程是没有问题的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/834570.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

p元素使用伪元素::before实现小圆点,换行缩进

p元素使用伪元素实现小圆点,默认换行第二行会与小圆点平行,图2是想要的样式 小圆点代码 p::before{content: "";display: inline-block;width: 6px;height: 6px;border-radius: 50%;background-color: #D8D8D8;margin: 0 5px 2px 0; }换行缩…

如何使用动态代理ip来突破限制

在如今数字化时代,互联网已经成为人们获取信息、交流互动、进行商业活动的重要平台。然而,许多网站为了保护安全和用户体验,采取了各种访问限制和封禁措施,使得用户在大规模网站访问和数据采集中面临种种困惑。作为动态IP代理产品…

数据可视化:Matplotlib详解及实战

1 Matplotlib介绍 Matplotlib是Python中最常用的可视化工具之一,可以非常方便地创建海量类型的2D图表和一些基本的3D图表。 Matplotlib提供了一个套面向绘图对象编程的API接口,能够很轻松地实现各种图像的绘制,并且它可以配合Python GUI工具(…

汽车维修保养记录查询API:实现车辆健康状况一手掌握

在当今的数字化世界中,汽车维修保养记录的查询和管理变得前所未有地简单和便捷。通过API,我们可以轻松地获取车辆的维修和保养记录,从而实现对手中车辆健康状况的实时掌握。 API(应用程序接口)是进行数据交换和通信的标…

pytorch实战-图像分类(二)(模型训练及验证)(基于迁移学习(理解+代码))

目录 1.迁移学习概念 2.数据预处理 3.训练模型(基于迁移学习) 3.1选择网络,这里用resnet 3.2如果用GPU训练,需要加入以下代码 3.3卷积层冻结模块 3.4加载resnet152模 3.5解释initialize_model函数 3.6迁移学习网络搭建 3.…

基于 Flink Paimon 实现 Streaming Warehouse 数据一致性管理

摘要:本文整理自字节跳动基础架构工程师李明,在 Apache Paimon Meetup 的分享。本篇内容主要分为四个部分: 背景 方案设计 当前进展 未来规划 点击查看原文视频 & 演讲PPT 一、背景 ​ 早期的数仓生产体系主要以离线数仓为主&#xf…

【Leetcode】二叉树的最近公共祖先,二叉搜索树转换成排好序的双向链表,前序遍历与中序遍历构造二叉树

一.二叉树的最近公共祖先 链接 二叉树的最近公共祖先 题目再现 『Ⅰ』思路一:转换成相交链表问题 观察上图,节点1和节点4的最近公共祖先是3,这是不是很像相交链表的问题,关于相交链表,曾经我在另一篇文章里写到过&a…

WPS Office AI实战:智能表单,信息收集神器

前面我们已经介绍了WPS里常用的文字、表格、演示文稿等等,在WPS AI的武装下重新发挥出智能化的威力,今天来聊聊表单的智能化应用会是什么样。 金山智能表单进行数据轻松收集,通过对话或拍照创建表单,回收结果还能自动生成数据报告…

回归预测 | MATLAB实现SO-CNN-BiGRU蛇群算法优化卷积双向门控循环单元多输入单输出回归预测

回归预测 | MATLAB实现SO-CNN-BiGRU蛇群算法优化卷积双向门控循环单元多输入单输出回归预测 目录 回归预测 | MATLAB实现SO-CNN-BiGRU蛇群算法优化卷积双向门控循环单元多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现SO-CNN-BiGRU蛇群算法…

浅谈管廊智能监控和报警系统设计探究

贾丽丽 安科瑞电气股份有限公司 上海嘉定 201801 摘要:综合地下管廊为我国城市的发展发挥了积极的推动作用,为了确保综合地下管廊基本功能得以真正的发挥出来,有必要将智能监控系统融入综合地下管廊智能管理系统构建中,以便于实…

windows物理机 上安装centos ,ubuntu,等多个操作系统的要点

一、摘要 一般情况下,我们的笔记本或工作电脑都默认安装windows 分几个区,当下是win7 win8 win 10 win11 等,突然我们有需求需要安装个centos ,后面我们应当怎么做,要点是什么?一定要根据网上的贴子一步步来…

【雕爷学编程】MicroPython动手做(37)——驱动LCD与图文显示3

MixPY——让爱(AI)触手可及 MixPY布局 主控芯片:K210(64位双核带硬件FPU和卷积加速器的 RISC-V CPU) 显示屏:LCD_2.8寸 320*240分辨率,支持电阻触摸 摄像头:OV2640,200W像素 扬声器&#…

python绘制六边形风车,用python画简单的风车

本篇文章给大家谈谈用python画简单的风车,以及python绘制六边形风车,希望对各位有所帮助,不要忘了收藏本站喔。 风车的动画,过程如下:1)绘制风车形状A,2)擦除风车形状A,3…

【LinearAlgebra】Chapter 12 - Linear Algebra in Probability Statistics

文章目录 Chapter 12 - Linear Algebra in Probability & StatisticsVariance (around athe mean) 方差(接近均值)Continuous Probability Distributions 连续概率分布Mean and Variance of p ( x ) p(x) p(x) p ( x ) p(x) p(x) 的均值和方差Norm…

idea-常用插件汇总

idea-常用插件汇总 码云插件 这个插件是码云提供的ps-码云是国内的一款类似github的代码托管工具。 Lombok Lombok是一个通用Java类库,能自动插入编辑器并构建工具,简化Java开发。通过添加注解的方式,不需要为类编写getter或setter等方法…

[MYSQL]查询单位时间消耗量

请求哪位大神给我优化一下mysql语句. 数据库表:(日/月/年 数据表和data_hour结构一样,懒得复制了,不然太长) DROP TABLE IF EXISTS data_source;#数据源 create table IF not EXISTS data_source ( num int unsigned not null auto_increment PRIMARY KEY COMMENT序号 …

关于win11 debian wsl 子系统安装启动docker一直starting,无法启动

首先我先说明,我的步骤都是按照官网步骤来的 通过官网的操作步骤 通过测试命令 sudo docker run hello-world得到下面的命令,我们通过启动命令 sudo service docker start 执行结果如下图 也就是说无法启动,一直显示在启动中 遇到这种情况…

Ubuntu安装git

使用 apt-get install git 安装git 报错: 这个错误信息通常表示您的系统上没有可用的 git 软件包。这可能是因为您的软件源列表中没有包含 git 软件包所在的软件源,或者您的软件源列表已经过期。 解决: 如果您使用的是 Ubuntu 或类似…

Vue2与Vue3响应式原理

Vue2的响应式 Vue3的响应式

(杭电多校)2023“钉耙编程”中国大学生算法设计超级联赛(5)

1001 Typhoon 计算几何 对于每一个避难点,计算其到所有线段的距离,取min即可 AC代码&#xff1a; #include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<deque> #include<cmath> #include<cstdio&…