人脸识别

目标:
实现三元组损失函数。
使用一个已经训练好了的模型来将人脸图像映射到一个128位数字的的向量。
使用这些编码来执行人脸验证和人脸识别。

导包

from keras.models import Sequential
from keras.layers import Conv2D, ZeroPadding2D, Activation, Input, concatenate
from keras.models import Model
from keras.layers.normalization import BatchNormalization
from keras.layers.pooling import MaxPooling2D, AveragePooling2D
from keras.layers.merge import Concatenate
from keras.layers.core import Lambda, Flatten, Dense
from keras.initializers import glorot_uniform
from keras.engine.topology import Layer
from keras import backend as K#------------用于绘制模型细节,可选--------------#
from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot
from keras.utils import plot_model
#------------------------------------------------#K.set_image_data_format('channels_first')import time
import cv2
import os
import numpy as np
from numpy import genfromtxt
import pandas as pd
import tensorflow as tf
import fr_utils
from inception_blocks_v2 import *%matplotlib inline
%load_ext autoreload
%autoreload 2np.set_printoptions(threshold=np.nan)

将人脸图像编码为128位的向量

初始模型使用由Szegedy et al.等人的初始模型,加载预训练权值,可以在inception_blocks.py文件来查看是如何实现的。
关键:

  1. 该网络使用了 96 × 96的RGB图像作为输入数据,图像数量为 m,输入的数据维度为 ( m , nc , nh , nw ) = ( m , 3 , 96 , 96 )。
  2. 输出为 ( m , 128 ) (m,128) (m,128)的已经编码的 m m m个 128 128 128位的向量。

创建一个人脸识别的模型:

FRmodel = faceRecoModel(input_shape=(3,96,96))
print("参数数量:" + str(FRmodel.count_params()))

结果:

参数数量:3743280

使用128神经元全连接层作为最后一层,该模型确保输出是大小为128的编码向量,然后使用比较两个人脸图像的编码:

通过计算两个编码和阈值之间的误差,可以确定这两幅图是否代表同一个人。

三元组损失函数将上面的形式实现,它会试图将同一个人的两个图像(对于给定的图和正例)的编码“拉近”,同时将两个不同的人的图像(对于给定的图和负例)进一步“分离”。
满足:

同一个人的两个图像的编码非常相似。
两个不同人物的图像的编码非常不同。

三元组损失函数

什么是三元组损失函数:
使用三元组图像(A,P,N)进行训练:

  1. A是“Anchor”,是一个人的图像。
  2. P是“Positive”,是相对于“Anchor”的同一个人的另外一张图像。
  3. N是“Negative”,是相对于“Anchor”的不同的人的另外一张图像。

这些三元组来自训练集,我们使用 ( A( i ), P( i ), N( i )) 来表示第i个训练样本。我们要保证图像A( i )与图像P( i )的差值至少比与图像 N ( i ) 的差值相差 α(阈值):

将上面式子化为损失函数求最小:

注意点:

  1. 公式(1)是给定三元组A与正例P之间的距离的平方,我们要让它变小。
  2. 公式(2)是给定三元组A与负例N之间的距离的平方,我们要让它变大。
  3. α是间距,是超参数,这里我们使用 α = 0.2。

逐步实现:

  1. 计算"anchor" 与 "positive"之间编码的距离:

  2. 计算"anchor" 与 "negative"之间编码的距离:

  3. 根据公式计算每个样本的值:

  4. 通过取带零的最大值和对训练样本的求和来计算整个公式:

def triplet_loss(y_true, y_pred, alpha = 0.2):anchor, positive, negative = y_pred[0], y_pred[1], y_pred[2]pos_dist = tf.reduce_sum(tf.square(tf.subtract(anchor,positive)),axis=-1)neg_dist = tf.reduce_sum(tf.square(tf.subtract(anchor,negative)),axis=-1)basic_loss = tf.add(tf.subtract(pos_dist,neg_dist),alpha)loss = tf.reduce_sum(tf.maximum(basic_loss,0))return loss

测试:

with tf.Session() as test:tf.set_random_seed(1)y_true = (None, None, None)y_pred = (tf.random_normal([3, 128], mean=6, stddev=0.1, seed = 1),tf.random_normal([3, 128], mean=1, stddev=1, seed = 1),tf.random_normal([3, 128], mean=3, stddev=4, seed = 1))loss = triplet_loss(y_true, y_pred)print("loss = " + str(loss.eval()))

结果:

loss = 528.143

加载训练好了的模型

FaceNet是通过最小化三元组损失来训练的,但是由于训练需要大量的数据和时间,所以我们不会从头训练,相反,我们会加载一个已经训练好了的模型,运行下列代码来加载模型,可能会需要几分钟的时间。

