FaceNet项目实践

2024-03-15 19:10
文章标签 实践 项目 facenet

本文主要是介绍FaceNet项目实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、论文的原理与复现

1. 论文复现 
Database:LFW db(论文采用,rgb图算是较大的典型数据集)。

LFW数据库 总共有 13233 张 JPEG 格式图片,属于 5749 个不同人。每张图片尺寸都是 250x250;

数据库下载地址:http://vis-www.cs.umass.edu/lfw/lfw.tgz

人脸对齐:python src\align\align_dataset_mtcnn.py data/lfw data/lfw_160 --image_size 160 --margin 32 --random_order --gpu_memory_fraction 0.25

2. 三分triplet类聚类方法 
不使用二分聚类判别,而使用三分聚类判别。 
(一).直接学习图像到欧式空间的映射,其中两张图像所对应的特征的欧式空间的点,最后一层都进行特征归一化。 
||f(x)|| = 1 
归一化后的欧式距离对应这连个图像的相似度

(二). 用三元组进行knn聚类,称为triplet 
a. 原理:三张图对应于两个身份: (a,b,c)=(A,A,B) 
b. 保证 |ab| < (|ac|+|bc|)/2 
c. triplet loss:三张图片输入的loss(之前都是double / single loss) 
d. loss的计算过程

3. 样本的选择方法 
假设有10000张样本,如果是遍历所有的pair,共10000×10000种情况,数量过于庞大,处理这种情况,考虑两种采用minibatch的方法: 
|=======方案一

  • 随机设置6000组embeddings(这个是自己做facenet时用的方法,事先生成随机pairs)

|=======方案二

  1. 假设每个人有20张图片,首先挑出一张图片作为a;
  2. 剩下的19张里选择一张hard positive,就是跟他最不相似的图片b;
  3. 同时在包括其他类的所有照片里,选择一张hard——negative,就是和这张图片最像的照片c。进行训练。


4. triplet方式的缺陷 
新问题:为什么容易进入局部最优?

  • 猜测:由于hard-positive和hard-negative都是选自和a同一类的照片,结果就变成了类间分类,Positive Pair的样本对训练没有积极作用。

解决方案:

  • semi-hard网络结构,在选择hard-negative的时候,要求满足: 
    |positive——pair的平方和| < |negative——pair的平方和-threshold| 
    保证了hard-negative不跟自己太像,不至于每次都选到自己同类的照片)

怀疑:

  • semi-hard是数学上的方法,但是边界阈值的设置需要靠经验吗?
  • 另外限定hard-negtive样本的选择范围于与a不同类的样本范围内,可以改善局部最优吗?

辩驳:

  1. 训练后期,学习率调低,如果训练进入局部最优,在与a不同类的样本里找hard-negative(也就是c),如果c和a的相似度高(欧式距离较小),同时b和a欧式距离也很小(虽然b是同一类里和a最不像的样本,但在bp传播优化过程中,b和a的距离也保持在很小的水平),那么bp的反向传播对网络的改善就大打折扣,难以逃出局部最优。
  2. 优化:在与a不同类的样本里,结合semi-hard方法,更合适于逃离局部最优。(未实践)

5. 评价函数

  1. 评价一: 
    所有6000对pairs的二分结果正确率
  2. 评价二: 
    ROC,Facenet输出了【TP】和【TN】指标。 
    把一对含有同一个人的两张照片pair称为Positive Pair。 
    把一对来自两个人的两张照片pair称为Negative Pair。 
    TP: 把Positive Pair正确判定为Positive Pair; 
    TN: 把Negative Pair正确判定为Negative Pair; 
    FP: 把Negative Pair正确判定为PositivePair; 
    FN: 把Positive Pair正确判定为Negative Pair;

6. 复现主要思路记录: 
前期进行常见的crop((w,h)=(160,160))预处理,没有进行flip、randomskip或rotate,主要是考虑先跑通了再考虑是否有必要通过映射变换增加样本数量。

LFW复现结果: 
以LFW为训练集、以LFW为测试集。loss收敛相当快,训练速度和作者说的差不多。作者硬件1070ti,我的是1080ti,迭代15000次,准确率到0.98,一个多小时(一个epoch取1000次batch。每个batch耗时0.2到0.3秒左右,耗时最长的环节,就是在评价编码器环节:每个epoch后,对LFW随机生成的6000对pair进行一一检验,以triplet方式衡量编码器的好坏,这部分平均耗时10秒以上)

