从零开始构建:使用CNN和TensorFlow进行人脸特征检测
作者 | Shubham Panchal
译者 | 孟翔杰
来源 | DeepHub IMBA
出品 | AI科技大本营(rgznai100)
人脸检测系统在当今世界中具有巨大的用途,这个系统要求安全性,可访问性和趣味性!今天,我们将建立一个可以在脸上绘制15个关键点的模型。
人脸特征检测模型形成了我们在社交媒体应用程序中看到的各种功能。您在Instagram上找到的面部过滤器是一个常见的用例。该算法将掩膜(mask)在图像上对齐,并以脸部特征作为模型的基点。
Instagram自拍过滤器需要知道您的眼睛,嘴唇和鼻子在图像上的确切位置
让我们使用Keras(TensorFlow作为底层)开发模型!首先,我们需要一些数据来训练我们的模型。
数据
我们使用Omri Goldstein Kaggle 上的带有标记特征的人脸图像数据集。数据集包含大约7000张图像(96*96),这些图像带有可以在facial_keypoints.csv文件中找到的面部标志。
但是在这里我们有一个问题。大多数图像没有15个完整的点集。因此,我们只需要那些具有15个面部关键点的图像即可。
可以使用此脚本,我已经做了一些清理,并将修改后的数据保存在Dataset Archives GitHub中。Colab notebook需要使用wget命令下载ZIP文件。
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split# Download the dataset from Kaggle. Unzip the archive. You'll find the facial_keypoints.csv file there.
facial_keypoints = pd.read_csv( "files/face-images-with-marked-landmark-points/facial_keypoints.csv")
num_missing_keypoints = facial_keypoints.isnull().sum( axis=1 )
all_keypoints_present_ids = np.nonzero( num_missing_keypoints == 0 )[ 0 ]# face_images.npz is present the same archive.
d = np.load( "files/face-images-with-marked-landmark-points/face_images.npz")
dataset = d[ 'face_images' ].T
dataset = np.reshape( dataset , ( -1 , 96 , 96 , 1 ) )images = dataset[ all_keypoints_present_ids , : , : , : ]
keypoints = facial_keypoints.iloc[ all_keypoints_present_ids , : ].reset_index( drop=True ).valuesx_train, x_test, y_train, y_test = train_test_split( images , keypoints , test_size=0.3 )# Save all the processed data.
np.save( "processed_data/x_train.npy" , x_train )
np.save( "processed_data/y_train.npy" , y_train )
np.save( "processed_data/x_test.npy" , x_test )
np.save( "processed_data/y_test.npy" , y_test )
我们还将图像以及坐标(关键点)进行了标准化处理。我们对y_train和y_test进行了重塑操作,因为它们将成为卷积层(Conv2D)而不是全连接层(Dense
)的输出。
x_train = np.load( "face_landmarks_cleaned/x_train.npy" ) / 255y_train = np.load( "face_landmarks_cleaned/y_train.npy" ) / 96x_test = np.load( "face_landmarks_cleaned/x_test.npy" ) / 255y_test = np.load( "face_landmarks_cleaned/y_test.npy" ) / 96y_train = np.reshape( y_train , ( -1 , 1 , 1 , 30 ))y_test = np.reshape( y_test , ( -1 , 1 , 1 , 30 ))
提示:我们找到了另一个用于人脸特征检测的数据集,称为UTKFace。它包含68个面部关键点以及其他特征,例如年龄和性别。可以尝试一下!
讨论模型
下面让我们讨论该模型的结构。我对该模型做了一些实验。我们需要一个模型,该模型采用尺寸为(96,96)的图像作为输入并输出形状为(30,)的数组(15个关键点* 2个坐标)
1.第一种模型读取一张图像,并将其通过预先训练的VGG网络。接下来,将VGG的输出展平并通过多个全连接层。问题在于,即使损失很小,模型也可以为每个图像预测相同的关键点。
2.第二种模型是您可以在Colab notebook中找到的模型。我们不使用全连接层。相反,我们将图像传递给卷积层,并获得形状为(1,1,30)的输出。因此,卷积层为我们提供了输出。使用此模型,对于每张图像甚至在数据集之外的图像,预测值都是不同的!
我们的模型是这样的。
model_layers = [tf.keras.layers.Conv2D( 256 , input_shape=( 96 , 96 , 1 ) , kernel_size=( 3 , 3 ) , strides=2 , activation='relu' ),tf.keras.layers.Conv2D( 256 , kernel_size=( 3 , 3 ) , strides=2 , activation='relu' ),tf.keras.layers.BatchNormalization(),tf.keras.layers.Conv2D( 128 , kernel_size=( 3 , 3 ) , strides=1 , activation='relu' ),tf.keras.layers.Conv2D( 128 , kernel_size=( 3 , 3 ) , strides=1 , activation='relu' ),tf.keras.layers.BatchNormalization(),tf.keras.layers.Conv2D( 128 , kernel_size=( 3 , 3 ) , strides=1 , activation='relu' ),tf.keras.layers.Conv2D( 128 , kernel_size=( 3 , 3 ) , strides=1 , activation='relu' ),tf.keras.layers.BatchNormalization(),tf.keras.layers.Conv2D( 64 , kernel_size=( 3 , 3 ) , strides=1 , activation='relu' ),tf.keras.layers.Conv2D( 64 , kernel_size=( 3 , 3 ) , strides=1 , activation='relu' ),tf.keras.layers.BatchNormalization(),tf.keras.layers.Conv2D( 32 , kernel_size=( 3 , 3 ) , strides=1 , activation='relu' ),tf.keras.layers.Conv2D( 32 , kernel_size=( 3 , 3 ) , strides=1 , activation='relu' ),tf.keras.layers.BatchNormalization(),tf.keras.layers.Conv2D( 30 , kernel_size=( 3 , 3 ) , strides=1 , activation='relu' ),tf.keras.layers.Conv2D( 30 , kernel_size=( 3 , 3 ) , strides=1 , activation='relu' ),tf.keras.layers.Conv2D( 30 , kernel_size=( 3 , 3 ) , strides=1 ),]
model = tf.keras.Sequential( model_layers )
model.compile( loss=tf.keras.losses.mean_squared_error , optimizer=tf.keras.optimizers.Adam( lr=0.0001 ) , metrics=[ 'mse' ] )
在执行回归任务时,我们使用 均方误差(MSE)。如果您有大量的数据,那么较小的学习率总是好的。
训练和相关推论
我们训练模型约250次,批处理数量为50个。训练后,我们将在测试集上进行一些预测。
import matplotlib.pyplot as pltfig = plt.figure(figsize=( 50 , 50 ))for i in range( 1 , 6 ):sample_image = np.reshape( x_test[i] * 255 , ( 96 , 96 ) ).astype( np.uint8 )pred = model.predict( x_test[ i : i +1 ] ) * 96pred = pred.astype( np.int32 )pred = np.reshape( pred[0 , 0 , 0 ] , ( 15 , 2 ) )fig.add_subplot( 1 , 10 , i )plt.imshow( sample_image.T , cmap='gray' )plt.scatter( pred[ : , 0 ] , pred[ : , 1 ] , c='yellow' )plt.show()
生成预测值
注意:请记住输入图像的旋转角度。在旋转90度的图像上训练的模型无法为没有进行旋转的图像生成正确的预测。
如果您未对模型和训练参数进行修改,则经过250次训练后的模型应如下图所示:
结果
印象相当深刻吧?就这样!您刚刚从头开始构建了一个人脸特征检测模型。 在Colab notebook中,我设置了一个代码单元,您可以将网络上的图像或摄像头拍摄的图像放入其中并运行模型。
【end】◆精彩推荐◆推荐阅读旷视提Circle Loss,统一优化视角,革新深度特征学习范式 | CVPR 2020清华学霸组团的工业AIoT创企再获数千万融资:玩家应推动在边缘 AI 芯片上跑算法腾讯内测全新 Tim 3.0,支持微信登录;滴滴顺风车上线夜间服务;Angular 9.1发布为何你的 SaaS 想法总是失败?没想清楚这 4 个原因可能会继续失败!GitHub 疑遭中间人攻击,无法访问,最大暗网托管商再被黑!万字好文:智能合约编写之Solidity的编程攻略,建议收藏!你点的每个“在看”,我都认真当成了AI
相关文章:

