1. 程式人生 > >吳恩達Coursera深度學習課程 deeplearning.ai (4-4) 人臉識別和神經風格轉換--程式設計作業

吳恩達Coursera深度學習課程 deeplearning.ai (4-4) 人臉識別和神經風格轉換--程式設計作業

Part 1:Happy House 的人臉識別

本週的第一個作業我們將完成一個人臉識別系統。

人臉識別問題可以分為兩類:

  • 人臉驗證: 輸入圖片,驗證是不是A
    • 1:1 識別
    • 舉例:人臉解鎖手機,人臉刷卡
  • 人臉識別: 有一個庫,輸入圖片,驗證是不是庫裡的一員
    • 1:K 識別
    • 舉例:員工門禁

FaceNet 通過神經網路學習將圖片編碼為128維數字向量。通過比較兩個128維向量的相似度來確定兩張圖片是否是同一個人。

在這個作業中,你需要:

  • 實現三元組損失函式
  • 使用一個預訓練模型將圖片轉換為128維數字向量
  • 運用這些128維的數字向量來執行人臉驗證和人臉識別

在這個練習中,你將使用一個預訓練模型,該模型表示圖片時使用”通道在前”的維度表示,(m,nC,nH,nW) 而不是之前的 (m,nH,nW,nC)。

開源社群中兩種表示方法都很常見,沒有統一的標準。

導包
from keras.models import Sequential
from keras.layers import Conv2D, ZeroPadding2D, Activation, Input, concatenate
from keras.models import Model
from keras.layers.normalization import BatchNormalization
from keras.layers.pooling import MaxPooling2D, AveragePooling2D
from
keras.layers.merge import Concatenate from keras.layers.core import Lambda, Flatten, Dense from keras.initializers import glorot_uniform from keras.engine.topology import Layer from keras import backend as K K.set_image_data_format('channels_first') import cv2 import os import numpy as np from numpy import
genfromtxt import pandas as pd import tensorflow as tf from fr_utils import * from inception_blocks_v2 import * %matplotlib inline %load_ext autoreload %autoreload 2 np.set_printoptions(threshold=np.nan)

0 樸素人臉驗證

在人臉驗證中,給你兩張圖片,你需要給出這兩張圖片是否是同一個人。最簡單的方式是一一比較兩張圖片的畫素,如果兩張圖片的畫素距離小於一個閾值,就認為是同一個人。

image

當然,這個演算法的表現著實很差,因為圖片的畫素會隨著燈光,角度,頭部位置等元素而劇烈變化。

你會發現,不通過原始圖片進行比較,而是通過機器學習將圖片進行編碼為相同維度的向量,然後計算向量的距離來識別是否是同一個人,擁有更高的準確率。

1 將圖片編碼為128維的向量

1.1 使用ConvNet編碼圖片

FaceNet模型需要大量的資料和時間去訓練,這裡我們使用別人已經訓練好的模型,你也可以從inception_blocks.py看到模型是怎麼實現的。

你需要知道:

  • 輸入:96x96 RGB:(m,nC,nH,nW) = (m,3,96,96)
  • 輸出: (m,128)
FRmodel = faceRecoModel(input_shape=(3, 96, 96))
print("Total Params:", FRmodel.count_params())
# Total Params: 3743280

在模型的最後一層使用128個神經元的全連線層,模型確保輸出維度為128,然後就可以利用編碼後的向量比較兩個圖片了。

image

如果符合以下條件,編碼方式就是好的:

  • 同一個人的兩張照片的編碼非常相似
  • 不同人的兩張照片編碼差別很大

三元組損失函式(triplet loss function) 很好的實現了上述要求,將同一個人的兩張照片 (anchor 和 Positive) 的編碼 推得很近,將不同人的兩張照片 (anchor 和 Negative) 的編碼拉的很遠。

image

1.2 三元組損失

對於一張圖片 x,另其編碼為f(x), 其中f是從神經網路計算出來的

image

三元組圖片:(A, P, N)

  • A:Anchor – 一個人的圖片
  • P:Positive – 與Ancher同一個人的圖片
  • N:Negative – 與Ancher不同人的圖片

我們訓練集中已經有這些三元組資料,用(A(i), P(i), N(i)) 來表示訓練集第i個樣本。

你需要確保 A(i) 到 P(i) 的距離至少比到 N(i) 的距離遠一個alpha。

f(A(i))f(P(i))22+α<∣∣f(A(i))f(N(i))22

我們將最小化如下的三元組損失 J:

z=i=1N[f(A(i))f(P(i))22(1)f(A(i))f(N(i))22(2)+α]
J=max(z,0)
注意:
  • 公式中(1)部分是”A”到”P”的平方距離,我們想要縮小
  • 公式中(2)部分是”A”到”N”的平方距離,我們想要擴大,所以這裡用了減法,而減完之後是個距離的負值
  • alpha 是一個距離閾值的超引數,需要手動設定,這裡使用0.2

很多實現都是先將圖片編碼進行歸一化再比較的,這裡我們不用考慮。

練習:實現三元組損失函式
  1. 計算”A”到”P”的距離
    f(A(i))f(P(i))22
  2. 計算”A”到”N”的距離
    f(A(i))f(N(i))22
  3. 計算 z
    z=∣∣f(A(i))f(P(i))∣∣f(A(i))f(N(i))22+α
  4. 計算 z 與 0 的最大值