DE

DeepFace

Face recognition and facial attribute analysis framework

Photo Management ★ 23.5k stars Medium setup MIT

DeepFace is a Python framework for face recognition, verification, and facial attribute analysis such as age, gender, and emotion. It wraps multiple state-of-the-art models behind a simple API and can be self-hosted as a recognition service.

Key features

  • Face verification and recognition
  • Age, gender and emotion analysis
  • Multiple backbone models
  • Simple REST API

Pros & cons

Strengths

  • Simple high-level API
  • Multiple model backends
  • Attribute analysis included

Trade-offs

  • Heavy TensorFlow dependency
  • Models download on first run

DeepFace replaces

Last reviewed Aug 26, 2026 · 818 words

Three lines of Python get you a face verification that would cost a per-call fee from AWS Rekognition, which is the appeal. The first run then downloads several hundred megabytes of model weights and TensorFlow settles into most of the 2 GB minimum RAM, which is the cost. DeepFace is a 23,337-star MIT framework that wraps a dozen recognition models behind one API, and the right way to think about it is as a building block for your own tool, not as a photo app. Immich and PhotoPrism already do face grouping for your library; DeepFace is what you reach for when you need recognition inside something you are building.

Verify, find, analyze

Install with pip install deepface and the whole surface is a handful of functions:

from deepface import DeepFace

# same person or not?
r = DeepFace.verify("img1.jpg", "img2.jpg", model_name="Facenet512")
print(r["verified"], r["distance"])

# which known face is this? (db_path is a folder of named images)
hits = DeepFace.find("unknown.jpg", db_path="faces/", model_name="Facenet512")

# attributes
a = DeepFace.analyze("img1.jpg", actions=["age", "gender", "emotion"])

verify compares 2 images, find searches a folder and caches embeddings in a pickle file next to it so the second query is fast, and represent (not shown) returns the raw embedding vector if you want to store it in your own database. Weights land in ~/.deepface/weights/ on first use, so mount that path as a volume in Docker or every container restart re-downloads.

Change the default model before you trust a result

The default backbone is the original VGG-Face, chosen for history rather than accuracy. In the project's own benchmarks, Facenet512 and ArcFace sit clearly ahead of it on standard face-pair tests, and both are 1 keyword argument away. The same applies to detection: the default detector is OpenCV's Haar cascade, which is fast and misses angled faces; detector_backend="retinaface" or "mtcnn" finds more and costs more CPU. Detection is often the slower half of the pipeline on CPU-only boxes, so pick your detector by hardware, then your recognition model by accuracy. GPU support comes through TensorFlow and is optional; a 4-core CPU handles a few verifications per second with the lighter detectors.

Running it as a service

For anything beyond a script, DeepFace ships a small Flask API. The official image is serengil/deepface on port 5000 with /verify, /analyze and /represent endpoints that accept base64 images or paths:

services:
  deepface:
    image: serengil/deepface
    ports: ["5000:5000"]
    volumes: ["./weights:/root/.deepface/weights"]
    restart: unless-stopped

Send it 2 base64 images as JSON and get the same dictionary the Python call returns. There is no authentication on that API, so keep it on an internal network and let whatever app you build sit in front. Memory sits around 2 GB with 1 model loaded; each additional model you call adds its own footprint, so standardise on 1.

Where it sits next to Immich, PhotoPrism and Frigate

If your goal is "group the people in my photo library", stop and use Immich or PhotoPrism; both ship face clustering, and either will do it better for a library than anything you build in an afternoon. If your goal is "tell me who is at the front door", the established pattern is Frigate for detection, Double Take as the matching layer, and a recognition backend behind it. Double Take talks to DeepFace out of the box, and to CompreFace, which is the other self-hosted option worth knowing: CompreFace is a full service with a management UI and per-subject training, DeepFace is a library with a thin API. Choose CompreFace when you want to click; choose DeepFace when you want to code.

Attribute analysis is a demo, not a feature

Age, gender and emotion estimation are included and they are fun for 5 minutes. Treat the output as a rough guess: age estimates swing by a decade, emotion labels flip between frames, and none of it should drive a decision about a person. Face verification itself is accurate enough for a convenience feature (open the garage for a known car and face) and not accurate enough to be the only lock on anything that matters. Keep the photos category mindset: this is your data, on your hardware, and the responsibility for what you do with recognition is yours too.

What I'd do

Run the Docker service on an internal network with the weights volume mounted, standardise on Facenet512 with the RetinaFace detector, and write the 40-line wrapper that fits your project rather than exposing the raw API. Use it for doorbell matching behind Frigate and Double Take, or for a custom tool your photo app cannot do. Leave library-wide face grouping to Immich, and leave attribute analysis in the demo notebook where it belongs.

Similar photo management apps