FaceNet源码解读2:史上最全的FaceNet源码使用方法和讲解(二)
史上最全的FaceNet源码使用方法和讲解(二)
这是对:史上最全的FaceNet源码使用方法和讲解(一)(附预训练模型下载)的一个补充。
一、对模型进行测试:
用到的函数:validate_on_lfw.py
在pycharm中配置的参数如下:
数据集所在路径 模型所在路径
示例:
20170512-110547 1.png 2.png
这将执行以下四个操作:
a)加载模型。
b)加载和解析文本文件与图像对。
c)计算所有图像(以及它们的水平翻转版本)在测试集中的向量。
d)计算精度,验证率(@ FAR = -10e-3),曲线下面积(AUC)和等误差率(EER)等性能指标。
典型的输出如下:
Model directory: /home/david/models/20180402-114759/
Metagraph file: model-20180402-114759.meta
Checkpoint file: model-20180402-114759.ckpt-275
Runnning forward pass on LFW images
........................
Accuracy: 0.99650+-0.00252
Validation rate: 0.98367+-0.00948 @ FAR=0.00100
Area Under Curve (AUC): 1.000
Equal Error Rate (EER): 0.004
二、对预训练模型重新进行训练
有时候,我们需要用自己的数据集对预训练好的模型进行重新训练,或者之前训练了一个模型之后,觉得训练轮数不够,又不想从头开始训练,这样,在训练之前就要把之前训练的模型重新加载进去,方式如下:
######第一步:添加预训练模型的参数:
在中train_tripletloss.py
找到这样一个语句:
改成这样:
parser.add_argument('--pretrained_model', type=str,help='Load a pretrained model before training starts.',default='模型所在路径')
第二步:解决程序中的一个小bug
如果只是完成了第一步,运行程序会报错。经过调试,是因为程序有一个小的bug需要修复:
找到这一行程序:
可以看出,这一处函数的作用是:如果预训练模型这个参数非空,那么用tensorflow的saver.restore()函数重新加载模型参数,但是此处会报错,
那么我们模仿compare.py
函数中的加载模型方法,将这个函数改为:
facenet.load_model(args.pretrained_model)
然后运行程序,发现程序已经可以正常执行了。
如果不放心,可以取一个已经训练好的模型,加载之后训练一轮,会发现初始的损失函数非常小,同时,训练一轮之后模型的准确率已经和加载的预训练模型准确率差不多了,说明模型加载成功。
三、用自己的数据集结合SVM训练一个人脸识别系统
可能希望自动对您的私人照片集进行分类。或者您有一个安全摄像头,您想要自动识别您的家庭成员。那么您可能希望在自己的数据集上训练分类器。在这种情况下,classifier.py程序也可以用于此。
1)构建自己的数据集。 在该示例中,每个类的5个第一图像用于训练,接下来的5个图像用于测试。
比如说,你有9个需要分类的人(这里暂时用F1-F9表示),其中你有每个人各20张照片
使用的类是:
F1
F2
F3
F4
F5
F6
F7
F8
F9
训练集的目录组织方式:
my_dataset/test
├── F1
│ ├── F1_0.png
│ ├── F1_1.png
│ ├── F1_2.png
│ ├── F1_3.png
│ ├── F1_3.png
…… ……
│ └── F1_19.png
├── F2
│ ├── F2_0.png
│ ├── F2_1.png
│ ├── F2_2.png
│ ├── F2_3.png
│ ├── F2_3.png
│ …… ……
│ └── F2_19.png
├── F3
│ ├── F3_0.png
│ ├── F3_1.png
…… …… ……
…
…
测试集的目录组织方式类似。
2)训练。 用到的代码:calssifier.py
。这一步是在你已经训练好了一个FaceNet模型(或者使用网上提供的模型),需要用这个模型计算出的自己照片的特征向量来训练一个SVM分类器的场景,这个程序的基本原理是:通过用图像算出来的向量数据来训练一个SVM分类器,从而对人的身份进行一个判断,同时在.pkl格式的文件中存储每一个分类。这也是作者对于FaceNet程序应用的一个探索。
这个函数有两个模式,一个模式用来训练,另一个模式用来测试。具体功能如下:
模式= TRAIN:
- 使用训练好的模型计算图片的向量,用来训练SVM分类器
- 将训练好的分类模型保存为python pickle文件
模式= CLASSIFY:
- 加载SVM分类器模型
- 使用来自数据集测试部分的向量来测试分类器
执行本代码需要添加的参数以及各参数的含义:
- mode: 设定“TRAIN”和“CLASSIFY”两种模式。
- data_dir: 图片数据所在文件夹
- model: 训练好的模型
- classifier_filename:类似于标签,如果mode参数是TRAIN,那么需要指定一个输出的文件位置(以.pkl结尾,例如**/**.pkl),如果mode参数是CLASSIFY,那么就需要指定参数的路径(.pkl文件)。
配置参数示例:
TRAIN 图片数据所在文件夹 模型文件夹 标签文件.pkl
运行结果:
Number of classes: 9
Number of images: 180
Loading feature extraction model
Model directory: 20180606
Metagraph file: model-20180606-232113.meta
Checkpoint file: model-20180606-232113.ckpt-120120
Calculating features for images
Training classifier
Saved classifier model to file "E:/facenet/pick/classifier.pkl"
测试:
CLASSIFY 图片数据所在文件夹 模型文件夹 标签文件保存地址.pkl
运行结果:
Number of classes: 9
Number of images: 20
Loading feature extraction model
Model directory: 20180606
Metagraph file: model-20180606-232113.meta
Checkpoint file: model-20180606-232113.ckpt-120120
Calculating features for images
Testing classifier
Loaded classifier model from file "E:/facenet/pick/classifier.pkl"0 F1: 0.4711 F1: 0.6722 F1: 0.6853 F1: 0.7004 F3: 0.6335 F1: 0.5566 F1: 0.5557 F1: 0.6968 F2: 0.8279 F2: 0.775…… ……
如果不需要在每次执行的过程中都配置这几个参数,可以对程序进行微调,找到原程序中的这几行代码:
改动如下(即将初始值配置在程序中,避免每次执行程序时都要输入对应的参数。如果参数有改动,只需要更改程序对应部位即可。):
parser.add_argument('--mode', type=str, choices=['TRAIN', 'CLASSIFY'],help='Indicates if a new classifier should be trained or a classification ' + 'model should be used for classification', default='CLASSIFY')#这里更改模式
parser.add_argument('--data_dir', type=str,help='Path to the data directory containing aligned LFW face patches.',default='TF1_classify')#添加自己的数据文件夹
parser.add_argument('--model', type=str,help='Could be either a directory containing the meta_file and ckpt_file or a model protobuf (.pb) file',default='20180606')#预训练模型
parser.add_argument('--classifier_filename',help='Classifier model file name as a pickle (.pkl) file. ' + 'For training this is the output and for classification this is an input.',default='pick/classifier.pkl')#.pkl文件存储的位置
附录:程序中的一些小改进:
一)用GPU训练模型。
原程序默认使用CPU训练,但是这样训练的速度太慢,如果你电脑恰好有一块不错的GPU,或者实验室里有GPU服务器,那么配置好GPU环境之后(包括cuda,TensorFlow-gpu等),可以在程序中添加代码如下:
import OS
os.environ["CUDA_VISIBLE_DEVICES"] = '0'#如果有多块显卡,可以指定第几块显卡,0即为第一块显卡。
这样,程序在执行过程中就优先调用GPU训练模型了。
二)微调损失函数
在《In Defense of the Triplet Loss for Person Re-Identification》这篇论文中提到:损失函数中去掉平方后效果还会更好一些,如下图:
如果有需要的话,可以改成开方的形式,在facenet.py
下的triplet_loss
函数中,找到如下两句代码:
改成:
pos_dist = tf.sqrt(tf.reduce_sum(tf.square(tf.subtract(anchor, positive)), 1)) # tf.square:平方。tf.subtract::减法
neg_dist = tf.sqrt(tf.reduce_sum(tf.square(tf.subtract(anchor, negative)), 1))
即加上一个开方运算。(目前正在测试效果,以后补充……)
个人知乎主页地址:知乎个人主页。欢迎关注。
附:
找到一个非常好的人脸识别领域的汇总博客,把链接贴在这里:格灵深瞳:人脸识别最新进展以及工业级大规模人脸识别实践探讨 | 公开课笔记
FaceNet源码解读2:史上最全的FaceNet源码使用方法和讲解(二)相关推荐
- 计算机配置好坏怎么看,电脑配置怎么看 史上最全的查看电脑配置好坏方法
原标题:电脑配置怎么看 史上最全的查看电脑配置好坏方法 很多电脑新手朋友都喜欢问:电脑配置怎么看,也就是如何看一台电脑的硬件的好坏.关于如何查看电脑配置好坏,目前网上有很多相关教程,大家可以在百度搜索 ...
- 联通开通流量不显示无服务器,史上最全的联通流量自助开通方法!
原标题:史上最全的联通流量自助开通方法! 天底下的流量包都在这儿,爱要不要!你的流量能HOLD住吗?哈哈,小编给你支招:以下就是给你推荐的超好用流量包订购方法!各位看官您瞧好了! 流量月包 兵马未动, ...
- 史上最全的JFinal源码分析(不间断更新)
打算 开始 写 这么 一个系列,希望 大家 喜欢,学习 本来就是 一个查漏补缺的过程,希望大家能提出建议.本篇 文章 是整个目录的向导,希望 大家 喜欢.本文 将以 包的形式跟大家做向导. Handl ...
- 2011年最新最全的 Cydia源地址_iPhone Cydia 源大合集_史上最全的Cydia源
资源的名称 资源的地址 网站里面的内容 Dev Unlock http://apt9.yellowsn0w.com/ Yellowsn0w unlock iFonetec http://app.ifo ...
- 史上最全推广小程序实操方法
通用篇 1.用小程序名称抢排位 小程序的排名跟名称.描述.上线时间.用户访问量和小程序的综合质量有关,且小程序的名称是唯一的.根据用户的搜索习惯和产品特性,尽可能多地注册小程序名称,才能让小程序的排名 ...
- 史上最全的APP推广模式及方法技巧
APP推广的重要性对APP的运营来说是不言而喻,首先要清楚的一点是,不同的APP适用于不同的推广方法,并没有哪一种APP推广方法是能够做到真正意义上的放之四海皆准的,而在所有的APP推广方法中,最重要 ...
- 史上最全JavaScript数组去重的十种方法(推荐)
一.前言: 我们在实际工作中,或者在面试找工作时,都会用到或者被问到一个问题,那就是"数组如何去重".是的,这个问题有很多种解决方案,看看下面的十种方式吧! 二.数组去重方式大汇总 ...
- 史上最全最细imx6 GPIO配置流程及讲解
我们拿到板子要做的第一件事,往往是驱动一个gpio,控制其 GPIO 输出高低电平,在有些应用场景中,需要做到开机之后,某个引脚一直输出一个电平来初始化设备,这就不仅需要在内核中配置引脚为GPIO功能 ...
- 史上最全!统计学常用的数据分析方法大总结
图片 描述统计 描述统计是通过图表或数学方法,对数据资料进行整理.分析,并对数据的分布状态.数字特征和随机变量之间关系进行估计和描述的方法. 描述统计分为集中趋势分析和离中趋势分析和相关分析三大部分. ...
- android 备份整个手机,快收藏!史上最全的安卓手机数据备份方法都在这里了
随时随地,想看就看.可以说,现在手机的江湖地位已经是如日中天,成为人们每天都离不开的东西.不论是工作还是生活,手机里都储存了太多代表我们回忆的数据,于我们而言,重要的不是手机,而是手机里的数据,今天, ...
最新文章
- [翻译]NUnit--前言(一)
- FileInputStream
- java的requestmapping_SpringMVC RequestMapping 详解
- linux命令cp -a,linux命令_ls命令与cp命令详解(一)
- 《抓住听众心理——演讲者要知道的100件事》一2.听众需要上下文
- GitHub、YouTube 们的开源替代品都有了!
- 【离散数学笔记】计数原理:解决计数问题的基本方法
- 服务器系统是指什么,服务器操作系统指的是什么
- 拓端tecdat|使用R语言对进行地理空间数据可视化
- Java保存class文件,[转载]Class文件在JVM中如何存储
- AutoCAD DWG,DXF文件导出高清图片、PDF
- Android 系统源码以及结构
- 魏俊妮《全面培训系统建设与培训管理实务》课程大纲
- STM32CUDE-STM32F407学习笔记2-按键操作
- UVALive 6959 - Judging Troubles
- java8 使用拉姆达对基本数据类型集合进行分组
- 自定义UITableView索引动画,实现饿了么菜单效果
- 如何获取新浪微博数据
- 进阶之路(中级篇) - 015 串口控RGB三色灯
- 判断推理——翻译推理