scope重定义
.directive(myAttr, function() {return {restrict: E,scope: {customerInfo: info},template: Name: {{customerInfo.name}} Address: {{customerInfo.address}}<br> Name: {{vojta.name}} Address: {{vojta.address}}}; }); directive中的几个属性: restric…
基于轮廓调整的SOTA实例分割方法,速度达32.3fps | CVPR 2020
作者 | VincentLee来源 | 晓飞的算法工程笔记介绍实例分割是许多计算机视觉任务中的重要手段,目前大多数的算法都采用在给定的bbox中进行pixel-wise分割的方法。受snake算法和Curve-GCN的启发,论文采用基于轮廓的逐步调整策略,提出了Deep sna…

Redis运行流程源码解析
原文作者:凡趣科技 pesiwang 原文地址:http://blog.nosqlfan.com/html/4007.html 本文分析源码基于 Redis 2.4.7 stable 版本。 概述 Redis通过定义一个 struct redisServer 类型的全局变量server 来保存服务器的相关信息(比如:…

2010年5月blog汇总:OpenExpressApp、其他
OpenExpressApp 信息系统开发平台OpenExpressApp - 框架待完善工作事项信息系统开发平台OpenExpressApp - 报表模块支持ReportObjectView信息系统开发平台OpenExpressApp - 从compositewpf到MEF信息系统开发平台OpenExpressApp - …

