TruthLens β€” AI Image Authenticity Detector

Classifies images as AI-generated (FAKE) or authentic (REAL) using a multi-branch convolutional neural network that analyses spatial, frequency, and noise-level features simultaneously.

The model is exported as a self-contained TorchScript file β€” no architecture definition is required to run it.


Model Details

Property Value
Architecture ImprovedDetector (multi-branch CNN)
Task Binary image classification (FAKE / REAL)
Input RGB image, resized to 32 Γ— 32, normalized to [-1, 1]
Output (logit, gates) β€” scalar logit + 3-weight gate vector
Decision threshold sigmoid(logit) > 0.5 β†’ FAKE
Format TorchScript (.pt)

Architecture

The model is built around three independent branches that each look for a different class of evidence, feeding into a shared gated fusion layer.

Spatial Branch

Processes raw pixel data through a stem convolution followed by three residual blocks. Looks for visual artifacts, unnatural textures, and lighting inconsistencies that generative models leave behind.

Frequency Branch

Operates in the frequency domain by computing the FFT magnitude, FFT phase, and a DCT approximation of the input β€” each processed by its own convolutional block. Detects the spectral fingerprints that generative models produce but real camera sensors don't.

Noise Branch

Applies a fixed high-pass filter to isolate the high-frequency noise layer of the image, then analyses it with a small CNN. Real photographs carry consistent sensor noise; AI images tend to have suspiciously smooth or periodically structured noise patterns.

Gated Fusion

All three branch embeddings are concatenated and passed through a two-layer gate network with a Softmax output, producing three scalar weights that sum to 1.0. These weights are used to compute a weighted sum of projected branch features before the final classifier. The gate weights are returned alongside the logit, giving per-image explainability.

Input image (3 Γ— 32 Γ— 32)
       β”‚
  β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚            β”‚            β”‚
Spatial   Frequency      Noise
(512-d)    (512-d)      (256-d)
  β”‚            β”‚            β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚
         Gated Fusion
         (learned weights β†’ 512-d)
               β”‚
          Classifier
      (512 β†’ 256 β†’ 64 β†’ 1)
               β”‚
             logit

Usage

Direct inference (Python)

import torch
from PIL import Image
import torchvision.transforms as T
from huggingface_hub import hf_hub_download

# Load model
path  = hf_hub_download("Medsa/ai-image-authenticity-detector", "detector_scripted.pt")
model = torch.jit.load(path, map_location="cpu")
model.eval()

# Preprocess
transform = T.Compose([
    T.Resize((32, 32)),
    T.ToTensor(),
    T.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5]),
])
img    = Image.open("photo.jpg").convert("RGB")
tensor = transform(img).unsqueeze(0)   # (1, 3, 32, 32)

# Inference
with torch.no_grad():
    logit, gates = model(tensor)

fake_prob = torch.sigmoid(logit).item()
verdict   = "FAKE" if fake_prob > 0.5 else "REAL"

print(f"Verdict   : {verdict}")
print(f"Fake prob : {fake_prob:.4f}")
print(f"Real prob : {1 - fake_prob:.4f}")
print(f"Gates     : spatial={gates[0,0]:.3f}  freq={gates[0,1]:.3f}  noise={gates[0,2]:.3f}")

Via the TruthLens API

The model is also served by the TruthLens web application:

curl -X POST http://localhost:5000/predict \
  -F "files=@photo.jpg"

Output Format

The model returns a tuple (logit, gates):

Output Shape Description
logit (1,) Raw pre-sigmoid score. Pass through sigmoid() to get fake_prob.
gates (1, 3) Softmax-normalized branch weights: [spatial, frequency, noise]
fake_prob = torch.sigmoid(logit).item()   # probability image is AI-generated
real_prob = 1 - fake_prob                 # probability image is authentic

spatial_weight   = gates[0, 0].item()
frequency_weight = gates[0, 1].item()
noise_weight     = gates[0, 2].item()

Gate weights indicate which branch was most influential for a given image. They always sum to 1.0.


Preprocessing

The model expects images preprocessed exactly as follows:

transforms.Compose([
    transforms.Resize((32, 32)),
    transforms.ToTensor(),                              # scales to [0, 1]
    transforms.Normalize([0.5, 0.5, 0.5],              # shifts to [-1, 1]
                         [0.5, 0.5, 0.5]),
])

Inputs that are not normalized to [-1, 1] will produce unreliable results.


Files

File Description
detector_scripted.pt TorchScript model β€” load with torch.jit.load()

Training

Dataset: CIFAKE β€” a balanced dataset of real CIFAR-10 images and AI-generated counterparts at 32 Γ— 32 resolution.

Optimizer: AdamW (lr=3e-4, weight_decay=1e-4) with cosine annealing down to 1e-6 over 50 epochs, batch size 64, gradient clipping at norm 1.0. Early stopping with patience 5.

Data augmentation (train only): random horizontal/vertical flips, color jitter (brightness, contrast, saturation), and small random rotation (Β±10Β°).

Loss function: standard BCE plus a gate diversity penalty to prevent branch collapse β€” an issue where the gate learns to ignore one or more branches entirely and routes everything through a single one:

L = BCE(logit, label) βˆ’ Ξ» Β· H(gates)

where H(gates) is the mean gate entropy across the batch. Maximising entropy keeps all three branches actively contributing. The weight Ξ» starts at 0.3 and decays by 0.9 per epoch (floored at 0.05), so the penalty is strong early on to force branch diversity, then relaxes as the gate is allowed to specialise.


Limitations

  • Input resolution is fixed at 32 Γ— 32. Fine spatial detail is lost; the model relies on statistical patterns rather than high-frequency pixel-level artifacts.
  • Performance may degrade on image types significantly underrepresented in training data (e.g. medical images, satellite imagery).
  • Like all detectors, it can be fooled by adversarial post-processing (JPEG compression, noise injection, resizing pipelines).
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support