Key Findings
  • DeepFace 讓你用一行 DeepFace.verify() 就能比對兩張人臉是否為同一人,準確率在 LFW 資料集上超過 97.5%
  • 內建 10+ 種辨識模型(VGG-Face、FaceNet、ArcFace 等)與 10+ 種偵測器(RetinaFace、MTCNN、YOLOv8 等),可自由組合
  • 除了比對身份,還能一次分析年齡、性別、情緒、種族——一個套件包辦四件事
  • 2026 年若需要更高精度或即時推論,InsightFace(ArcFace + SCRFD)和 MediaPipe 是更主流的選項

一、DeepFace 是什麼?為什麼它這麼受歡迎?

人臉辨識聽起來很厲害,但實作起來其實有一堆瑣碎的事要處理:人臉偵測、對齊、裁切、特徵萃取、向量比對⋯⋯。光是把這條 pipeline 串起來就夠頭痛了,更別說每個環節還有一堆模型可以選。

DeepFace[1][2] 的存在就是為了讓你跳過這些苦工。它是由 Sefik Ilkin Serengil 開發的開源 Python 函式庫,GitHub 上超過 21,000 顆星,把市面上最強的人臉辨識模型和偵測器全部包裝成幾個簡單的函式呼叫。你不需要搞懂 FaceNet 的 triplet loss 怎麼訓練的[3],也不用理解 ArcFace 的 angular margin 為什麼有效[4]——只要 pip install deepface,然後呼叫 API,就能拿到結果。

用一個比喻來說:如果 FaceNet、ArcFace、VGG-Face 是各自獨立的高級食材,DeepFace 就是那個幫你把食材洗好、切好、擺盤好的廚房助手。你只要說「我要這道菜」,它就端上來了。

二、環境準備:Google Colab 設置

打開 Google Colab,新建 Notebook。人臉辨識的推論不一定需要 GPU(CPU 也跑得動),但如果你要處理大量圖片,切換到 T4 GPU 會快不少。

2.1 安裝 DeepFace

# 安裝 DeepFace(會自動拉 TensorFlow、OpenCV 等依賴)
!pip install deepface -q

第一次跑的時候,DeepFace 會自動下載你選用的模型權重(通常幾十到幾百 MB),這是正常的。之後就會從快取載入,不用重複下載。

from deepface import DeepFace
import matplotlib.pyplot as plt
import cv2
import os

print("DeepFace 安裝成功!")

2.2 準備測試圖片

我們需要幾張人臉圖片來玩。最簡單的方式是直接從網路上抓公開的樣本圖片:

import urllib.request

# 下載測試圖片(使用公開的 LFW 資料集樣本)
os.makedirs("faces", exist_ok=True)

# 使用 DeepFace 內建的測試圖片路徑
# DeepFace 套件自帶了幾張測試圖片
test_imgs = [
    "dataset/img1.jpg",
    "dataset/img2.jpg",
    "dataset/img3.jpg",
]

# 或者,用你自己的圖片(上傳到 Colab):
# from google.colab import files
# uploaded = files.upload()

# 我們先用簡單的方式:直接從網路下載兩張同一人的照片
urls = {
    "face_a1.jpg": "https://raw.githubusercontent.com/serengil/deepface/master/tests/dataset/img1.jpg",
    "face_a2.jpg": "https://raw.githubusercontent.com/serengil/deepface/master/tests/dataset/img2.jpg",
    "face_b1.jpg": "https://raw.githubusercontent.com/serengil/deepface/master/tests/dataset/img3.jpg",
}

for fname, url in urls.items():
    path = os.path.join("faces", fname)
    if not os.path.exists(path):
        urllib.request.urlretrieve(url, path)
        print(f"  下載完成: {fname}")

# 顯示下載的圖片
fig, axes = plt.subplots(1, 3, figsize=(12, 4))
for i, (fname, _) in enumerate(urls.items()):
    img = cv2.imread(os.path.join("faces", fname))
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    axes[i].imshow(img)
    axes[i].set_title(fname)
    axes[i].axis("off")
plt.tight_layout()
plt.show()

三、核心功能一:人臉驗證(Verify)

這是最常用的功能——給兩張照片,問「這是同一個人嗎?」

# ★ 一行搞定人臉驗證 ★
result = DeepFace.verify(
    img1_path="faces/face_a1.jpg",
    img2_path="faces/face_a2.jpg",
    model_name="VGG-Face"        # 預設模型
)

