Lucentage AI age estimator

Methodology

How accurate is Lucentage?

Last updated

The short version: Lucentage is a single-value regression model that reads a 192-pixel face crop and returns apparent age in years. It was trained on 425,330 labelled portraits whose ages cluster heavily in middle adulthood, which is the single most useful thing to know about how it behaves. This page documents the data, the architecture, the training procedure and the measured error, so you can judge the number rather than take it on trust.

Task
Single-value regression Apparent age in years
Backbone
efficientvit_b1 timm, ImageNet-pretrained
Input
192 × 192 RGB Aspect-preserving letterbox
Head
1536 → 512 → 1 LayerNorm, Hardswish, dropout 0.2
Training images
382,793
Held-out images
42,537
Loss
Smooth L1 (Huber) β = 2.0 years
Optimiser
AdamW Weight decay 1e-3
Learning rate
5e-5 / 1e-4 Backbone / head
Schedule
Cosine to 1% Per step, no warmup
Epochs
32 Batch size 64
Runtime
ONNX, opset 17 Dynamic batch axis

What the model predicts

One scalar: apparent age in years. The network has no classifier over age buckets, no ordinal head and no uncertainty estimate, so there is no distribution to report and no interval to quote. A single forward pass produces a single number.

That is why the interface shows one figure and nothing else. Attaching a confidence percentage to a plain regression output would mean inventing a quantity the model never computes, and a fabricated interval is worse than an honest point estimate because it looks like rigour.

Ages are standardised against the training split before the loss is computed (mean 36.87 years, standard deviation 13.8) and converted back to years inside the network’s own forward pass. The exported graph therefore emits years directly, and the de-normalisation constants travel with the weights instead of living in application code where they could drift out of sync.

The training corpus

425,330 portraits, organised one directory per integer age. The split is stratified within each of those directories rather than taken across the corpus as a whole, so every age present contributes to both halves and no age band can land entirely in training or entirely in validation: 382,793 images to train on, 42,537 held out. The shuffle is seeded, so the split is reproducible across runs and the held-out images are never trained on.

The label distribution matters more than the headline count. The training ages have a mean of 36.87 and a standard deviation of 13.8, which puts roughly two thirds of the corpus between 23 and 51 years old. Children, teenagers and people over about seventy are all represented, but thinly by comparison. A regressor fitted to a distribution shaped like that pulls its predictions toward the centre of it, and this one does.

From photo to tensor

Every image is letterboxed rather than stretched. The longest side is scaled to 192 pixels and the shorter side is padded out to a square by replicating its edge pixels, so a portrait-orientation photo and a square one both reach the network with the face at its true proportions. Squashing a face to a fixed aspect ratio would distort exactly the geometry the model reads age from.

Padding by replication rather than with a constant colour keeps a hard synthetic edge out of the frame. A black bar is a strong feature, and a network will happily learn something about it that has nothing to do with age.

Architecture

An EfficientViT-B1 backbone, ImageNet-pretrained, with its classifier removed and replaced by a regression stack:

Linear(1536 → 512, bias=False)
LayerNorm(512)
Hardswish
Dropout(0.2)
Linear(512 → 1)

EfficientViT is a hybrid convolution–attention family designed for cheap inference rather than benchmark maxima, which is what a free tool serving every request on CPU actually needs. The B1 variant at 192 pixels is small enough that the whole estimate (upload, face detection, crop and forward pass) comes back in about a second.

The normalisation and activation between the two linear layers are doing real work: a bare projection from 1536 dimensions down to a scalar trains a good deal less stably at these learning rates, and the dropout is the only regulariser sitting directly in front of the output.

How it was trained

Loss

Smooth L1, better known as Huber loss, with β = 2 years. Inside two years of the true label it behaves like squared error and pushes hard for precision; beyond two years it grows only linearly. That transition point is chosen for the data rather than for the maths. Age labels are noisy: some self-reported, some estimated, a few simply wrong. Under plain squared error, a single mislabelled example forty years off can contribute more gradient than the rest of its batch combined. Huber caps that influence without giving up the precision that matters near the answer.

Learning rates and decay

Two rates, not one. The pretrained backbone trains at 5e-5 while the freshly initialised head trains at 1e-4, so the head can converge from random initialisation without the backbone’s ImageNet features being washed out in the first few epochs.