对网络的小改进: 
pair.txt虽然是事先随机的抽取,不过所有pair被固化了,可能无法代表部分判别项。于是,我把pair.txt文件删了,写了新脚本,保证每次pair都是随机生成的10000对,same和notsame维持在1比2的比例附近。随机的pair的生成,虽然增加了图像IO队列的流动成本,但是事实证实了网络收敛地更快。仅迭代1200次,evaluate的结果就达到了0.98。

插曲: 
调试时疑惑不解scipy读取的图像数据,plt.show和cv2.imshow,结果不同。scipy.misc.imread按照RGB格式,opencv按照BGR格式读取。可以说是很逗了。


7.拓展:对其他数据集的复现 
Yale_B(单通道,pgm格式,考虑了多种光照效果,参杂bad样本,其他说明略)数据库,相对于LFW,它的单类样本数更多,分类数较少。以Yale_B为例,观察facenet对中小型人脸数据库的检测精度。同时,通过学姐的帮助,对各数据集进行有效的降维,加快训练效率。

插曲: 
facenet为了节省样本读取的时间,采用pipline方式从图片路径IO输入输出的方式。tf这种方式对png/jpg是支持的,对pgm不支持,考虑到重写输入输出结构需要改动大量代码,所以采用了更简单的办法:写个脚本pgm转jpg搞定。其他修改的细枝末节不赘述。


输出最终结果: 
多次测试,同样迭代千次级别,二分准确率达到0.98。在中小型数据上,facenet也表现出强劲的二分检测能力。涉及师姐的成果,所以图片抹掉了部分重要信息。

python src\validate_on_lfw.py  ../data/lfw_160 models/20180408-102900

----------------------------------------------------------------------------------------------

二. 用来做计算人脸之间的相似度

.准备工作:

2-1.下载FaceNet官方代码

下载地址:https://github.com/davidsandberg/facenet.git 

2-2.下载训练好的FaceNet模型文件

下载地址:https://github.com/davidsandberg/facenet

解压,并将其模型存放在和compare.py代码相同的路径下。

2-3.下载两张待测试的图片。(图片大小无要求,格式为jpg/png)

同样,将图片存放在和compare.py代码相同的路径下。

2-4.运行compare.py代码

1)cd到compare.Py所在路径

2)分别输入:python compare.py 20170511-185253 001.jpg 002.jpg

                      python compare.py 20170511-185253 001.jpg 003.jpg(注意图片格式)

3)  完成

 

这篇关于FaceNet项目实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/812981

相关文章

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

SpringBoot项目是如何启动

启动步骤 概念 运行main方法,初始化SpringApplication 从spring.factories读取listener ApplicationContentInitializer运行run方法读取环境变量,配置信息创建SpringApplication上下文预初始化上下文,将启动类作为配置类进行读取调用 refresh 加载 IOC容器,加载所有的自动配置类,创建容器在这个过程

Maven创建项目中的groupId, artifactId, 和 version的意思

文章目录 groupIdartifactIdversionname groupId 定义:groupId 是 Maven 项目坐标的第一个部分,它通常表示项目的组织或公司的域名反转写法。例如,如果你为公司 example.com 开发软件,groupId 可能是 com.example。作用:groupId 被用来组织和分组相关的 Maven artifacts,这样可以避免

2. 下载rknn-toolkit2项目

官网链接: https://github.com/airockchip/rknn-toolkit2 安装好git:[[1. Git的安装]] 下载项目: git clone https://github.com/airockchip/rknn-toolkit2.git 或者直接去github下载压缩文件,解压即可。

9.8javaweb项目总结

1.主界面用户信息显示 登录成功后,将用户信息存储在记录在 localStorage中,然后进入界面之前通过js来渲染主界面 存储用户信息 将用户信息渲染在主界面上,并且头像设置跳转,到个人资料界面 这里数据库中还没有设置相关信息 2.模糊查找 检测输入框是否有变更,有的话调用方法,进行查找 发送检测请求,然后接收的时候设置最多显示四个类似的搜索结果