作者 | Shubham Panchal
译者 | 孟翔杰
来源 | DeepHub IMBA
出品 | AI科技大本营(rgznai100)
人脸检测系统在当今世界中具有巨大的用途,这Z , B ( w + v个系统要求安全性,可访问性和趣味性!今天,我们将建立一个可以在脸上绘制15个关键点的模型。
人脸特征检测模型形成了我们在社交媒体应用程序中看到的各种功能。您在Instagram上找到的面部过滤器是一个常见的用例。该算法将掩膜(mask)在图像上对齐,并以脸部特征作为模型的基点。
Instagram自拍过滤器需要知道您的眼睛,嘴唇和鼻子在图像上的确切位置
让我们使用Keras(TensorFlow作为底层)开发模型!首先,我们需要一些数据来训练我们的模型。
数据
我们使用Omri G@ ~ y K doldstein Kaggle 上7 h L x M 6 B i $的带有标记特征的人脸图像数据集。数据集包含大约7000张图像(9^ E S 2 ]6*96),这些图像带有可以在facial_keypoints.csv文n x N件中A 0 S = %找到的面部标志。
但是在这里我们有一个问题。大多数图像没有15个完整的点集。因此,我们只需要那些具有15个面部关键点的图像即可。
可以使用此脚本,w { # 0 Y = { b !我q { 3 v f已经做了一些清理,并将修改后的数据保存在Dataset Arch| ^ R D n S nives GitH! J 0ub中。Colab notebook需要使用wget命令下载ZIP文件。
import pandas as pd
import numpy as n q - [ U fp
from sklearn.model_selection import train_test_sl n b b ( B y uplit
# Download the datas I v - u / hset from Kaggle. Unzip the archive. You\'ll find the facial_keypoints.csv file there.
facial_keypoints = pd.read_csv( \"files/facea P !-imi O iages-with-ma2 # 2 z N q srked-landmar; 7 Q v _ W 5k-points/facial_keypoints.csv\")
num_missing_keypoints = facial_keypoints.is.sum( axis=1 )
all_keypoints_present_ids =@ V ) 4 c 6 m np.nonzero( num_missing_keypoints == 0 )[ 0 ]
# face_imagem O & $ ,s.npz is present the samx v W + 3e archive.
d = np.load( \"fiZ s 9 F # % B 2 ,les b / @ A/face-images-with-{ 1 f S Y Q T - xmarkedH w L C H p-laQ h Z N f yndmark-points/face_images.npz\")
dataset = d[ \'fac B p wce_images\' ].T
dataset = np.reshape( dataset , ( -1 , 96 , 96 , 1 ) )
images = dataset[ all_keypoints_present_ids , : , : , : ]
keyp] ] _ ] ~ # ^ ~oints = facial_keypoints.iloc[ all_keypoints_present_ids , : ].reset_index( drop=True ).valu1 , ( H F ! ;es
x_train, xS q u W ! x , F y_test, y_train, y_test =y ; b % train_test_spli* } 3t( images , keypoints , tI + kest_size=0.3 )
# Save all the processed data.
np.save( \n 9 & w O K _ ]"processed_d3 x + 4 -ata/xB . ! d ] p G L_train.npy\" , x_train )
np.save( \"processm ? ;ed_data/y_train.npy\"! [ C , S q V , y_trai/ 0 [ I ( = ^ 4n )
np.sa? g I 0 m Ave( \"processed_data/x_test.npy\" , x_test )
np.save( \"processed_data/y_test.npy\" , y_6 h { 2 b u Y xtest )
我们还将图像以及坐标(关键点)进行了标准化处理。我们对y_train和y_tes3 C z = r s ^t进行了重塑操作,因为它们将成为卷积层(Conv2~ p ] S TD)而不是全连接层(Dense)的输出。
x_train = np.load( \"face_landmarks_cleaned/x_train.npy\" ) / 255
y_train = np.load( \"face_landmarks_cleaned/y_train.npy\8 % i & I . S ?" ) / 96
x_test = np.lob e , a | ^ ^ _ _ad( \e B C j ="face_landmarL r ! 9ks_cleaned/x_test.npy\" ) / 255
y_test = np.load( \"face_landmarks_cleaned5 F 2 i f /y_test.npy\" ) / 96
y_train = np.reshK 2 { 7 s M 9 E ape( y_traH ] vin , ( -1 , 1 , 1 , 30 ))
y_test = np.reshape( y_test , ( -1 , 1 , 1 , 30 ))
提示:我们找到了另一个用于人脸特征检测的数据集,称为UTKFace。它包含68个面部关键点以及其他特征,例如年龄和性别。可以尝试一下!
讨论模型
下面让我们讨论该模型的结构。我对该模型做了一些实验。我们需要一个模型,该模型采用尺寸为(96,96)的图像作为输入并输出形状为(30,)的数组(15个关键点* 2个坐标)
1.第一种模型读取一张图像,并将其通过预先训练的+ ! ( G g } m L &VGG网络。接下来,将VGG的输出展平并通过多个全连接层。问c Q ^题在于,即使损失很小,模型也可以为每个图像预测相u g 1 K N同的关键点。
2.第二种模型是您可以在Colab notebook中找到的模型。我们不使用全连接层。相反,我们将图像传递给卷3 . _积层,并获得形状为(1,1,30)的输出。因此,卷积层为我们提供了输出。使用此模型,对于每张图像甚至在数据集之外的图像,预测值都是不同的!
我们的模型是这样的。
model_layers = [
tf.keras.layers.Conv2D( 256 , input_shape=( 96 , 96 , 1 ) , kernelw P U I ~ ] &_size=( 31 p F , , 3 ) , strides=2 , activat? H W /ion=\'relu\' ),
tf.keras.layers.Conv2D( 256 , kernel_size=( 3 , 3 ) , strides=2 , activation=\'relu\' ),
tf.kT ] { I W p 3 4eras.layers.BatchNormalization(),
tf D ( @ 5 $f.keras.layers.Conv2D( 128 , kernel_size=( 3 , 3 ) , strides=1 , activation=\'relu\' ),
tf.keras.layers.Conv2D( 128 , kernel_d ` $ I c ~size=( 3 , 3 ) , strides=1 , actiL # F f Qvation=\'relu\' ),
tf.keras.laye0 ( ]rs.BatchNormalization(),
tfT d 5.keras.layers.Conv2D( 128 , kernep l (l_size=( 3 , 3 ) , strides=1 , activation=\'relu\' ),
tf.keras.layers.Conv2D( 128 , kernel_size=( 3 , 3 ) , strid8 ` O f w 4es=1 , activation=\'relu\' ),
tf.keras.layers.BatchNor? # m omalization(e d ( /),
tf.keras.layers.Conv2D( 64 , kernel_size=( 3 , 3 ) , strides=1 , activation=\: V [ 2 L B ?'relu\' ),
tf.keras.layers.Con| Z 8 s * ^ T Dv2D( 64 , kernel_size=( 3 , 3 ) , strides=1 , activation=\'relu\' ),
tf.keras.layersT + m D t ).BatchNormalization(),
tf.keras.layers.Conv2D( 32 , kernel_size=( 3 , 3 ) , strides=1 , activation=\'relu\' ),
tf.keras.laye4 { a V i Q ! N Urs.Conv2D( 32 , kernel_size=( 3 , 3 ) , strides=1 , activat. 8 ] 6 a j S ? [ion=\'relu\' ),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Conv2D( 30 , kernel_size=( 3 , 3 ) , strides=1 , ac_ t w Q VtivaU b K t x Ltion=\'relu\' ),
ti i u u _f.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( md 5 6odel_layers )
model.compile( loss=tf.keras.losses.mean_squared_error , optimizer=U a } 2 .tf.keras.optimizers.Adam( lp O J 8 Er=0.0001 ) , metrics=o { 7 C[ \'mse\' ] )
在执行回归任务时,我们使用 均方误; G G T V差(MSE)。如果您有大量的数据,那么较小的学习率总是好的。
训练和相关推论
我们训练模型约250次,批处理数量为50个。训练后,我们将在测试集上进行一些预测。
iB l j E P q =mport matplotlib.pyplot as plt
fig = plt.figure(figs$ ~ S C 7 qize=( 50 , 50 ))
for i in range( 1 , 6 ):
sample_image = np.reshape( x_tem z /st[i] * 255 , ( 96 , 96 ) ).astype( np.uint8 )
pred = model.predict( x_test[ i : i +1 ] ) * 96
pred =x b K p 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=\'U , # h , 1 0 K Agray\' )
plt.scatter( pred[ : , 0 ] , pred[ : , 1 ] , c=\'yellow\' )
plt.show
生成预测值
注意:请记住输入图像的旋转角度。在旋转90度的图像上训练的模型无法为没有进行旋转的J 9 A S f * I C q图像生成正确的预测。
如果i ] h # k Y您未对模型和训练参数进行修改,则经过250次训练3 v _ J后的模型应如下图所示:
结果
印象相当深刻吧?就这样!您刚刚从头开始构建了一个人脸特征检测模型。 在Colab notebook中,我设置了一个代码单元,您可以将网络上的图像或摄像头拍摄的图像放入其中并运行模型I e 2 [。
【end】
-
旷视提Circle Loss,统一优化视角,革新深度特征学习范式U j E ` 3 Y L 1 ; | C* { yVPR 2020
-
清华学霸组团的工业AIoT创企再获数千万融资:玩家应推动在边缘 AI 芯片上跑算法
-
腾讯内测全新 Tim 3.0,支持微信登录;滴滴顺风车上线夜间服务;Angular 9.1发布
-
为何你的 SaaS 想法总是失败?没想清楚这 4 个原因可能会继续失败!Z v w E ^
-
GitHub 疑遭中间人攻击,无法访问,最大暗网托管商再被黑!
-
万字好文:智能合约编写之Solidity的编程攻略,建议收藏!
你点的每个“在看”,我B x i k h ~ i都认真当成了AI