Weight decay of 1e-3 applies to weight matrices only. Biases and every one-dimensional parameter, which is to say the LayerNorm gains, are held out of it, because decaying a normalisation gain toward zero works directly against the thing that layer exists to do.

Schedule and checkpoint selection

A single cosine decay from the full learning rate down to 1% of it, stepped once per batch across all 32 epochs, with no warmup. The backbone is pretrained and its rate is low enough that there is nothing to warm up from.

The shipped checkpoint is the epoch with the lowest held-out error, not the last epoch. Both the PyTorch weights and the ONNX export are rewritten only when validation improves, so the exported graph and the reported figure always describe the same model.

Augmentation

Horizontal flip
p = 0.5
Translation
±4%, p = 0.7
Brightness / contrast / saturation
±20%, always
Hue
±0.02, always

What is missing is as deliberate as what is there. There is no rotation, no scale jitter and no cutout, because the service crops to a detected face before the model sees anything: train-time geometry is kept close to the geometry the model actually meets in production, and inventing variation the deployment never produces would spend capacity on nothing.

Colour is the exception, and it is applied to every training image rather than probabilistically. Lighting is the one thing that genuinely does vary between a studio portrait and a phone photo taken in a kitchen at night, and it is not something the crop step can normalise away.

Measured error

The figure that matters is mean absolute error over the 42,537 held-out images: on average, how many years the estimate sits away from the label. MAE rather than RMSE because it is in the same unit as the answer and it is not dominated by the handful of images the model gets badly wrong, which makes it the honest summary of what a typical result looks like.

A training run is in progress. The measured error for the next checkpoint is published here once that run completes and the best held-out epoch is selected. We would rather leave this figure blank for a few days than quote one we have not measured against the model currently being served.

Where the model is weakest

Every limitation below follows from the design above rather than from a disclaimer template.

  • Ages far from the middle

    Two thirds of the training labels sit between 23 and 51. Children and people over about seventy are represented far more thinly, and a regressor trained on a distribution like that pulls its predictions toward the middle of it. Expect the model to read young children as older than they are and the very old as younger.

  • Apparent age is not chronological age

    The labels are ages, but what the network learns is what an age looks like. Genetics, sun exposure, weight, sleep, styling, makeup and the camera itself all move apparent age by years in either direction, and the model reads all of them as evidence.

  • One face, the largest one

    The service crops to the most prominent face and reports on that alone. It does not average a group, and it has nothing useful to say about a face that is small, turned away, or partly out of frame.

  • Photographic conditions

    Error rises with extreme angles, sunglasses, heavy filters, strong backlighting, low light and motion blur. The training augmentation varies colour and lighting on every image but leaves geometry close to a centred, front-facing crop, which is the geometry the service supplies.

  • No published per-demographic breakdown

    We report one aggregate error figure. We have not published error broken down by age band, skin tone or sex, and until we do you should assume the error is not evenly distributed, because for face-age models it generally is not.

What this is not

Lucentage is not an age-verification or identity service. It is a statistical estimate of how old a face looks, published for entertainment, research and product prototyping. It must not be used to decide anyone’s access to age-restricted goods, services or content, and an error measured in years is by itself sufficient reason why not.

Nothing described here is a system of record. Photos are processed in memory for a single request and discarded when the response is written, as set out in our privacy policy.

From upload to number

  1. Your browser resizes

    The photo is re-encoded to WebP and scaled so its longest side is 640 pixels before anything leaves your device. A typical upload is tens of kilobytes rather than several megabytes.

  2. The service finds a face

    The inference service detects faces in the frame and crops to the largest one. 640 pixels is deliberately more than the model needs, so that crop is downscaled into the network rather than upscaled.

  3. The crop is letterboxed

    The crop is scaled so its longest side is 192 pixels and padded to a square by replicating its edge pixels. Nothing is stretched, so a face keeps its proportions whatever shape it arrived in.

  4. One forward pass

    The network emits a single number, de-normalised to years inside the graph itself. The image is released as soon as the response is written, and no copy is kept.

Lucentage is built and operated by EchoLensa Aesthetic Inc. If you are writing about age estimation and something here is unclear or looks wrong, we would rather hear about it than not.

Try it on your own photo

Free, no account, and the image is gone the moment the answer comes back.

Run an estimate