一文學會使用CNN進行人臉關鍵點識別
項目概況
該項目的目標是預測面部圖片上關鍵點的位置。這可以用作各種應用程序中的組件,包括:
圖片和視頻中的人臉識別。
面部表情的研究。
用于醫(yī)學診斷,識別畸形面部癥狀。
識別面部關鍵點是一個很難解決的話題。人與人的面部特征差異很大,即使在一個人內,由于 3D 姿勢、大小、位置、視角和照明環(huán)境,也會存在很多差異。盡管計算機視覺研究在解決這些問題方面取得了長足的進步,但仍有許多可以改進的領域。
目錄
介紹
先決條件
程序和編程
面部關鍵點檢測的有用應用
介紹
利用卷積神經網絡和計算機視覺技術進行人臉關鍵點檢測,對人臉的重要區(qū)域(如眼睛、嘴角和鼻子)進行標記,這些區(qū)域與各種任務(如人臉濾波、情感識別和姿勢識別)相關。
它需要預測特定面部的面部關鍵點坐標,例如鼻尖、眼睛中心等。為了識別面部關鍵點,我們使用基于卷積神經網絡的模型使用自動編碼器。
卷積神經網絡 (CNN) 具有深層結構,允許它們提取高級信息并在識別每個重要點時提供更好的精度。卷積網絡旨在同時預測所有點。
先決條件
因為神經網絡經常需要標準化的圖片,所以它們應該有一個恒定的大小,顏色范圍和坐標的標準化范圍,并從 NumPy 列表和數(shù)組轉換為 Tensor 和 Keras(用于 PyTorch)。因此,需要進行一些預處理。
程序和編程
我正在使用 Kaggle 數(shù)據集來訓練模型,你可以通過運行 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))
你寫入當前目錄的任何輸出都會被存儲。下一步是為訓練和測試數(shù)據的每個文件設置路徑,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 文件,然后加載數(shù)據集。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)
加載數(shù)據集后,我們可以使用pandas的庫查看數(shù)據框,并列出數(shù)據集的頭部。train_df.info()
填充 Nan 值并分離和重塑輸入值(x_train) train_df.fillna(method='ffill',inplace=True)
在訓練數(shù)據集中分離和重塑輸入值(x_train):使用圖像創(chuàng)建一個數(shù)組,keypoints:關鍵點將是我們數(shù)據集的一個樣本。我們的數(shù)據集將接受一個可選的參數(shù)轉換,允許我們對樣本執(zhí)行任何必要的處理。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)
創(chuàng)建一個以圖片為輸入輸出關鍵點的CNN:輸入圖片大小為224*224px(由transform決定),輸出類分數(shù)為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')
在我們編寫了可視化函數(shù)之后,接下來,我們可以使用函數(shù)調用來可視化每個圖像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)
數(shù)據已經預處理完畢,F(xiàn)在是創(chuàng)建訓練模型的時候了。為了創(chuàng)建我們的 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 開始,以快速評估你的模型是如何訓練的,并確定你是否應該改變其結構或超參數(shù)。在訓練時跟蹤模型的損失如何隨時間變化:它是否首先快速減少,然后減速?在訓練多個時期并創(chuàng)建最終模型之前,使用這些初始觀察對模型進行更改并決定最佳架構。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)
示例輸出:
在整個訓練數(shù)據集中執(zhí)行了總共 50 次迭代。我們已經學會了如何簡單地使用 CNN 來訓練深度學習模型。現(xiàn)在是時候使用我們的數(shù)據收集對模型進行測試了。我們必須首先準備我們的測試集。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 x in img]
imageArr.append(img)
x_test = np.array(imageArr,dtype='float')
x_test = x_test.reshape(-1,96,96,1)
print(x_test.shape)
我們知道要在測試數(shù)據集中分離目標值 (y_test)y_test = np.array(keypoints_df,dtype='float')
print(y_test.shape)
現(xiàn)在,是時候預測訓練模型的結果了:pred = model.predict(x_test)
idLookupTable.head()

請輸入評論內容...
請輸入評論/評論長度6~500個字