FRmodel.compile(optimizer = 'adam', loss = triplet_loss, metrics = ['accuracy'])
fr_utils.load_weights_from_FaceNet(FRmodel)

使用这个模型进行人脸验证和人脸识别。

人脸验证

构建一个数据库,里面包含了允许进入的人员的编码向量,使用的是一个字典来表示,这个字典将每个人的名字映射到他们面部的128维编码上。

database = {}
database["danielle"] = fr_utils.img_to_encoding("images/danielle.png", FRmodel)
database["younes"] = fr_utils.img_to_encoding("images/younes.jpg", FRmodel)
database["tian"] = fr_utils.img_to_encoding("images/tian.jpg", FRmodel)
database["andrew"] = fr_utils.img_to_encoding("images/andrew.jpg", FRmodel)
database["kian"] = fr_utils.img_to_encoding("images/kian.jpg", FRmodel)
database["dan"] = fr_utils.img_to_encoding("images/dan.jpg", FRmodel)
database["sebastiano"] = fr_utils.img_to_encoding("images/sebastiano.jpg", FRmodel)
database["bertrand"] = fr_utils.img_to_encoding("images/bertrand.jpg", FRmodel)
database["kevin"] = fr_utils.img_to_encoding("images/kevin.jpg", FRmodel)
database["felix"] = fr_utils.img_to_encoding("images/felix.jpg", FRmodel)
database["benoit"] = fr_utils.img_to_encoding("images/benoit.jpg", FRmodel)
database["arnaud"] = fr_utils.img_to_encoding("images/arnaud.jpg", FRmodel)

当有人出现在你的门前刷他们的身份证的时候,你可以在数据库中查找他们的编码。
实现verify() 函数来验证摄像头的照片(image_path)是否与身份证上的名称匹配,这个部分可由以下步骤构成:

  1. 根据image_path来计算编码。
  2. 计算与存储在数据库中的身份图像的编码的差距。
  3. 如果差距小于0.7,那么就打开门,否则就不开门。

我们使用L2(np.linalg.norm)来计算差距。

def verify(image_path, identity, database, model):encoding = fr_utils.img_to_encoding(image_path, model)dist = np.linalg.norm(encoding - database[identity])if dist < 0.7:print("欢迎 " + str(identity) + "回家!")is_door_open = Trueelse:print("经验证,您与" + str(identity) + "不符!")is_door_open = Falsereturn dist, is_door_open

测试:

verify("images/camera_0.jpg","younes",database,FRmodel)

结果:

欢迎 younes回家!
(0.65939206, True)

人脸识别

实现一个人脸识别系统,该系统将图像作为输入,并确定它是否是授权人员之一(如果是,是谁),与之前的人脸验证系统不同,我们不再将一个人的名字作为输入的一部分。

现在我们要实现who_is_it()函数,实现它需要有以下步骤:

  1. 根据image_path计算图像的编码。
  2. 从数据库中找出与目标编码具有最小差距的编码。
    初始化min_dist变量为足够大的数字(100),它将找到与输入的编码最接近的编码。
    遍历数据库中的名字与编码,可以使用for (name, db_enc) in database.items()语句。
    计算目标编码与当前数据库编码之间的L2差距。
    如果差距小于min_dist,那么就更新名字与编码到identity与min_dist中。
def who_is_it(image_path, database,model):encoding = fr_utils.img_to_encoding(image_path, model)min_dist = 100for (name,db_enc) in database.items():dist = np.linalg.norm(encoding - db_enc)if dist < min_dist:min_dist = distidentity = nameif min_dist > 0.7:print("抱歉,您的信息不在数据库中。")else:print("姓名" + str(identity) + "  差距:" + str(min_dist))return min_dist, identity

测试:

who_is_it("images/camera_0.jpg", database, FRmodel)

结果:

姓名younes  差距:0.659392
(0.65939206, 'younes')

人脸验证解决了更容易的1:1匹配问题,人脸识别解决了更难的1∶k匹配问题。

三重损失是训练神经网络学习人脸图像编码的一种有效的损失函数。

相同的编码可用于验证和识别。测量两个图像编码之间的距离可以确定它们是否是同一个人的图片。

