顔認識ライブラリ「InsightFace」を使いこなしながら、顔認証とAIモデルの構造を学ぶ (1)

顔認証とは

顔認証とは、この人物は主張するとおりの人物かどうかを確認することです。顔認証システムでは提供された顔の画像と、あらかじめ登録されている画像などを比較し、その人物が本当にその人物かの確認を行います。ドアを顔認証で解錠するシステムなどが一般的になってきています。

顔認識との違いは?

顔認識は、顔の画像からその人物の特徴を抽出し、その人物の特徴をもつ人物を検索することです。顔認証は、あらかじめ登録されている人物との一致を確認することです。顔認証では「この人物は主張する通りの人物ですか?」という質問に答えるのに対し、顔認識は「この人物はデータベースの中で誰ですか?」という質問に答える点で違いがあります。このように、顔認証と顔認識には明確な違いがありますが、顔認証は顔認識を利用して行われることが多いので混乱しやすいかもしれません。このコースでも、顔認証を実装するために顔認識を利用します。

InsightFaceとは

InsightFaceは、主に顔認識、顔検出、顔属性推定などの顔分析タスクに使用できるpythonライブラリです。InsightFaceにはディープラーニング(深層学習)モデルが使用されており、しかもオープンソースでそのコードは隅から隅まで公開されています。これから本格的にディープラーニング利用したアプリケーション開発等を学習されたい方、またモダンなAIシステムがどのような仕組みになっているのかを知るためには最適な教材になると思います。

InsightFaceは無料でつかえるのですか?

はい、InsightFaceはオープンソースで完全に無料です。そのライセンスもMIT licenseとなっており、商用利用が可能です。

InsightFaceの全てのソースコードはこちらで確認できます。

InsightFaceをつかってみよう(サンプルコードあり)

InsightFaceを使ってみましょう。InsightFaceをインストールします。インストールはpipコマンドで行ってください。インストールが完了したら下記のコードを実行してみてください。下記のコードは、カメラから2枚の画像を1秒おきに取得し、その画像から顔を検出し、顔の特徴(embedding)を抽出しています。このベクトルを比較することで、顔の類似度を計算することができます。下記のコードを実行してみてください。PCに付属してるカメラが起動し、2枚の画像を撮影、1枚目と2枚目に映った顔の類似度が表示されます。

sample.py

import cv2
import numpy as np
import insightface
from insightface.app import FaceAnalysis
import time

# 1枚目の画像を撮影
cap = cv2.VideoCapture(0)
img_1 = cap.read()[1]
h, w = img_1.shape[:2]
# rgbへ変換
img_1 = cv2.cvtColor(img_1, cv2.COLOR_BGR2RGB)

# 1秒末
time.sleep(1)

# 2枚目の画像を撮影
cap = cv2.VideoCapture(0)
img_2 = cap.read()[1]
h, w = img_2.shape[:2]
# rgbへ変換
img_2 = cv2.cvtColor(img_2, cv2.COLOR_BGR2RGB)

app = FaceAnalysis()
app.prepare(ctx_id=0, det_size=(640, 640))
# 1枚目の画像から顔を検出
faces = app.get(img_1)
if len(faces) == 0:
    print("顔が検出されませんでした。終了します。")
    exit()
face_1 = faces[0]
# 2枚目の画像から顔を検出
faces = app.get(img_2)
if len(faces) == 0:
    print("顔が検出されませんでした。終了します。")
    exit()
face_2 = faces[0]

# Compare face embeddings
embedding_1, embedding_2 = face_1.embedding, face_2.embedding
similarity = np.dot(embedding_1, embedding_2) / (
    np.linalg.norm(embedding_1) * np.linalg.norm(embedding_2)
)
print(f"1枚目と2枚目に映った顔の類似度は: {similarity}")
        

これだけのコードで顔認証ができてしまいましたね。insightfaceはとても簡単に顔認証を実装できるライブラリです。ただし、このコースでは、insightfaceを使うことではなく、insightfaceを分解して、AIがどのように実装されているのか、を学習することが目的です。AI学習が目的ではなく、顔認証をサクッと使いたい人は上のコードで十分ですので以降読み進める必要はないかもしれません。これ以後の内容はプログラミング中級者対象として記載していますので、少し難しい内容も含まれています。

サンプルコードの分解

それではInsightFaceを実際にソースコードを見ながら分解してみましょう。実用的なAIモデルを実装していくことは、ライブラリを通して出来上がった機能を使うのとは打って変わって実に複雑です。