注意!Linux glibc再曝漏洞,可导致Linux软件劫持
2019独角兽企业重金招聘Python工程师标准>>> glibc是GNU发布的libc库,即c运行库。它是Linux系统中最底层的API,几乎其它运行库都会依赖于glibc。 近日,Google和Red Hat的安全人员发现GNU C Library (glibc)中存在严重的安全漏洞&a…

redis常用命令参考
操作Redis数据库 下面我们来简单的操作一下数据库。在实例开启的情况下: 1、插入数据 redis 127.0.0.1:6379> set name wwl OK 设置一个key-value对。 2、查询数据 redis 127.0.0.1:6379> get name "wwl" 取出key所对应的value。 3、删除键…

Script:收集UNDO诊断信息
以下脚本可以用于收集Automatic Undo Management的必要诊断信息,以sysdba身份运行: spool Undo_Diag.out ttitle off set pages 999 set lines 150 set verify off set termout off set trimout on set trimspool onREM REM ----------------------------------…
又要头秃?2020年七大AI编程语言大盘点
作者 | Claire D译者 | 苏本如,编辑 | 伍杏玲来源 | CSDN(ID:CSDNnews)人工智能已成为我们日常生活不可或缺的一部分,它被广泛地应用到几百种实际场景中,极大地便利人们的工作和生活。随着近年来的发展&…