print(f"是同一人嗎? {result['verified']}")
print(f"距離分數:    {result['distance']:.4f}")
print(f"閾值:        {result['threshold']:.4f}")
print(f"使用模型:    {result['model']}")
print(f"相似度指標:  {result['similarity_metric']}")

verified 是布林值——True 表示系統認為這是同一人,False 表示不是。distance 是兩張臉的嵌入向量距離,越小表示越相似。當 distance 小於 threshold 時,就判定為同一人。

接著試試兩張不同人的照片:

# 比對兩張不同人的照片
result2 = DeepFace.verify(
    img1_path="faces/face_a1.jpg",
    img2_path="faces/face_b1.jpg",
    model_name="VGG-Face"
)

print(f"是同一人嗎? {result2['verified']}")
print(f"距離分數:    {result2['distance']:.4f}")
print(f"閾值:        {result2['threshold']:.4f}")

你會看到不同人的 distance 明顯大於閾值,所以 verifiedFalse

3.1 換個更強的模型試試

DeepFace 支援一大票模型,每個的精度和速度不同。來做個小實驗:

# 用不同模型比對同一對照片,看看差異
models = ["VGG-Face", "Facenet", "Facenet512", "ArcFace", "SFace"]

print("=" * 60)
print(f"{'模型':<15} {'結果':<8} {'距離':<10} {'閾值':<10}")
print("=" * 60)

for model in models:
    try:
        r = DeepFace.verify(
            img1_path="faces/face_a1.jpg",
            img2_path="faces/face_a2.jpg",
            model_name=model,
            enforce_detection=True
        )
        status = "同一人" if r["verified"] else "不同人"
        print(f"{model:<15} {status:<8} {r['distance']:<10.4f} {r['threshold']:<10.4f}")
    except Exception as e:
        print(f"{model:<15} 錯誤: {e}")

print("=" * 60)

通常 Facenet512ArcFace 的表現最穩定。VGG-Face 是預設值,速度快但模型較老。FaceNet 512 維的嵌入向量比 128 維版本提供了更細膩的特徵區分[3],而 ArcFace 使用的 angular margin loss 在大規模人臉資料集上有非常亮眼的表現[4]

四、核心功能二:人臉屬性分析(Analyze)

這是 DeepFace 最好玩的功能——丟一張臉進去,它會同時告訴你年齡、性別、情緒和種族:

# ★ 人臉屬性分析——年齡、性別、情緒、種族一次搞定 ★
analysis = DeepFace.analyze(
    img_path="faces/face_a1.jpg",
    actions=["age", "gender", "emotion", "race"],
    detector_backend="opencv"
)

# analyze 回傳的是 list(因為一張圖可能有多張臉)
for i, face in enumerate(analysis):
    print(f"\n--- 偵測到的第 {i+1} 張臉 ---")
    print(f"  年齡估計:  {face['age']} 歲")
    print(f"  性別:      {face['dominant_gender']}")
    print(f"  主要情緒:  {face['dominant_emotion']}")
    print(f"  主要種族:  {face['dominant_race']}")

    # 情緒細節分布
    print(f"\n  情緒分布:")
    for emotion, score in sorted(face["emotion"].items(), key=lambda x: -x[1]):
        bar = "█" * int(score / 2)
        print(f"    {emotion:<10} {score:5.1f}% {bar}")

幾個注意事項:

  • 年齡估計通常有 ±5 歲的誤差,別太認真
  • 情緒分析其實是表情分析——它偵測的是臉部肌肉的狀態,不是你內心的真實感受
  • 種族分類有 6 個類別(asian、white、middle eastern、indian、latino hispanic、black),這個功能有明確的倫理爭議,用在產品上要非常謹慎

五、核心功能三:人臉搜尋(Find)

如果你有一個人臉資料庫,想找出「這張臉在資料庫裡最像誰」,用 DeepFace.find()

# 建立一個簡單的人臉資料庫(用資料夾裝圖片)
os.makedirs("face_db", exist_ok=True)

# 把已知的臉複製到資料庫
import shutil
shutil.copy("faces/face_a1.jpg", "face_db/person_a.jpg")
shutil.copy("faces/face_b1.jpg", "face_db/person_b.jpg")

# ★ 用另一張照片在資料庫中搜尋 ★
results = DeepFace.find(
    img_path="faces/face_a2.jpg",    # 查詢圖片
    db_path="face_db",               # 資料庫路徑
    model_name="Facenet512",
    enforce_detection=True
)