吴恩达深度神经网络笔记—人脸识别相关推荐

  1. 吴恩达深度学习笔记(四)

    吴恩达深度学习笔记(四) 卷积神经网络CNN-第二版 卷积神经网络 深度卷积网络:实例探究 目标检测 特殊应用:人脸识别和神经风格转换 卷积神经网络编程作业 卷积神经网络CNN-第二版 卷积神经网络 ...

  2. 吴恩达深度学习笔记——卷积神经网络(Convolutional Neural Networks)

    深度学习笔记导航 前言 传送门 卷积神经网络(Convolutional Neural Networks) 卷积神经网络基础(Foundations of Convolutional Neural N ...

  3. 吴恩达深度学习笔记——神经网络与深度学习(Neural Networks and Deep Learning)

    文章目录 前言 传送门 神经网络与深度学习(Neural Networks and Deep Learning) 绪论 梯度下降法与二分逻辑回归(Gradient Descend and Logist ...

  4. 吴恩达深度学习笔记——结构化机器学习项目(Structuring Machine Learning Projects)

    深度学习笔记导航 前言 传送门 结构化机器学习项目(Machine Learning Strategy) 机器学习策略概述 正交化(orthogonalization) 评价指标 数字评估指标的单一性 ...

  5. 吴恩达深度学习笔记1-Course1-Week1【深度学习概论】

    2018.5.7 吴恩达深度学习视频教程网址 网易云课堂:https://mooc.study.163.com/smartSpec/detail/1001319001.htm Coursera:htt ...

  6. 799页!吴恩达深度学习笔记.PDF

    吴恩达深度学习课程,是公认的最优秀的深度学习课程之一,目前没有教材,只有视频,本文提供完整笔记下载,这本笔记非常适合和深度学习入门. 0.导语 黄海广博士和同学将吴恩达老师深度学习视频课程做了完整的笔 ...

  7. 吴恩达深度学习笔记- lesson4 卷积神经网络

    文章目录 Week 1 卷积神经网络基础 4.1.1 计算机视觉(Computer vision) 4.1.2 边缘检测示例(Edge detection example) 4.1.3 更多边缘检测内 ...

  8. 吴恩达卷积神经网络 笔记,吴恩达 深度神经网络

    如何评价吴恩达的学术地位 吴恩达(AndrewNg),斯坦福计算机系的副教授,师从机器学习的大师级人物MichaelI.Jordan. 同门师兄弟包括ZoubinGhahramani,TommiJaa ...

  9. 吴恩达--深度学习笔记

    这是一个督促自己学习的笔记 文章目录 这是一个督促自己学习的笔记 1.logistic回归 1. 神经网络基础----二分分类 2. logistic回归 3. logistic回归损失函数 4. 梯 ...

最新文章

  1. 2020年中国面向人工智能“新基建”的知识图谱行业白皮书
  2. 华为服务器面板显示,服务器面板怎么查看
  3. 电脑屏幕变黄如何调整_如何调整电脑屏幕比例
  4. Spring底层控制反转解耦合(IOC)
  5. Excel表格内容导出到页面
  6. iOS10 xcode8 分页请求MJRefresh崩溃问题
  7. C++_程序内存模型_内存四区_栈区_堆区---C++语言工作笔记029
  8. python实例编写(7)---测试报告与测试套件(多个py文件,1个py文件内多个用例)
  9. Java实现微信刷屏(2)
  10. 解决/**/嵌套问题---条件编译:#if 0 statement #endif 帅帅哒洋办法
  11. git添加文件到版本库中
  12. spring cloud 解决问题
  13. 从 sourcemap 中获取源码
  14. 北航linux内核编译及烧录实验报告,北航操作系统实验Lab1笔记
  15. [硬件]导热垫(Thermal Pad)和导热过孔(Via for thermal pad)
  16. 试题 B: 顺子日期
  17. mysql管理员权限哪个表_Mysql 用户权限管理(权限列表)
  18. 好工具推荐系列:Windows系统查看各个进程/网速/CPU的软件(查看系统资源工具)
  19. Linux不是Windows(转)
  20. brpc internal

热门文章

  1. docker invalid reference format: repository name must be lowercase
  2. python openpyxl load_workbook报AttributeError: 'MergedCell' object attribute 'hyperlink' is read-only
  3. kmp---Simpsons’ Hidden Talents(初学者能看懂的算法)
  4. 百度跳动争抢优质内容,豆瓣微博们何去何从?
  5. 其实书童是一个集算法、实践、论文以及Transformer于一身的公号(往期索引大全)...
  6. 博客和论坛结合推广的经验分享
  7. html自动点击屏幕,虚拟按键大师(屏幕自动点击辅助器)
  8. vb6.0 类没有注册,查找具有 CLSID 的对象:{7EBDAAE0-8120-11CF-899F-00AA00688B10} 7EBDAAE1 7EBDAAE2
  9. 杰理之单音VCOMO直推,喇叭没声音问题【篇】
  10. 二、代码实现深度学习道路训练样本数据的制作(代码部分详解)——重复工作+多次返工的血泪史