facenet-pytorchで顔識別

facenet-pytorchで顔識別

顔の識別(Face Identification)

facenet-pytorchを使うと顔と顔の類似度が分かる。

github_facenet-pytorch

例えばこの2つの顔画像の類似度は0.87(-1 ~ 1 の間で値が大きいほど似ている)



facenet-pytorchによる同一人物判定の実装と、その性能評価を行う。

1. 実験1 2枚の顔画像の類似度を取得

以前facenet-pytorchを使ったときの環境を使用する。

コードの全体は最後に記す。

1.1. ライブラリ

1
2
3
from facenet_pytorch import MTCNN, InceptionResnetV1
from PIL import Image
import numpy as np

1.2. モデル読み込み

顔部分切り取り用のMTCNNと特徴ベクトル取得用のResnetを使う。

1
2
mtcnn = MTCNN()
resnet = InceptionResnetV1(pretrained='vggface2').eval()

1.3. 画像読み込み・顔部分切り出し

MTCNNによって顔部分を切り出す。

1
2
3
image_path = "images/a_1.jpg"
img = Image.open(image_path)
img_cropped = mtcnn(img)

この画像が、



こうなる。



1.4. 顔画像の特徴ベクトル取得

Resnetによって特徴ベクトルを取得する。

1
2
feature_vector = resnet(img_cropped.unsqueeze(0))
feature_vector_np = feature_vector.squeeze().to('cpu').detach().numpy().copy()

float型の512次元のベクトルが手に入る。

1.5. 特徴ベクトル間の類似度を計算

2つの特徴ベクトル間の類似度を計算する。
コサイン類似度を使用する。

1
2
3
4
5
#### 2つのベクトル間のコサイン類似度を取得(cosine_similarity(a, b) = a・b / |a||b|)
def cosine_similarity(a, b):
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

similarity = cosine_similarity(feature_vector_np_1, feature_vector_np_2)

ベクトル間の類似度(-1 ~ 1 の間で値が大きいほど似ている)が手に入る。

2. 実験2 性能評価

facenet-pytorchの実力がどの程度か性能評価する。

2.1. 実験概要

フリー素材「ぱくたそ」から取得したフリー画像を使用して実験。
https://www.pakutaso.com/

4人×5枚の画像間の類似度を総当たりで計算。
本人同士の類似度が大きく、別人同士の類似度が小さくなってほしい。

2.2. 実験に使用した画像

段田隼人さん、大川竜弥さん、八木彩香さん、にゃるるさんの4名のフリー画像からできるかぎり様々な表情の画像を使用。




2.3. 実験結果

総当たりで類似度を計算した結果がこれ。
小数点第1位で四捨五入している。



類似度が大きいほど赤く、小さいほど青くなる。
斜めのラインは完全に同じ画像同士を比較しているので1になる。
同一人物の画像同士の類似度が大きく、別人の画像同士の類似度が小さいので良い感じに識別できていることが分かる。

仮に類似度0.7以上を本人とした場合、結果は以下のようにまとめられる。(同じ画像同士の比較は除く)

TP(本人を本人と判定した数)FP(他人を本人と判定した数)FN(本人を他人と判定した数)TN(他人を他人と判定した数)
68212238

正解率(Accuracy) = (TP+TN)/(TP+FP+FN+TN) = 95.63%
精度(Precision) = TP/(TP+FP) = 97.14%
再現率(Recall) = TP/(TP+FN) = 85.0%

3. コード

実験に使用したコード。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from facenet_pytorch import MTCNN, InceptionResnetV1
from PIL import Image
import numpy as np

#### MTCNN ResNet のモデル読み込み
mtcnn = MTCNN()
resnet = InceptionResnetV1(pretrained='vggface2').eval()

#### 画像ファイルから画像の特徴ベクトルを取得(ndarray 512次元)
def feature_vector(image_path):
img = Image.open(image_path)
img_cropped = mtcnn(img)
feature_vector = resnet(img_cropped.unsqueeze(0))
feature_vector_np = feature_vector.squeeze().to('cpu').detach().numpy().copy()
return feature_vector_np

#### 2つのベクトル間のコサイン類似度を取得(cosine_similarity(a, b) = a・b / |a||b|)
def cosine_similarity(a, b):
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

#### 2枚の画像からそれぞれの特徴ベクトルを取得
img1_fv = feature_vector("images/a_1.jpg")
img2_fv = feature_vector("images/a_2.jpg")

#### 2枚の画像間の類似度を取得
similarity = cosine_similarity(img1_fv, img2_fv)
print(similarity)

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×