上のサンプルソースコードでポイントとなる部分は2つ、一つ目は、

sample.py

app = FaceAnalysis()
app.prepare(ctx_id=0, det_size=(640, 640))
        

二つ目は、

sample.py

faces = app.get(img_1)
        

です。3行の非常にシンプルなコードですが、これらのコードは実際には何を行っているのでしょう。InsightFace内部コードを見ていきましょう!

InsightFaceの内部コードを見てみよう

InsightFaceをインストールしたら、インストール先のフォルダを開きます。インストール先のフォルダは、

console

pip show insightface

で確認できます。インストール先のフォルダを開くとソースコードが確認できるはずです。insightfaceのgithubのリポジトリでも同じものを確認することができ、インスール先フォルダの内容と同一のものになっているはずです。

InsightFaceの公式githubリポジトリの該当ページはこちら

face_analysis.pyを見てみよう

インストール先のフォルダの中にあるface_analysis.pyを開いてみましょう。このファイルの中には、FaceAnalysisクラスがあり、そこにはprepareメソッドもあります。どうやら、このクラスを使用して顔認証を行っているなということがわかります。以下がその部分です

face_analysis.py

class FaceAnalysis:
    def __init__(self, name=DEFAULT_MP_NAME, root='~/.insightface', allowed_modules=None, **kwargs):
        onnxruntime.set_default_logger_severity(3)
        self.models = {}
        self.model_dir = ensure_available('models', name, root=root)
        onnx_files = glob.glob(osp.join(self.model_dir, '*.onnx'))
        onnx_files = sorted(onnx_files)
        for onnx_file in onnx_files:
            model = model_zoo.get_model(onnx_file, **kwargs)
            if model is None:
                print('model not recognized:', onnx_file)
            elif allowed_modules is not None and model.taskname not in allowed_modules:
                print('model ignore:', onnx_file, model.taskname)
                del model
            elif model.taskname not in self.models and (allowed_modules is None or model.taskname in allowed_modules):
                print('find model:', onnx_file, model.taskname, model.input_shape, model.input_mean, model.input_std)
                self.models[model.taskname] = model
            else:
                print('duplicated model task type, ignore:', onnx_file, model.taskname)
                del model
        assert 'detection' in self.models
        self.det_model = self.models['detection']

    def prepare(self, ctx_id, det_thresh=0.5, det_size=(640, 640)):
        self.det_thresh = det_thresh
        assert det_size is not None
        print('set det-size:', det_size)
        self.det_size = det_size
        for taskname, model in self.models.items():
            if taskname == 'detection':
                model.prepare(ctx_id, input_size=det_size, det_thresh=det_thresh)
            else:
                model.prepare(ctx_id)
    // 以下省略
        

FaceAnalysisクラス実行時にAIモデルがダウンロードされる

上記のコードの内容をよく追っていくと、FaceAnalysisクラス初期化時のensure_available()機能の中でAIモデルのダウンロードを行っていることがわかります。ensure_available()の内部コードはここでは省略しますが、そのコードを読むと、使用中のPCのホームディレクトリに.insightfaceディレクトリが作成され、そちらにモデルがダウンロードされることがわかります。

ダウンロードもとのページはこちら。

https://github.com/deepinsight/insightface/releases

buffalo_l.zipの中をみると複数のonnxという拡張子がついたファイルが格納されていることがわかります。

同様にお使いのPCのホームディレクトリの'.insightface'フォルダにも同じファイルがダウンロードされているはずです。

ダウンロードされたonnxファイル

  1. 1k3d69.onnx
  2. 2d106det.onnx
  3. det_10g.onnx
  4. genderage.onnx
  5. w600k_r50.onnx

なんと5つのonnxモデルがダウンロードされていることがわかります。なるほど、insightfaceの顔認証はこの5つのAIモデルを使って動いているようですね!次回の記事ではこれら一つ一つのモデルを見ていきますので、楽しみにしていてください!

ところでONNX(オニックス)とは?

Open Neural Network Exchange の略で、機械学習フレームワークやツール間でのモデルの共有と移植を容易にするための共通フォーマットです。PyTorch、TensorFlow、MXNetなど、さまざまな人気のある機械学習フレームワークでトレーニングされたモデルをONNXフォーマットでエクスポートすることができます。これにより、モデルを別のフレームワークに移行して推論を実行するのが簡単になります。これまでの調査でわかったように、InsightFaceでもAIモデルをONNXフォーマットとして扱っています。