# find() 回傳 list of DataFrames
if len(results) > 0 and len(results[0]) > 0:
    df = results[0]
    print("搜尋結果(按相似度排序):")
    print(df[["identity", "distance"]].to_string(index=False))
else:
    print("未找到匹配的人臉")

第一次執行 find() 時,DeepFace 會為資料庫中的每張圖計算嵌入向量並快取成 pickle 檔。之後再搜尋就會直接讀取快取,速度會快很多。

六、核心功能四:人臉嵌入向量(Represent)

如果你想自己處理向量比對的邏輯(例如存進向量資料庫),可以直接取得嵌入向量:

# ★ 取得人臉的嵌入向量 ★
embedding = DeepFace.represent(
    img_path="faces/face_a1.jpg",
    model_name="Facenet512",
    detector_backend="retinaface"
)

vec = embedding[0]["embedding"]
print(f"嵌入向量維度: {len(vec)}")
print(f"前 10 個值:   {[round(v, 4) for v in vec[:10]]}")

# 你可以把這個向量存進 Pinecone、Milvus、Qdrant 等向量資料庫
# 之後用餘弦相似度做搜尋

不同模型產生的向量維度不同:VGG-Face 是 4,096 維,FaceNet 是 128 維,Facenet512 是 512 維,ArcFace 是 512 維。維度越高不一定越好——FaceNet 的 128 維在 LFW 資料集上就達到了 99.63% 的準確率[3][9]

七、進階:切換偵測器比較效果

人臉辨識的第一步是「偵測」——先找到臉在哪裡。DeepFace 支援十幾種偵測器,效果差異滿大的:

# 比較不同偵測器的表現
import time

detectors = ["opencv", "ssd", "mtcnn", "retinaface", "yunet"]

print(f"{'偵測器':<15} {'耗時(秒)':<12} {'偵測到的臉'}")
print("=" * 45)

for det in detectors:
    try:
        start = time.time()
        result = DeepFace.analyze(
            img_path="faces/face_a1.jpg",
            actions=["age"],            # 只分析年齡(快一點)
            detector_backend=det,
            enforce_detection=True
        )
        elapsed = time.time() - start
        print(f"{det:<15} {elapsed:<12.3f} {len(result)} 張臉")
    except Exception as e:
        print(f"{det:<15} 失敗: {str(e)[:40]}")

一般來說:

  • opencv / ssd:最快,但精度最低,只能抓正面臉
  • mtcnn:速度和精度的平衡點,社群很愛用
  • retinaface[6]:精度最高,能偵測側臉和小臉,但速度較慢
  • yunet:輕量且精度不錯,適合邊緣裝置

如果你的圖片品質不錯、人臉夠大,用預設的 opencv 就夠了。如果是監控畫面、低解析度、多人場景,建議切到 retinaface

八、完整程式碼(一鍵複製版)

# === DeepFace 人臉辨識 完整版 ===
# 環境:Google Colab(CPU 即可,GPU 更快)

# Step 1: 安裝
!pip install deepface -q

# Step 2: 匯入
from deepface import DeepFace
import matplotlib.pyplot as plt
import urllib.request
import cv2
import os

# Step 3: 下載測試圖片
os.makedirs("faces", exist_ok=True)
urls = {
    "face_a1.jpg": "https://raw.githubusercontent.com/serengil/deepface/master/tests/dataset/img1.jpg",
    "face_a2.jpg": "https://raw.githubusercontent.com/serengil/deepface/master/tests/dataset/img2.jpg",
    "face_b1.jpg": "https://raw.githubusercontent.com/serengil/deepface/master/tests/dataset/img3.jpg",
}
for fname, url in urls.items():
    urllib.request.urlretrieve(url, os.path.join("faces", fname))

# Step 4: 人臉驗證
result = DeepFace.verify("faces/face_a1.jpg", "faces/face_a2.jpg", model_name="Facenet512")
print(f"同一人: {result['verified']}, 距離: {result['distance']:.4f}")

# Step 5: 屬性分析
analysis = DeepFace.analyze("faces/face_a1.jpg", actions=["age", "gender", "emotion"])
print(f"年齡: {analysis[0]['age']}, 性別: {analysis[0]['dominant_gender']}, 情緒: {analysis[0]['dominant_emotion']}")

