techjam-2026-track5: pe-core-fused-w15

Detector for AI-generated images whose ranking survives JPEG re-encoding, blur, rescaling, noise, colour jitter and cropping. Entry for TikTok TechJam 2026, Track 5. Project repo: https://github.com/AudricY/techjam26-image-detection.

Two LayerNorm + linear heads on one frozen PE-Core-L/14-336 tower (timm/vit_pe_core_large_patch14_336.fb @ e63206c8e3a0e9b699e40f31080eebd78fd2258e, Apache-2.0; 316,114,946 parameters loaded, 15.8 % of the track's 2B cap). Head A is trained on a balanced multi-family pool, head B on a pool tilted toward modern commercial generators; the served score is a weighted sum of the two Platt-calibrated logits, w = (0.15, 0.85), with the threshold refit at 1 % FPR on 11,510 held-out reals (real_pool_A_v1; realised 1.01 %). The tower is not shipped here: it is fetched from the hub by pinned id and revision at load, and its sha256 is checked against MANIFEST.json. This directory is not loadable with timm.create_model; it is a checkpoint directory for the project's predict CLI (below).

Measured results, with 95 % CIs and a zero-pixel null beside every number

read result zero-pixel null (metadata only)
Organisers' validation split, original-COCO copy (5,000 reals vs 8,843 DALL·E 3): clean AUROC, raw 0.9971 [0.9965, 0.9977] quality 0.9998, pixels 0.9994: the raw null is above the model; under the bias-corrected norm protocol the null falls to 0.5000 / 0.849 and the model reads 0.9974
same copy, norm: robust AUROC over the 15 transform cells · worst cell (noise σ0.10) 0.9912 [0.9902, 0.9921] · 0.9628 [0.9601, 0.9656] 0.849
WildFake-COCO copy (4,998 reals, 200×200 re-encodes): clean AUROC raw / norm 0.9690 [0.9664, 0.9716] / 0.9759 [0.9737, 0.9782] pixels 1.0000 raw / 0.428 norm
400 held-out generators (Community Forensics slice, 16,000 fakes vs 3,500 LAION reals; 397 are families absent from every training pool, three are WildFake-era families under CF's spelling), clean 0.9986 [0.9981, 0.9989] size null 0.9813; on the square-aspect stratum where that null is 0.5 by construction: 0.9958 clean, 0.9774 [0.9701, 0.9838] under noise σ0.05
Commercial frontier fakes, TPR at the served threshold: nano-banana · GPT-Image class 76.3 % [72.8, 79.6] · 18.2 % [15.3, 21.5] at a matched 1 %-FPR cut this system reads above the public SigLIP baseline on both (matched-τ table in the project README); its training provenance is unknown, ours is provably held out

Operating point. The shipped threshold (0.5) is precision-heavy: on the validation split it flags 0 of 5,000 reals and 40.8 % of the DALL·E 3 fakes (TPR 0.958 at 1 % FPR, raw: the ranking is strong, the cut is conservative). Cut pred elsewhere if recall matters more; the generated τ-ladder below gives the measured trade at five cuts. CPU serve: 0.44 s/image (48 cores, batch 8, model load included).

τ-ladder — pe-core-v2 + pe-core-v31 at w=[0.15, 0.85], norm protocol, clean cell

Served scale: sigmoid(0.15·logit(pe-core-v2) + 0.85·logit(pe-core-v31) − tau_shift(0.34634694123443033)), the checkpoint's own rule (weights/current). Fusion path validated against the persisted fused run results/20260831-1540-w15-assembly on dev_internal_v2 (norm.clean, n = 4,892): max |Δp| 2.30e-04, 0 decision flips at 0.5.

Recall and false positives across the ladder

threshold τ TPR organiser fakes TPR CF fakes TPR stress nano-banana TPR stress echo-4o-gptimage FPR coco-orig reals FPR coco-wildfake reals FPR CF LAION reals
served 0.5 0.5 (served) 0.3899 [0.3798, 0.4001] 0.5356 [0.5279, 0.5433] 0.7633 [0.7277, 0.7956] 0.1817 [0.1529, 0.2145] 0.0000 [0.0000, 0.0008] 0.0016 [0.0008, 0.0032] 0.0003 [0.0001, 0.0016]
coco-orig reals @ FPR 1% 0.0127193 0.9637 [0.9596, 0.9674] 0.9814 [0.9792, 0.9834] 0.9933 [0.9830, 0.9974] 0.9283 [0.9049, 0.9464] 0.0100 [0.0076, 0.0132] 0.1495 [0.1398, 0.1596] 0.0109 [0.0079, 0.0149]
coco-orig reals @ FPR 5% 0.00343981 0.9896 [0.9873, 0.9915] 0.9954 [0.9942, 0.9963] 0.9967 [0.9879, 0.9991] 0.9817 [0.9675, 0.9897] 0.0500 [0.0443, 0.0564] 0.3735 [0.3602, 0.3871] 0.0520 [0.0451, 0.0599]
coco-orig reals @ FPR 10% 0.0017417 0.9959 [0.9944, 0.9971] 0.9978 [0.9969, 0.9984] 0.9983 [0.9906, 0.9997] 0.9950 [0.9854, 0.9983] 0.1000 [0.0920, 0.1086] 0.5212 [0.5073, 0.5350] 0.1006 [0.0910, 0.1110]
CF LAION reals @ FPR 1% 0.0150169 0.9590 [0.9546, 0.9629] 0.9787 [0.9763, 0.9808] 0.9917 [0.9806, 0.9964] 0.9233 [0.8992, 0.9420] 0.0082 [0.0061, 0.0111] 0.1293 [0.1202, 0.1388] 0.0100 [0.0072, 0.0139]
CF LAION reals @ FPR 5% 0.00366686 0.9885 [0.9860, 0.9905] 0.9950 [0.9938, 0.9960] 0.9967 [0.9879, 0.9991] 0.9800 [0.9654, 0.9885] 0.0458 [0.0403, 0.0520] 0.3629 [0.3497, 0.3764] 0.0500 [0.0433, 0.0577]
CF LAION reals @ FPR 10% 0.00176024 0.9959 [0.9944, 0.9971] 0.9978 [0.9969, 0.9984] 0.9983 [0.9906, 0.9997] 0.9950 [0.9854, 0.9983] 0.0986 [0.0906, 0.1072] 0.5192 [0.5053, 0.5330] 0.1000 [0.0905, 0.1104]

n: organiser fakes 8,843, CF fakes 16,000, stress nano-banana 600, stress echo-4o-gptimage 600, coco-orig reals 5,000, coco-wildfake reals 4,998, CF LAION reals 3,500. Brackets are Wilson 95 % score intervals. These are single-sample rates on fixed persisted arrays: there is NO repeat-run noise floor for them beyond the interval.

Accuracy beside the accuracy nobody has to earn

always-fake never looks at a pixel and returns fake for every row. On a split whose fakes outnumber its reals, that alone is the accuracy an honest headline has to beat.

threshold organiser coco-orig acc always-fake balanced organiser coco-wildfake acc always-fake balanced CF breadth slice acc always-fake balanced
served 0.5 0.6103 0.6388 0.6950 0.6096 0.6389 0.6942 0.6189 0.8205 0.7677
coco-orig reals @ FPR 1% 0.9732 0.6388 0.9769 0.9228 0.6389 0.9071 0.9828 0.8205 0.9853
coco-orig reals @ FPR 5% 0.9753 0.6388 0.9698 0.8585 0.6389 0.8080 0.9869 0.8205 0.9717
coco-orig reals @ FPR 10% 0.9613 0.6388 0.9480 0.8092 0.6389 0.7374 0.9801 0.8205 0.9486
CF LAION reals @ FPR 1% 0.9708 0.6388 0.9754 0.9271 0.6389 0.9148 0.9807 0.8205 0.9843
CF LAION reals @ FPR 5% 0.9761 0.6388 0.9713 0.8616 0.6389 0.8128 0.9869 0.8205 0.9725
CF LAION reals @ FPR 10% 0.9618 0.6388 0.9487 0.8099 0.6389 0.7384 0.9802 0.8205 0.9489

Reporting-only: every τ above is a quantile of a reals population, published beside its realised FPR. The served threshold is unchanged; nothing here fits, selects or trains.

Full 16-cell tables, both protocols and both COCO copies, with null rows: docs/robustness.md in the project repo.

Files

config.json + calib.json + MANIFEST.json here define the fused serving; members/pe-core-v2/ (head A) and members/pe-core-v31/ (head B) hold the two heads with their Platt calibration, 62 KB in total.

Use

# from a clone of the project repo, where this checkpoint ships as weights/current/
uv sync
uv run predict --input-dir path/to/images --output preds.json --checkpoint weights/current

# the same checkpoint is mirrored on the Hugging Face hub
uv run hf download audya/techjam-2026-track5 --local-dir weights/hf     # config, calib, MANIFEST, members/
uv run predict --input-dir path/to/images --output preds.json --checkpoint weights/hf

Output: a JSON list of {"image_path", "pred"}, pred = P(AI-generated) ∈ [0, 1]. An undecodable image gets 0.5 (the threshold itself, not a measurement) and is named on stderr. The tower downloads once (~1.2 GB); GPU when present, CPU otherwise.

Licence

Heads, calibration and config: Apache-2.0. Backbone: Apache-2.0 (Meta Perception Encoder Core, via timm). Training data: WildFake (ModelScope, Apache-2.0; its LAION-5B reals are URL-derived third-party photographs, never redistributed), COCO train2017 (annotations CC-BY-4.0, images under their Flickr terms), SID-Set (CC-BY-4.0), Community Forensics (CC-BY-4.0). No organiser validation image was used for training, calibration or selection.

Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support