# Why Is Face Recognition Accuracy Lower for Children? A Technical Analysis of the face_recognition Library

> Discover why face recognition accuracy is lower for children. Learn how dlib model training data bias impacts child face encodings in the face_recognition library.

- Repository: [Adam Geitgey/face_recognition](https://github.com/ageitgey/face_recognition)
- Tags: deep-dive
- Published: 2026-03-06

---

**Face recognition accuracy drops for children because the underlying dlib models in the `face_recognition` library were trained primarily on adult faces, creating a data bias that produces less discriminative encodings for smaller, proportionally different child faces.**

The `face_recognition` Python library provides a simple interface for face detection and recognition, but developers often observe reduced accuracy when processing children's faces. This performance gap stems from architectural constraints in the underlying dlib models and training data limitations that favor adult facial geometry, as implemented in the `ageitgey/face_recognition` repository.

## Root Causes of Reduced Accuracy for Child Faces

### Training Data Bias in Deep Learning Models

The library wraps dlib's CNN face detector (`cnn_face_detection_model`) and 128-D face embedding network (`face_recognition_model`), both trained on datasets like VGGFace2 and Labeled Faces in the Wild. These datasets contain predominantly adult faces, causing the neural networks to learn statistical patterns optimized for adult facial geometry, skin texture, and landmark locations.

When applied to children, the models generate encodings with higher intra-class variance and lower inter-class separation. In [`face_recognition/api.py`](https://github.com/ageitgey/face_recognition/blob/main/face_recognition/api.py) at lines 28-30, the library loads these pre-trained models using `face_recognition_models.face_recognition_model_location()` and `dlib.face_recognition_model_v1`, embedding the adult-face bias directly into the prediction pipeline.

### Physical Face Characteristics and Proportions

Children exhibit distinct facial proportions compared to adults—larger forehead-to-chin ratios, smaller noses, and different bone structures. The 68-point shape predictor (`pose_predictor_68_point`) in [`face_recognition/api.py`](https://github.com/ageitgey/face_recognition/blob/main/face_recognition/api.py) (lines 54-66) was trained on adult landmarks, leading to misalignment during the preprocessing stage before encoding generation.

### Detection Challenges for Smaller Faces

Children's faces occupy fewer pixels in images, particularly in unconstrained photography. The default HOG detector struggles with low-resolution inputs, while the CNN detector's default up-sampling (`number_of_times_to_upsample=1`) in `_raw_face_locations` (lines 92-100) often misses small child faces entirely.

### Encoding Limitations and Jittering

The `face_encodings` function (lines 103-115) defaults to `num_jitters=1`, performing only one sampling of the face. For children—where detection and landmark placement are less reliable—this limited jittering fails to average out noise, resulting in less stable 128-D vectors.

## Technical Implementation Details

In [`face_recognition/api.py`](https://github.com/ageitgey/face_recognition/blob/main/face_recognition/api.py), the library loads pre-trained dlib models at lines 28-30 using `face_recognition_models.face_recognition_model_location()` and `dlib.face_recognition_model_v1`. These immutable model weights encode the adult-face bias directly into the prediction pipeline.

The `compare_faces` function (lines 17-26) calculates Euclidean distance between encodings, but the default `tolerance=0.6` threshold assumes adult-level encoding stability that children rarely achieve. When processing child faces, the Euclidean distances between the same child's different photos tend to be larger, while distances to other subjects may be smaller, causing both false negatives and false positives.

## Mitigation Strategies for Child Face Recognition

### Increase Up-sampling for Small Face Detection

To capture smaller child faces, increase the up-sampling parameter when calling `face_locations`:

```python
import face_recognition

image = face_recognition.load_image_file("child.jpg")
face_locations = face_recognition.face_locations(
    image,
    number_of_times_to_upsample=2,  # Increase from default 1

    model="cnn"                     # Use CNN instead of HOG

)

```

### Use CNN Model and GPU Acceleration

The CNN detector (`model="cnn"`) in `_raw_face_locations` provides superior accuracy for challenging poses and scales compared to the default HOG detector, though it requires GPU acceleration for practical performance.

### Add Jittering for Robust Encodings

Increase `num_jitters` when generating encodings to average out detection noise common in child faces:

```python
encodings = face_recognition.face_encodings(
    image,
    known_face_locations=face_locations,
    num_jitters=5,      # Increase from default 1

    model="large"       # Use 68-point landmark model

)

```

### Adjust Tolerance Thresholds

Lower the tolerance threshold in `compare_faces` to reduce false positives when dealing with less discriminative child encodings:

```python
matches = face_recognition.compare_faces(
    known_child_encodings,
    child_encoding,
    tolerance=0.5       # Stricter than default 0.6

)

```

### Batch Processing for Large Datasets

For processing many child images efficiently, use the batch API with GPU acceleration:

```python
import glob
import face_recognition

paths = glob.glob("children_dataset/*.jpg")
images = [face_recognition.load_image_file(p) for p in paths]

# Batch-detect faces on the GPU

batch_locations = face_recognition.batch_face_locations(
    images,
    number_of_times_to_upsample=2,
    batch_size=32
)

# Compute encodings for each detected face

all_encodings = []
for img, locs in zip(images, batch_locations):
    all_encodings.extend(
        face_recognition.face_encodings(img, locs, num_jitters=3)
    )

```

## Summary

- **Face recognition accuracy drops for children** due to training data bias in dlib's models, which were trained primarily on adult faces in datasets like VGGFace2 and Labeled Faces in the Wild.
- **Physical differences** in child facial proportions and smaller face sizes in images compound the problem through misaligned landmarks and missed detections in [`face_recognition/api.py`](https://github.com/ageitgey/face_recognition/blob/main/face_recognition/api.py).
- **Default parameters**—particularly `number_of_times_to_upsample=1` and `num_jitters=1` in the encoding pipeline—are optimized for adult faces and produce less stable vectors for children.
- **Mitigation requires** increasing up-sampling, using the CNN detector, adding jittering, and tightening tolerance thresholds to compensate for less discriminative child face encodings.

## Frequently Asked Questions

### Can I retrain the face_recognition models on child faces?

The `face_recognition` library uses pre-trained dlib models that cannot be retrained through the library's API. Retraining would require accessing the original dlib training pipeline and datasets, which is outside the scope of this wrapper library. To improve accuracy, collect a child-specific gallery and adjust detection parameters rather than retraining the underlying neural networks.

### Why does the HOG detector miss child faces more often than adult faces?

The HOG (Histogram of Oriented Gradients) detector in `face_recognition` relies on gradient patterns that become less distinct at lower resolutions. Children's smaller faces produce weaker gradient signals in the `_raw_face_locations` function, causing the detector to fail more frequently than with larger adult faces. Switching to the CNN detector with increased up-sampling significantly improves detection rates for children.

### How many times should I up-sample images containing children?

For images where children's faces appear small or distant, set `number_of_times_to_upsample=2` in the `face_locations` function. This doubles the image resolution before detection in the CNN pipeline, significantly improving recall for small faces at the cost of increased processing time. For very small faces, you may need to increase this to 3, though computational costs rise accordingly.

### Will increasing num_jitters slow down my application?

Yes. The `num_jitters` parameter in `face_encodings` performs multiple random perturbations of the face image and averages the results. Setting `num_jitters=5` will roughly quintuple the encoding time compared to the default `num_jitters=1`, though this trade-off is often necessary for accurate child face recognition where landmark detection is less reliable.