使用CNN进行人脸关键点识别

项目概况

该项目的目标是预测面部图片上关键点的位置。这可以用作各种应用程序中的组件,包括:

图片和视频中的人脸识别。

面部表情的研究。

用于医学诊断,识别畸形面部症状。

识别面部关键点是一个很难解决的话题。人与人的面部特征差异很大,即使在一个人内,由于 3D 姿势、大小、位置、视角和照明环境,也会存在很多差异。尽管计算机视觉研究在解决这些问题方面取得了长足的进步,但仍有许多可以改进的领域。

目录

  1. 介绍

  2. 先决条件

  3. 程序和编程

  4. 面部关键点检测的有用应用

介绍

利用卷积神经网络和计算机视觉技术进行人脸关键点检测,对人脸的重要区域(如眼睛、嘴角和鼻子)进行标记,这些区域与各种任务(如人脸滤波、情感识别和姿势识别)相关。

它需要预测特定面部的面部关键点坐标,例如鼻尖、眼睛中心等。为了识别面部关键点,我们使用基于卷积神经网络的模型使用自动编码器。

卷积神经网络 (CNN) 具有深层结构,允许它们提取高级信息并在识别每个重要点时提供更好的精度。卷积网络旨在同时预测所有点。

先决条件

因为神经网络经常需要标准化的图片,所以它们应该有一个恒定的大小,颜色范围和坐标的标准化范围,并从 NumPy 列表和数组转换为 Tensor 和 Keras(用于 PyTorch)。因此,需要进行一些预处理。

程序和编程

我正在使用 Kaggle 数据集来训练模型,你可以通过运行 API 命令下载它

kaggle competitions download -c facial-keypoints-detection

导入 NumPy 和 pandas 库:

import numpy as np # linear algebra
import pandas as pd # data processing
import os
for directoryname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(directoryname, filename))

你写入当前目录的任何输出都会被存储。

下一步是为训练和测试数据的每个文件设置路径,

train_zip_path = "../input/facial-keypoints-detection/training.zip"
test_zip_path = "../input/facial-keypoints-detection/test.zip"
id_lookup_table = "../input/facial-keypoints-detection/IdLookupTable.csv"
sample_Submission = "../input/facial-keypoints-detection/SampleSubmission.csv"

让我们使用 zip 文件解压 zip 文件,然后加载数据集。

import zipfile
with zipfile.ZipFile(train_zip_path,'r') as zip_ref:
zip_ref.extractall('')
with zipfile.ZipFile(test_zip_path,'r') as zip_ref:
zip_ref.extractall('')
train_df = pd.read_csv('training.csv')
test_df = pd.read_csv('test.csv')
idLookupTable = pd.read_csv(id_lookup_table)
sampleSumission = pd.read_csv(sample_Submission)

加载数据集后,我们可以使用pandas的库查看数据框,并列出数据集的头部。

train_df.info()

填充 Nan 值并分离和重塑输入值(x_train)

 train_df.fillna(method='ffill',inplace=True)

在训练数据集中分离和重塑输入值(x_train):

使用图像创建一个数组,keypoints:关键点将是我们数据集的一个样本。我们的数据集将接受一个可选的参数转换,允许我们对样本执行任何必要的处理。

image_df = train_df['Image']
imageArr = []
for i in range(0,len(image_df)):
     img = image_df[i].split()
     img = ['0' if x == '' else x for x in img]
     imageArr.append(img)
 x_train = np.array(imageArr,dtype='float')
 x_train = x_train.reshape(-1,96,96,1)
 print(x_train.shape)

创建一个以图片为输入输出关键点的CNN:

输入图片大小为224*224px(由transform决定),输出类分数为136,即136/2 = 68。(我们想要的68个关键点)和分离目标值

keypoints_df = train_df.drop('Image',axis = 1)
y_train = np.array(keypoints_df,dtype='float')
print(y_train.shape)

def visualizeWithNoKeypoints(index):
    plt.imshow(x_train[index].reshape(96,96),cmap='gray')
def visualizeWithKeypoints(index):
    plt.imshow(x_train[index].reshape(96,96),cmap='gray')
    for i in range(1,31,2):
        plt.plot(y_train[0][i-1],y_train[0][i],'ro')

在我们编写了可视化函数之后,接下来,我们可以使用函数调用来可视化每个图像

import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8,4))
fig.subplots_adjust(left=0,right=1,bottom=0,top=1,hspace=0.05,wspace=0.05)
plt.subplot(1,2,1)
visualizeWithNoKeypoints(1)
plt.subplot(1,2,2)
visualizeWithKeypoints(1)

数据已经预处理完毕。现在是创建训练模型的时候了。

为了创建我们的 CNN 模型,我们将使用 Keras 框架。

from keras.models import Sequential, Model
from keras.layers import Activation, Convolution2D,MaxPooling2D,BatchNormalization, Flatten, Dense, Dropout
from keras.layers.advanced_activations import LeakyReLU

最初只从一两个 epoch 开始,以快速评估你的模型是如何训练的,并确定你是否应该改变其结构或超参数。

在训练时跟踪模型的损失如何随时间变化:它是否首先快速减少,然后减速?