# Step 6: 嵌入向量
embedding = DeepFace.represent("faces/face_a1.jpg", model_name="Facenet512")
print(f"向量維度: {len(embedding[0]['embedding'])}")

九、2026 年的當下,有更好的選擇嗎?

跟上一篇 AutoKeras 文章一樣,答案是:看情境。DeepFace 是絕佳的「瑞士刀」,但如果你有明確的需求,以下幾個工具可能更合適。

9.1 InsightFace:精度之王

如果你對辨識準確率有極高要求——例如門禁系統、金融 KYC——InsightFace 是目前的業界標竿。它整合了 ArcFace[4] 辨識模型和 SCRFD[7] 偵測器,在 LFW 和 MegaFace 等基準測試上表現頂尖。

# InsightFace 做人臉辨識
!pip install insightface onnxruntime-gpu -q

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

# 初始化(會自動下載 buffalo_l 模型包)
app = FaceAnalysis(
    name="buffalo_l",
    providers=["CUDAExecutionProvider", "CPUExecutionProvider"]
)
app.prepare(ctx_id=0, det_size=(640, 640))

# 偵測 + 辨識
img = cv2.imread("faces/face_a1.jpg")
faces = app.get(img)

for face in faces:
    print(f"人臉信心值: {face.det_score:.4f}")
    print(f"年齡估計:   {face.age}")
    print(f"性別:       {'男' if face.gender == 1 else '女'}")
    print(f"嵌入維度:   {face.embedding.shape}")

# 比對兩張臉
img2 = cv2.imread("faces/face_a2.jpg")
faces2 = app.get(img2)

if faces and faces2:
    # 計算餘弦相似度
    sim = np.dot(faces[0].embedding, faces2[0].embedding) / (
        np.linalg.norm(faces[0].embedding) * np.linalg.norm(faces2[0].embedding)
    )
    print(f"\n餘弦相似度: {sim:.4f}")
    print(f"是否同一人: {sim > 0.4}")

InsightFace 的 SCRFD 偵測器比 RetinaFace 更快、更準[7],特別在小臉和遮擋場景下表現出色。缺點是 API 沒有 DeepFace 那麼「傻瓜式」,需要多寫一點膠水程式碼。

9.2 MediaPipe Face:即時推論首選

如果你的場景是「即時影像串流中偵測人臉」——例如視訊會議的虛擬背景、AR 濾鏡——MediaPipe[8] 是最佳選擇。Google 開發的 BlazeFace 模型在手機 GPU 上都能跑到 200 FPS。

# MediaPipe 人臉偵測 + 特徵點
!pip install mediapipe -q

import mediapipe as mp
import cv2
import matplotlib.pyplot as plt

mp_face = mp.solutions.face_detection
mp_mesh = mp.solutions.face_mesh
mp_draw = mp.solutions.drawing_utils

# 人臉偵測
img = cv2.imread("faces/face_a1.jpg")
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

with mp_face.FaceDetection(model_selection=1, min_detection_confidence=0.5) as detector:
    results = detector.process(img_rgb)

    if results.detections:
        for det in results.detections:
            mp_draw.draw_detection(img_rgb, det)
            print(f"信心值: {det.score[0]:.4f}")

