使用深度學習檢測面部特徵,讓實時視訊聊天變得更有趣
也許你想知道如何在實時視訊聊天或者檢測情緒的時候把有趣的東西放在臉上?我們可以利用深度學習以及一種較老的方法實現它。
過去,檢測人臉及其特徵(如眼睛、鼻子、嘴,甚至從它們的形態中獲知情感)一項是極具挑戰性的任務。現在,這個任務可以通過深度學習解決,任何有天賦的青少年都可以在幾個小時內完成這項任務。我將在這篇文章中向你展示這種方法。
“古典”方法(CLM)
如果你像我一樣,需要執行面部跟蹤(將姿態從網路攝像機轉換成動畫角色),你可能會發現一個用於限制當地模型(CLM:連結地址為https://sites.google.com/site/xgyanhome/home/projects/clm-implementation/ConstrainedLocalModel-tutorial%2Cv0.7.pdf?attredirects=0)的最佳演算法,由如 Cambridge Face Trackeror(連結地址為https://github.com/TadasBaltrusaitis/CLM-framework)實現其新的OpenFaceincarnation(連結地址為https://github.com/TadasBaltrusaitis/OpenFace)。這是基於將檢測任務分割為檢測形狀向量特徵(ASM:連結地址為http://slidegur.com/doc/3183242/face-and-facial-feature-tracking-asm–aam–clm)和補丁影象模板(AAM:連結地址為http://slidegur.com/doc/3183242/face-and-facial-feature-tracking-asm–aam–clm),並使用預先訓練的線性SVM來改進檢測。
它通過粗略估計關鍵點的位置來工作,然後使用SVM預先訓練的影象中包含臉部的部分並且調整關鍵點的位置。重複這一過程直到錯誤降到足夠低。此外,值得一提的是,它假定影象上的臉部位置已經被估計,例如使用viola – jones(連結地址為https://en.wikipedia.org/wiki/Viola%E2%80%93Jones_object_detection_framework)探測器(Haar cascade:連結地址為https://en.wikipedia.org/wiki/Haar-like_feature)。CLM過程非常複雜,而且非常重要,絕對不會由一個高階中學的嚮導來實現。你可以看到這裡的整體架構:
深度學習
我們可以使用一個非常簡單的卷積神經網路(CNN:連結地址為https://en.wikipedia.org/wiki/Convolutional_neural_network),並在我們希望在包含人臉的影象上執行關鍵點的檢測。為此我們需要有一個訓練資料集;我們可以使用“Kaggle”(連結地址為https://www.kaggle.com/)提供的一個包含15個關鍵點的“面部關鍵點檢測挑戰”(連結地址為https://www.kaggle.com/c/facial-keypoints-detection/data),或者一個帶有76個關鍵點的複雜的“MUCT資料集”(連結地址為http://www.milbo.org/muct/)。
很明顯,擁有高質量的訓練資料集在這裡是必不可少的。
這裡是一個樣本的巴洛克式樣貌和它在Kaggle資料集的關鍵點的樣子:
資料集包含有96×96解析度的灰度影象和15個關鍵點,其中每個眼睛有5個關鍵點,嘴巴鼻子有5個關鍵點。
對於任意一張影象,我們首先需要檢測人臉影象的位置;前面提到的基於Haar cascades的viola – jones探測器可以使用(它的工作原理和CNNs類似)。或者,如果你更有冒險精神,你可以使用完全卷積網路(FCN:連結地址為https://people.eecs.berkeley.edu/~jonlong/long_shelhamer_fcn.pdf),並進行深度評估的影象分割。
總之,使用OpenCV是一件很簡單的事:
Grayscale_image= cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
face_cascade= cv2.CascadeClassifier(‘haarcascade_frontalface_default.xml’)
bounding_boxes= face_cascade.detectMultiScale(grayscale_image,1.25,6)
這段程式碼返回影象上所有可能的面部邊界框。
接下來,對於Viola-Jones返回的每個邊界框,我們提取出相應的子影象,將它們轉換成灰度,並將它們調整到96×96。他們將會成為我們完成CNN的輸入。
CNN的架構非常瑣碎;一堆5×5的卷積層(實際上3個,分別帶有24個、36個和48個過濾器),然後2個或者更多的3×3卷積層(64個過濾器)和3個完全連線層(分別有500個、90個和30個節點)。一些max pooling可以防止過度擬合和全域性平均池,以減少flatten引數的數量。輸出將是30個浮點數,表示每個15個關鍵點的x,y座標。
以下是Keras(連結地址為https://keras.io/)的實現:
model= Sequential()
model.add(BatchNormalization(input_shape=(96,96,1)))
model.add(Convolution2D(24,5,5, border_mode=”same”, init=’he_normal’, input_shape=(96,96,1), dim_ordering=”tf”))
model.add(Activation(“relu”))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), border_mode=”valid”))
model.add(Convolution2D(36,5,5))
model.add(Activation(“relu”))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), border_mode=”valid”))
model.add(Convolution2D(48,5,5))
model.add(Activation(“relu”))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), border_mode=”valid”))
model.add(Convolution2D(64,3,3))
model.add(Activation(“relu”))
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), border_mode=”valid”))
model.add(Convolution2D(64,3,3))
model.add(Activation(“relu”))
model.add(GlobalAveragePooling2D());
model.add(Dense(500, activation=”relu”))
model.add(Dense(90, activation=”relu”))
model.add(Dense(30))
你可能希望選擇均方根傳播(rmsprop:連結地址為http://root%20mean%20square%20propagation/)優化器和均方誤差(MSE:連結地址為https://en.wikipedia.org/wiki/Mean_squared_error)作為損失函式和精度指標。
就像在輸入影象上批量標準化,全球平均池,以及 HE normal重量初始化一樣,在大約30個訓練時期,可以得到80 – 90%的驗證精度和低於0.001的損失。
model.compile(optimizer=’rmsprop’, loss=’mse’, metrics=[‘accuracy’])
checkpointer= ModelCheckpoint(filepath=’face_model.h5', verbose=1, save_best_only=True)
epochs= 30
hist= model.fit(X_train, y_train, validation_split=0.2, shuffle=True, epochs=epochs, batch_size=20, callbacks=[checkpointer], verbose=1)
<imgclass="size-full wp-image-7435 aligncenter" src="http://imgcdn.atyun.com/2017/09/6-1.png" alt="" width="402" height="278">
<imgclass="size-full wp-image-7436 aligncenter" src="http://imgcdn.atyun.com/2017/09/7.png" alt="" width="408" height="278">
然後預測關鍵點位置的簡單執行:
features= model.predict(region, batch_size=1)
現在已經掌握了檢測面部關鍵點的技術。
記住,你的預測結果將是15對x,y座標,按照如下圖所示:
如果你想做得更好,你可能想做一些額外的作業:
- 試驗如何減少卷積層數和過濾大小,同時保持精度和提高推理速度
- 用轉移學習代替卷積部分(我最喜歡的是Xception:連結地址為https://arxiv.org/abs/1610.02357)
- 使用更詳細的資料集
- 做一些高階的影象增強來提高穩健性
你可能會覺得這一切都太簡單了,如果你想要挑戰自己,那就轉到3D,看看Facebook(連結地址為https://research.fb.com/wp-content/uploads/2016/11/deepface-closing-the-gap-to-human-level-performance-in-face-verification.pdf)和英偉達(連結地址為http://research.nvidia.com/sites/default/files/publications/laine2017sca_paper_0.pdf)是如何追蹤人臉的。
很明顯,你可以用這個新學會的魔法來做一些你可能一直想做但不知道怎麼做的事情:
- 在視訊聊天中,把某些物體放在臉上,比如太陽鏡,奇怪的帽子,鬍子等等。
- 與朋友、敵人、動物和物品交換臉部
- 通過允許在自拍實時視訊上測試新的髮型、珠寶或化妝,滿足人類的虛榮心。
- 檢測你的員工是否醉酒,以致於不能執行指定的任務
- 如果你想使情感處理自動化,就需要在你的視訊中識別人們的情緒
- 使用了GANs(連結地址為https://en.wikipedia.org/wiki/Generative_adversarial_networks)的實時face-to-cartoon轉換,根據你在網路攝像頭上的臉來彎曲卡通臉,進而模仿你的動作、談話和情緒。