在训练多个时期并创建最终模型之前,使用这些初始观察对模型进行更改并决定最佳架构。

model = Sequential()
model.add(Convolution2D(32,(3,3),padding='same',use_bias=False, input_shape=(96,96,1)))
model.add(LeakyReLU(alpha = 0.1))
model.add(BatchNormalization())

model.add(Convolution2D(32,(3,3),padding='same',use_bias = False))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Convolution2D(64,(3,3),padding='same',use_bias = False))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())

model.add(Convolution2D(64, (3,3), padding='same', use_bias=False))
model.add(LeakyReLU(alpha = 0.1))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(96, (3,3), padding='same', use_bias=False))
model.add(LeakyReLU(alpha = 0.1))
model.add(BatchNormalization())

model.add(Convolution2D(96, (3,3), padding='same', use_bias=False))
model.add(LeakyReLU(alpha = 0.1))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(128, (3,3),padding='same', use_bias=False))
# model.add(BatchNormalization())
model.add(LeakyReLU(alpha = 0.1))
model.add(BatchNormalization())

model.add(Convolution2D(128, (3,3),padding='same', use_bias=False))
model.add(LeakyReLU(alpha = 0.1))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(256, (3,3),padding='same',use_bias=False))
model.add(LeakyReLU(alpha = 0.1))
model.add(BatchNormalization())

model.add(Convolution2D(256, (3,3),padding='same',use_bias=False))
model.add(LeakyReLU(alpha = 0.1))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(512, (3,3), padding='same', use_bias=False))
model.add(LeakyReLU(alpha = 0.1))
model.add(BatchNormalization())

model.add(Convolution2D(512, (3,3), padding='same', use_bias=False))
model.add(LeakyReLU(alpha = 0.1))
model.add(BatchNormalization())

model.add(Flatten())

model.add(Dense(512,activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(30))

model.summary()

下一步是配置模型:

model.compile(optimizer='adam',loss='mean_squared_error',metrics=['mae','acc'])

model.fit(x_train,y_train,batch_size=256,epochs=45,validation_split=2.0)

示例输出:

在整个训练数据集中执行了总共 50 次迭代。

我们已经学会了如何简单地使用 CNN 来训练深度学习模型。

现在是时候使用我们的数据收集对模型进行测试了。

我们必须首先准备我们的测试集。

test_df.isnull().any()

x 测试:分离和重塑输入测试值

image_df = test_df['Image']
keypoints_df = test_df.drop('Image',axis = 1)
imageArr = []

for i in range(0,len(image_df)):
    img = image_df[i].split()
    img = ['0' if x=='' else x for <a onclick="parent.postMessage({'referent':'.kaggle.usercode.9109824.32742593.[5124,5127].x'}, '*')">x in img]
    imageArr.append(img)

x_test = np.<a onclick="parent.postMessage({'referent':'.numpy.array'}, '*')">array(imageArr,dtype='float')
x_test = x_test.reshape(-1,96,96,1)
print(x_test.shape)

我们知道要在测试数据集中分离目标值 (y_test)

y_test = np.<a onclick="parent.postMessage({'referent':'.numpy.array'}, '*')">array(keypoints_df,dtype='float')
print(y_test.shape)

现在,是时候预测训练模型的结果了:

pred = model.predict(x_test)

idLookupTable.head()

我们已经学习了如何简单地使用 CNN 构建深度学习面部关键点检测模型。

面部关键点检测的一些有用应用

该技术的适用性是多种多样的。以下只是当今企业界中一些更有趣的面部识别应用。

1) 使用 CNN 检测面部关键点并在带有面部过滤器的应用程序中使用它们

用有趣的东西覆盖人脸照片的面部过滤器越来越受欢迎。它们通常出现在社交媒体平台上。此过滤器应用程序中使用了面部关键点(或“关键点”)检测技术。

可以评估一个人的面部表情(以及情绪)的面部重要区域被称为面部关键点。它们对于开发实时应用程序以检测困倦、评估生物特征和读取人们的情绪至关重要。

2) 虚拟现实和增强现实 (AR)

几个流行的智能手机应用程序中使用了面部关键点识别。Instagram、Snapchat 和 LINE 上的面部过滤器就是一些众所周知的例子。AR软件可以通过识别用户面部关键点,实时将图片滤镜正确叠加在用户面部上。

如果你是游戏或应用程序设计师,如果用户专注于将东西放置在靠近地板或桌子角落的地方,该算法的性能会好得多。由于这种架构,算法将始终在锚点附近发现足够多的关键点。

3)Snap pay(无现金支付)

尽管在大多数国家/地区尚无法使用,但目前中国的大量零售商已接受面部识别支付。SnapPay 还宣布于 2019 年 10 月 16 日在北美推出面部识别支付技术。所有新兴国家都正在引入这种支付方式。

4) 带面锁的防盗门

安全门或门是该技术的另一个应用。面部识别技术可用于允许或拒绝进入你的公寓大楼、你公司的大堂,甚至火车站的检票口。虽然这项技术在其他国家没有广泛使用。

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

猜你喜欢

转载自blog.csdn.net/woshicver/article/details/120170558