File size: 3,742 Bytes
33a7a3a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | ---
license: apache-2.0
language:
- fr
- en
library_name: onnx
pipeline_tag: image-segmentation
tags:
- document-forensics
- image-manipulation-detection
- tampering-detection
- fraud-detection
- payslip
- banking
- onnx
- pytorch
- synthetic-data
metrics:
- roc_auc
- f1
---
# docverify — payslip tampering detection
A forensic segmentation network that finds **where a payslip was edited** — copy-move, splice from
another document, or a re-typed amount — and the small models and thresholds that turn its pixel
map into a verdict an analyst can act on.
Part of **docverify**, a complete system with arithmetic checks, PDF forensics and a local LLM note:
[project](https://github.com/Elghoudani/docverify) ·
[YOLO field detector](https://huggingface.co/ghostsas001/docverify-yolo-fields)

## Files
| File | What it is |
|---|---|
| `tampernet.onnx` | the served model — ONNX FP32, 1.56× faster than PyTorch on CPU, identical decisions |
| `tampernet.pt` | the same weights for PyTorch |
| `threshold.json` | page threshold 7.86 (5% false alarms on genuine payslips), field threshold 9.19 (1% of genuine pages rated high risk) |
| `siglip_probe.json` | linear probe on frozen Google SigLIP image embeddings: payslip / RIB / invoice |
| `version.txt` | release `2` |
## Model
**TamperNet** (~33M parameters): a pretrained ConvNeXt encoder on RGB, plus two forensic inputs —
fixed **SRM noise residual** filters (edits break the sensor/print noise) and a **JPEG/DCT** branch
(a pasted region carries its own 8×8 compression grid) — fused into a U-Net-style decoder that
outputs one logit per pixel. The page score is the mean of the top-200 pixel logits.
Inference runs at full resolution (1000 × 1414 px pages, padded to a multiple of 32 to keep the JPEG grid).
## Results
Frozen test split: 793 synthetic payslips (390 genuine, 403 forged), never seen in training.
| Metric | v2 (this release) | v1 (U-Net) |
|---|---|---|
| ROC-AUC | **0.902** | 0.877 |
| Forgeries caught at 1% false alarms | **61%** | 55% |
| Forgeries caught at 5% false alarms | **72%** | 66% |
| Pixel F1 on forged pages | **0.81** | 0.77 |
| Pixel IoU | **0.68** | 0.62 |
| Segment (recall at 5% false alarms) | v2 |
|---|---|
| Splice (pasted from another document) | 90% |
| Copy-move (inside the document) | 77% |
| Rewritten amount | 50% |
| Scanned | 77% |
| Phone photo | 63% |



Rewritten amounts are the hard case for pixels alone. In the full system, seven payslip
arithmetic rules raise recall on them from 56% to 92%, and on all forgeries to **95% at 1.7% false
alarms** (240-document OCR subset):

## Speed
A full page needs ~4 GB of RAM and ~5 s on 4 CPU threads (~0.44 s on a T4).

## Limits
- **Synthetic data only.** Trained and evaluated on generated French payslips (Faker `fr_FR`, fake
people and companies). Never measured on real documents.
- Built for one layout family (French payslips). Other documents need adaptation; the forensic
branches are generic.
- It flags; it does not decide. In docverify, a human analyst always makes the decision.
- EU AI Act: fraud detection is excluded from the Annex III 5(b) high-risk category. Using this
score directly to grant or refuse credit would not be.
## License
Apache-2.0. The ConvNeXt encoder was initialised from `timm` ImageNet weights (Apache-2.0).
The SigLIP probe applies to Google's SigLIP (Apache-2.0), downloaded from Google's repository.
|