# 人臉特徵點(468 個點!)
with mp_mesh.FaceMesh(
    static_image_mode=True,
    max_num_faces=1,
    refine_landmarks=True,        # 包含虹膜特徵點
    min_detection_confidence=0.5
) as mesh:
    results = mesh.process(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    if results.multi_face_landmarks:
        print(f"特徵點數量: {len(results.multi_face_landmarks[0].landmark)}")

plt.figure(figsize=(8, 8))
plt.imshow(img_rgb)
plt.axis("off")
plt.title("MediaPipe Face Detection")
plt.show()

但要注意:MediaPipe 專精於「偵測」和「特徵點」,它本身不做身份辨識(不會告訴你「這是誰」)。如果你需要辨識身份,還是得搭配 FaceNet 或 ArcFace 的嵌入模型。

9.3 face_recognition:最簡單的 dlib 封裝

如果你只是想快速做個簡單的人臉比對 demo,face_recognition 這個套件可能是最直覺的:

# face_recognition(dlib 封裝,API 極簡)
!pip install face_recognition -q

import face_recognition

# 載入圖片
img_a = face_recognition.load_image_file("faces/face_a1.jpg")
img_b = face_recognition.load_image_file("faces/face_a2.jpg")

# 取得 128 維嵌入向量
enc_a = face_recognition.face_encodings(img_a)[0]
enc_b = face_recognition.face_encodings(img_b)[0]

# 比對
results = face_recognition.compare_faces([enc_a], enc_b, tolerance=0.6)
distance = face_recognition.face_distance([enc_a], enc_b)[0]

print(f"是否同一人: {results[0]}")
print(f"距離: {distance:.4f}")

API 非常乾淨,但底層用的是 dlib 的 ResNet 模型(2017 年的),精度在 2026 年的標準下已經不算頂尖。適合教學和快速原型,不建議用在生產環境。

十、該選哪個?一張表搞定

工具適合場景精度速度API 易用性維護狀態
DeepFace快速原型、多模型實驗極高活躍
InsightFace高精度生產環境最高活躍
MediaPipe即時偵測、行動裝置偵測優最快Google 維護
face_recognition教學、簡單 demo中等極高低度維護

我的建議:

  • 第一次接觸人臉辨識:用 DeepFace,它的 API 設計是真的替初學者著想,而且內建的多模型切換功能讓你快速建立直覺
  • 要上生產環境:InsightFace + SCRFD 是目前的黃金組合,精度和速度都是一線水準
  • 即時串流場景:MediaPipe 做偵測 + InsightFace 做辨識,各取所長
  • 想用最少程式碼跑起來:face_recognition 套件三行就搞定,但別期待太高的精度

十一、倫理提醒:人臉辨識不是你想用就能用

技術面聊完了,但有件更重要的事必須說清楚:人臉辨識是高度敏感的技術

在實務上,你需要注意:

  1. 法規合規:歐盟 AI Act 將公共場所的即時人臉辨識列為「高風險」甚至「禁止」用途。台灣的個資法和即將上路的 AI 基本法也有相關規範
  2. 偏見問題:目前的人臉辨識模型在不同膚色、性別上的表現存在顯著差異[5]。用在決策場景時(如招聘、信用評分)要特別謹慎
  3. 知情同意:收集和處理人臉資料前,務必取得當事人的明確同意
  4. 資料保護:人臉嵌入向量屬於生物特徵資料,儲存和傳輸都需要加密

技術本身是中性的,但使用者有責任確保它被負責任地使用。

十二、常見問題 FAQ

Q:DeepFace 首次執行很慢是正常的嗎?

是的。第一次使用某個模型時,DeepFace 會從網路下載預訓練權重(VGG-Face 約 580 MB,FaceNet 約 90 MB)。下載完會存在 ~/.deepface/weights/ 目錄下,之後就不需要再下載了。

Q:enforce_detection=True 一直報錯怎麼辦?

這表示偵測器在圖片中找不到人臉。可能的原因:圖片太小、人臉太側面、光線太差。你可以改用更強的偵測器(如 retinaface),或者暫時設成 False(但結果可能不準)。

Q:可以處理即時影像嗎?

可以,但 DeepFace 本身不是為即時串流設計的。如果你要做 webcam 即時辨識,建議偵測用 MediaPipe 或 YuNet(快),辨識用 DeepFace 的 represent() 取嵌入向量後自己算距離。或者直接用 InsightFace 的 FaceAnalysis,它的 pipeline 比較適合影片流。

Q:DeepFace 2026 年還有在更新嗎?

有。最近的版本(v0.0.96,2025 年 11 月)新增了 register()build_index()search() 等更適合生產環境的 API[10],也加入了 YOLOv11、YOLOv12 等新偵測器的支援。社群依然活躍。

十三、結語:先跑起來,再選最佳方案

人臉辨識這個領域,入門和精通之間的差距是巨大的。但好消息是,DeepFace 把那個入門的門檻壓得非常低。你不需要讀完 FaceNet 和 ArcFace 的論文才能開始——先裝好、跑起來、看到結果,然後再回頭去理解背後的原理。

這才是正確的學習路徑:先有感覺,再有理論

當你用 DeepFace 跑出第一個結果、看到兩張照片被正確判定為同一人時,你自然會好奇:「它到底是怎麼算的?」那時候再去讀 FaceNet 的 triplet loss[3]、ArcFace 的 angular margin[4],就會覺得豁然開朗。

去試試吧。Google Colab 打開、程式碼貼進去,十分鐘後你就有一個能辨識人臉的系統了。