I.MX6 bq27441 driver hacking
/************************************************************************** I.MX6 bq27441 driver hacking* 声明:* 本文主要是记录对电池计量芯片bq27441芯片驱动注册过程进行代码跟踪。** 2016-2-…
PHP5.5的一点变化
之前一直使用eAccelerator,参考:PHP安装eAccelerator 注意PHP5.5以后暂时不能使用eAccelerator 原因:其中一个我知道的是eAccelerator中使用了: php_register_info_logo(EACCELERATOR_VERSION_GUID, "text/plain", (un…

虚拟机的操作系统的安装
虚拟机的操作系统的安装启动虚拟机进入下一步,按Enter键开始安装。按F8许可协议选则C创建分区再按C,将未划分的分区划分按ENTER继续,选择NTFS文件系统格式化磁盘分区写上姓名和单位,单击下一步直接点击关闭<?xml:namespace pr…
2020,国产AI开源框架“亮剑”TensorFlow、PyTorch
「AI技术生态论」 人物访谈栏目是CSDN发起的百万人学AI倡议下的重要组成部分。通过对AI生态专家、创业者、行业KOL的访谈,反映其对于行业的思考、未来趋势的判断、技术的实践,以及成长的经历。 2020年,CSDN将对1000人物进行访谈,形…

Centos下部署Solr 搜索引擎
一、环境准备:系统环境:centos 6.5tomcat 7.0.47jdk-7u9solr-4.7.0首先将软件包上传到/tmp目录下1、 jdk安装[rootsvn-server /]# cd /tmp/ [rootsvn-server /]#tar zxvf jdk-7u9-linux-x64.tar.gz[rootsvn-server /]#mv jdk1.7.0_09 /u…

Redis源码分析-TCMalloc
redis很多地方都在调用zmalloc函数 zmalloc在这里定义zmalloc.c void *zmalloc(size_t size) {void *ptr malloc(sizePREFIX_SIZE);if (!ptr) zmalloc_oom_handler(size); #ifdef HAVE_MALLOC_SIZEupdate_zmalloc_stat_alloc(zmalloc_size(ptr));return ptr; #else*((size_t…
让AI训练AI,阿里和浙大的“AI训练师助手”是这样炼成的
不久前,人力资源社会保障部发布了一种炙手可热的新职业:AI训练师。没想到,浙江大学与阿里安全的人工智能训练师马上创造出一个 “AI训练师助手”,高效打造AI深度模型,应对海量应用场景的增加,让AI训练模型面…

用 Navicat for Oracle 管理 Oracle10g/11g 数据库
Navicat for xxx 是一个优秀的数据库管理客户端,有 MySQL、Oracle 等版本。建议大家最好用 Enterprise 版本,功能全面一些,但较之于免费的 Lite 版,企业版可是要花银子买的。 安装 Navicat for Oracle 后,首先需要建一…

借一个同事的经历,谈一谈程序员的成长
一个很久之前的同事,今天找我,想让我帮他推荐下,去我们公司来工作,因为认识很久,就和他说了说公司的现状,也询问了一下他的状况,寒暄几句,让他下周等面试。 这位同事是之前一起做游戏…

select,epoll,poll比较
select,poll,epoll简介 select select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理。这样所带来的缺点是: 1 单个进程可监视的fd数量被限制 2 需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内…
华为开发者大会HDC.Cloud技术探秘:云搜索服务技术实践
搜索是一个古老的技术,从互联网发展的第一天开始,搜索技术就绽放出了惊人的社会和经济价值。随着信息社会快速发展,数据呈爆炸式增长,搜索技术通过数据收集与处理,满足信息共享与快速检索的需求。基于搜索技术…

从今天开始,自己做SEO。
1.购买了一点黑链。开始优化之路。 2.更改了关键词,描述。 3.整理了友情链接。 4.购买了VPS服务器:点击查看 转载于:https://www.cnblogs.com/zq535228/archive/2010/06/09/1754986.html

Elasticsearch2.2.0配置文件说明
为什么80%的码农都做不了架构师?>>> 官方配置文档 https://www.elastic.co/guide/en/elasticsearch/reference/current/setup.html 配置详解 # ---------------------------------- Cluster (集群配置)----------------------…

各种类型的字节数
int类型比较特殊,具体的字节数同机器字长和编译器有关。如果要保证移植性,尽量用__int16 __int32 __int64吧,或者自己typedef int INT32一下。 C、C标准中只规定了某种类型的最小字节数(防止溢出) 64位指的是cpu通用寄…
154 万 AI 开发者用数据告诉你,中国 AI 如何才能弯道超车?| 中国 AI 应用开发者报告...
曾经,软件吞噬世界。现在,AI 吞噬软件。作者 | 屠敏数据 | 杨阳、刘学涛可视化&策划 | 唐小引出品 | CSDN(ID:CSDNnews)从三年前年薪 25 万只是白菜价,到去年华为以年薪最高达 201 万招揽顶尖应届毕业生…

中国移动用户能不能用WCDMA网?(世界杯与通信2)
到南非有移动的用户也有联通的用户,联通的网络快这是肯定的,不过联通的通话价格也比移动的高,就有人希望拿着移动的号去南非,最好也能享受WCDMA的网络速度,这样就是两全其美了,对于这个问题,在国…

平安陆金所-点金计划,简直是骗子行为。
陆金所点金计划,让人防不胜防。平安保险,骗子中的教练。 转载于:https://www.cnblogs.com/hthf/p/5205921.html
深度分析define预处理指令
#define语句 预处理 宏替换 --以上出自《C语言入门经典(第四版)》 #和## --出自《C语言程序设计:现代方法(第2版)》 #undef取消定义 --以上出自《21天学通C语言(第6版)》

建立YUM服务器CENTOS
1 ,YUM Client:要保证安装有如下软件包:yum-3.2.19-18.el5.centosyum-metadata-parser-1.1.2-2.el52 ,YUM Server:要保证安装有如下软件包:yum-3.2.19-18.el5.centosyum-metadata-parser-1.1.2-2.el5yum-fastestmirror…
数据库设计的10个最佳实践
作者 | Emily Williamson译者 | 孙薇,责编 | 屠敏出品 | CSDN(ID:CSDNnews)以下为译文:数据库是应用及计算机的核心元素,负责存储运行软件应用所需的一切重要数据。为了保障应用正常运行,总有一…

十进制转化为十六进制分割高低位
2019独角兽企业重金招聘Python工程师标准>>> 将十进制1000,转化为十六进制,则为0x03E8,如果得到高低位,high0x03,low0xE8 BYTE high;BYTE low;int temp_data1nWeightValue;highBYTE(temp_data1 >>8);int temp_data2nWeightV…
Nginx内存池--pool代码抽取(链表套路)
ngx_palloc.c文件 ngx_palloc_large_hm是自己写的代码没有nginx原版的ngx_palloc_large写的好,细节要品味才会发现nginx的美 nginx链表的套路,正好是两种插入“从前插”和“从后插”,有些许差别 #include <stdio.h> #include <std…