顔認識モデルの選定:1:1・1:N評価としきい値設計
InsightFaceの認識モデルを選び、FRVT準拠で1:1・1:Nのベンチマークを設計し、しきい値を決定する実務ガイド。オープンソースのモデルパックと商用モデルの使い分けまでを解説します。
このガイドで作るもの
顔認識システムの失敗の多くは、コードではなくモデル選定としきい値調整の段階で起こります。公開リーダーボードで上位のモデルでも、運用ポイント、属性分布、撮影品質、ギャラリ規模が違えば、本番データで誤動作することがあります。
本ガイドはNIST FRVTの方法論に沿ったベンダー中立の評価フレームワークを提示し、1:1認証と1:N識別の違い、押さえるべき指標、再現性のあるテストの組み立て方、InsightFaceオープンソースパックの公開数値の目安、そしてInsightFace商用モデルが妥当となる条件と「精度が高い」が数値として何を意味するのかを示します。
始める前に
- 顔検出・整列・特徴量抽出をinsightface PythonパッケージまたはONNX Runtime経由で実行できること。
- 本番トラフィックの属性、年齢層、姿勢、照明、遮蔽(マスク・眼鏡・髪)、カメラ品質、撮影距離を代表する検証データセットがあること。
- ROC・DET・類似度スコア解析のためのnumpy/scikit-learnの基本操作。
- 「精度XX%」ではなく、FMRまたはFPIR(例:FMR = 1e-5)として明示された目標運用ポイント。
1. まず1:1か1:Nかを切り分ける
1:1認証は「この顔は本人か」に答える処理です。プローブ1件と登録テンプレ1件を照合し、類似度スコアと同一/別人の判定を返します。端末ロック解除、KYC(自撮りと身分証の突合)、決済確認、再認証などが代表例です。
1:N識別は「N人の登録者の中に該当者がいるか、誰か」に答える処理です。プローブ1件をギャラリN件と照合し、候補リストを返します。入退場ゲート、ウォッチリスト警報、勤怠、重複登録検出などが代表例です。1:1のLFWで上位の手法が、10^5〜10^6のギャラリ規模の1:Nでも上位とは限りません。NISTがFRVT 1:1とFRVT 1:Nを別レポートとして公開しているのもこのためです。
- 1:1は同一人ペアが多数を占め、誤一致のコストはトランザクション単位で効きます。
- 1:Nは非同一人ペアが多数を占め(特にウォッチリストはほとんどがNon-Mate)、偽陽性率はギャラリ規模Nに応じて増えます。
- ワークロードを先に決めること。同じバックボーンでも、1:1と1:Nでしきい値は変わります。
2. FRVT流の指標を採用する
「Accuracy一発」での評価をやめます。FRVTレポートは固定の運用ポイントで2種類の誤差率を報告し、トレードオフを曲線で可視化します。
1:1ではFMR(False Match Rate)とFNMR(False Non-Match Rate)を使います。目標FMR(典型的には1e-4、1e-5、1e-6)を定め、その点でのFNMRを報告します。1:NではFPIR(False Positive Identification Rate)とFNIR(False Negative Identification Rate)を使います。ギャラリ規模N、ランク、Closed-set(プローブが必ずギャラリに存在)かOpen-set(存在しない場合あり)かを必ず明示します。
- 報告値には必ずしきい値を併記します。FMRなしのFNMR、FPIRなしのFNIRには意味がありません。
- ROCではなくDET(Detection Error Tradeoff)曲線を描きます。低誤差率域での読み取りに適しています。
- 全体平均だけでなく、属性層別(FRVTのDemographic Effects報告と同じ思想)で数値を出します。
3. 防御可能なテストセットを設計する
Mateペアと非Mateペアは別々にサンプリングします。1:1でFMR = 1e-6を統計的に有意に推定するには、概ね10 / FMR = 10^7オーダーの非Mate比較が必要です。同じプローブを複数ペアで使い回しても構いませんが、有効サンプル数は正直に申告します。
属性、撮影端末、屋内/屋外、登録〜プローブの年齢差、遮蔽の種類、頭部姿勢などで層化し、平均値だけでなく層ごとに数値を出します。学習・ファインチューン・事前学習(Glint360K、WebFace42M、MS1MV3など)に使ったデータと完全に分離し、出所と同意取得の状況を文書化します。
- 目標FMRに対し最低でも10 / FMR件の非Mate比較を確保します。少ないと推定値の信頼区間が広がります。
- テストセットは凍結します。何度もチューニング対象にしているテストセットは事実上の検証セットです。
- 「ゴールデンセット」と呼ぶ小規模で固定の部分集合を用意し、モデルや前処理を変えるたびに再実行します。
4. 特徴量・類似度・しきい値の計算
公式の前処理を必ず使います。検出はRetinaFaceまたはSCRFD、5点ランドマークでの整列、112x112 RGBクロップ、認識パック付属の平均/分散です。前処理の不一致は、公開数値が再現できない最大の原因です。
L2正規化済み特徴量に対するコサイン類似度に統一します。InsightFace Python APIではface.normed_embeddingが該当します。しきい値は検証セットで決めて凍結し、テストセットでは評価のみ行います。テストセット上でしきい値を選ぶと結果は楽観的に膨らみます。
- InsightFaceの認識パックの1:1しきい値は、FMR = 1e-4〜1e-5でおおむねコサイン0.30〜0.45に収まります。バックボーン・学習データ・対象集団で変わるため、必ず再計算してください。
- デプロイメント間でギャラリ分布が変わる場合は、z-norm/t-normのスコア正規化が有効です。
- ファインチューンしたら、しきい値も必ず再算出します。バージョン間で流用しないでください。
import numpy as np
from insightface.app import FaceAnalysis
app = FaceAnalysis(
name="buffalo_l",
providers=["CUDAExecutionProvider", "CPUExecutionProvider"],
)
app.prepare(ctx_id=0, det_size=(640, 640))
def embed(image_bgr):
faces = app.get(image_bgr)
if not faces:
return None
# use the largest detected face
face = max(faces, key=lambda f: (f.bbox[2] - f.bbox[0]) * (f.bbox[3] - f.bbox[1]))
return face.normed_embedding.astype(np.float32) # already L2-normalized
def cosine(a, b):
return float(np.dot(a, b)) # both vectors are already L2-normalizedimport numpy as np
# scores collected on a held-out validation split
genuine = np.array(genuine_scores) # same person pairs
impostor = np.array(impostor_scores) # different people pairs
# pick the operating point you must defend in production
target_fmr = 1e-5
# threshold = score above which (1 - target_fmr) of impostors fall
threshold = float(np.quantile(impostor, 1.0 - target_fmr))
fnmr = float(np.mean(genuine < threshold))
print(f"threshold = {threshold:.4f}")
print(f"FNMR @ FMR = {target_fmr:.0e} -> {fnmr:.4f}")import numpy as np
# gallery_emb: (N, d) L2-normalized embeddings of enrolled identities
# probe_emb: (P, d) L2-normalized embeddings of probes
# probe_label: (P,) ground-truth gallery index, or -1 for non-mate probes (open-set)
scores = probe_emb @ gallery_emb.T # (P, N) cosine similarity
top1_idx = scores.argmax(axis=1)
top1_score = scores.max(axis=1)
# choose threshold from validation, then evaluate FPIR / FNIR
threshold = 0.40
mate = probe_label >= 0
non_mate = ~mate
fnir = float(np.mean(
(top1_idx[mate] != probe_label[mate]) | (top1_score[mate] < threshold)
))
fpir = float(np.mean(top1_score[non_mate] >= threshold))
print(f"FNIR = {fnir:.4f}, FPIR = {fpir:.4f} at threshold {threshold:.2f}")5. InsightFaceオープンソースモデルのベンチマーク
insightface Pythonパッケージは、検出器と認識バックボーンをまとめた即用モデルパックを配布しています。よく使われる認識パックは、buffalo_sc・buffalo_s(モバイル/エッジ向け)、buffalo_m(バランス)、w600k_r50ヘッドのbuffalo_l(サーバー標準)、glintr100ヘッドのantelopev2(大規模サーバー)です。Model ZooにはR50・R100 ArcFaceの素のウェイトも公開されています。
標準アカデミックベンチマーク(LFW、CFP-FP、AgeDB-30、IJB-B、IJB-C)での公開結果は、これらのパックを概ね以下のオーダーに位置づけます。あくまで参考値とし、自社データで必ず再計測してください。
- LFW 1:1精度:99.50%(モバイルMBF)〜99.85%(R100、w600k_r50)。LFWは飽和しており、サニティチェック以上の意味は持ちません。
- CFP-FP(正面対横顔):ラインナップ全体で96〜99%。横顔ではR100クラスが明確に有利です。
- AgeDB-30:ラインナップ全体で96〜98.5%。大型パックは年齢差に強い傾向。
- IJB-C TAR @ FAR = 1e-4:MBF/モバイルでおよそ90〜93%、R50で95〜96%、R100/w600k_r50/glintr100で96〜97.5%。
- MFR(Multi-racial Face Recognition、ICCV-21/22チャレンジ準拠で、African・Caucasian・East Asian・South Asian・MixedをFMR = 1e-6/1e-5で評価):モデルが小さくなるほど最良コホートと最悪コホートのTAR差は広がります。R100クラス(w600k_r50、glintr100)はコホート間で数ポイント以内に収まり、R50では数ポイント台中盤、モバイルMBFでは最も難しいコホートで二桁の差が出ることもあります。運用ポイントを決定する前に、必ず自社の人口分布で再現確認してください。
- スループット(単一GPU、batch 32、FP16):MBFは毎秒数千件、R100は毎秒数百件。必ず本番ハードウェアで計測してください。
6. ワークロードに合わせたオープンソースパック選定
プロダクト開発で必要となるのは、基本的にオープンソースパック2種類のうちのいずれか、つまりモバイル・エッジ向けのbuffalo_s(さらに軽量なbuffalo_sc)と、サーバー向けのbuffalo_lの選択です。
buffalo_s/buffalo_scは、端末上の顔認証、モバイルSDK統合、組み込みボックスなど、絶対精度よりレイテンシとバイナリサイズが支配的なワークロードのデフォルトです。buffalo_l(w600k_r50)はサーバー側認識のデフォルトで、1:1認証、数十万件規模までの1:N識別、目標FMR 1e-5前後に適しています。
- モバイル/エッジ:buffalo_sを選び、メモリや計算量がより厳しい場合はbuffalo_scを選びます。
- サーバー:buffalo_lを選びます。当社が提供する最強のオープンソース認識パックであり、協力的撮影が前提の認証・識別シナリオの大半をカバーします。
- FMR >= 1e-5かつ協力的撮影が前提のプロダクト機能であれば、オープンソースパックでおおむね十分です。それ以上の要件は次節を参照してください。
7. InsightFace商用モデルへの切り替え時期
InsightFaceの商用認識モデルは、桁違いに大規模で多様なIDセットと独自のロス・学習レシピで訓練されており、運用ポイントの記録と署名済みアーティファクトが付属して提供されます。「オープンソースモデルをパラメータ増しただけ」のものではありません。
具体的な数値で言えば、社内のバランス済み1:1プロトコル・FMR = 1e-6において、商用モデルは最強のオープンソースパックに対しFNMRをおおむね2〜5倍低減します(例:マスク・大姿勢・低解像度などの難サブセットで、FNMRが概ね5〜8%から1〜2%に低下)。属性バランス済みの1:N(ギャラリ100万人超)でも、固定FPIRにおけるFNIRが同程度の比率で低下し、最良サブグループと最悪サブグループの差が厳しい運用ポイントで縮小します。
切り替え判断を自社データで容易に検証していただけるよう、事前協業契約(NDA/パイロット契約)の締結後、商用認識モデルを2週間無料で評価いただけるトライアルを提供しています。期間中は商用モデルアーティファクトまたはホスト型APIへの期間限定アクセスを付与し、本ガイドで述べたFRVT流の1:1・1:Nテストをそのまま実施し、現在お使いのオープンソースパックと数値を直接比較したうえで、商用契約の判断を下していただけます。
- FMR <= 1e-6で運用する用途、たとえば出入国管理、決済承認、規制対応KYCには商用モデルを選びます。
- ギャラリが10万〜100万人を超え、Rank-1の安定性が重要な場合に商用モデルを選びます。
- 厳しい運用ポイントで属性間格差を縮める公平性監査が必要な場合に商用モデルを選びます。
- 本番に難条件(強い遮蔽、大姿勢、瞳孔間距離が約48 px未満の低解像度、非協力撮影)が含まれる場合に商用モデルを選びます。
- エンタープライズSLA、オンプレライセンス、PAD/生体検知の統合、署名済みアーティファクト、補償条項が必要な場合に商用モデルを選びます。
- 事前協業契約を締結のうえ、自社データで2週間の無料評価を行ってから商用契約を判断してください。
8. 本番展開と継続評価
モデルアーティファクト(暗号学的ハッシュ)、前処理コード、しきい値、指標定義をひとつのリリース単位として固定します。前処理の変更はFMRを静かにずらすため、ウェイトと同等以上に前処理のバージョン管理が重要です。
本番サンプルでの再評価を最低でも四半期ごとに実施します。最重要のライブ指標は本番しきい値におけるFMR(新たなインポスタセットで計測)であり、ビジネスに約束した運用ポイントが現在も維持されているかを示します。
- FMR/FNMRのドリフト、誤警報率、オペレータ上書き率、属性別差分を一括して追跡します。
- ロールバック計画を必ず用意します。しきい値とモデルは共バージョン管理。片方だけのロールバックは禁止です。
- モデル更新時はしきい値を必ず再算出し、運用ポイントを再公表してから本番トラフィックを切り替えます。