LoginSignup
2
0

More than 3 years have passed since last update.

不特定多数の顔分類問題にチャレンジ

Posted at

前提

最近機械学習の勉強を始めた超初心者による記事なので、間違った認識をしていることがあるかもしれません。
そしてもっといい分類方法があるかもしれません。

問題

  • 顔の写った写真が複数枚ある(今回は1枚につき顔は1つの写真を想定するが、複数写っていても問題ない)
  • 同じ顔が別の写真に映っている
  • 同じ顔が写っている写真をグループ化したい
  • ユニークな顔がいくつかは知らない(ここが難しそうなポイント)

どうやって解くか

とりあえず流れとしては、

  • 顔を検出

簡単に顔認識ができるライブラリであるface_recognitionを用いる

  • 顔をテンソル化

face_recognitionの128次元テンソルを用いる

  • テンソルを2次元に圧縮

PCAで圧縮する。t-SNEを用いてみたがうまく行かなかった。

  • クラスタリング

顔がいくつあるかわかっていれば、k-meansなどが使えるが、今回は不明なのでDBSCANを用いる

という感じで良さそう。

コード

予めpipでface_recognition、scikit-learn、matplotlibをインストールしておくこと

main.py
import face_recognition
from sklearn.decomposition import PCA
from sklearn.cluster import DBSCAN
import glob
from matplotlib import pyplot as plt
import numpy as np

filelist = glob.glob('./faces/*[jpg|JPG|png]')  # とりあえずfacesディレクトリの中にある画像を対象に読み込む(適宜書き換えてください)
images = [face_recognition.load_image_file(i) for  i in filelist]

faces = []  # 顔の128次元テンソルを格納
for i in images:
    faces += face_recognition.face_encodings(i)  # テンソルを取得

faces = np.array(faces)
# PCAで128次元→2次元に圧縮
compressed = PCA(n_components=2).fit_transform(faces)

# DBSCANでクラスタリング
db = DBSCAN().fit(faces)
labels = db.labels_  # 各顔がどのグループに属するのかというラベル情報

#  グループごと点をプロット & print
cluster_max = np.max(labels)
for i in range(0, cluster_max+1):
    points = compressed[labels == i]
    plt.scatter(points[:, 0], points[:, 1])


# ファイル名をプロット
for i, xy in enumerate(compressed):
    # 今回は1画像1顔なのでこれができる
    plt.annotate(filelist[i], xy)

# labelsが-1のものは分類に失敗したノイズなのでグレーでプロット
points = compressed[labels == -1]
plt.scatter(points[:, 0], points[:, 1], color="gray")
print('\nNoise')
for i, v in enumerate(labels == -1):
    if v == True:
        print(filelist[i])

plt.show()

結果

facesフォルダの中に、適当にネット上から引っ張ってきたオバマ、トランプ、ヒラリー・クリントンが写った写真を5枚づつ突っ込んでおいた。
黒人、白人、男性、女性ということでかなり分類しやすいはずだ。

スクリーンショット 2019-07-28 21.25.21.png
完全に分類できています。めでたしめでたし。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0