File size: 3,983 Bytes
9a5883b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
105
---
license: apache-2.0
tags:
  - image-classification
  - ai-generated-image-detection
  - lora
  - robustlens
  - techjam-2026
library_name: pytorch
---

# RobustLens β€” experimental LoRA adapters

Adapters produced while building **RobustLens**, a transformation-resistant
AI-generated-image detector for TikTok TechJam 2026 Track 5.

> ## ⚠️ None of these adapters were adopted
>
> Every adapter here comes from an experiment that was **rejected on
> measurement**. They are published for reproducibility and provenance β€” so a
> collaborator can verify the rejections rather than take them on trust.
>
> **The production RobustLens system does not use any of them.** It runs the
> unmodified base checkpoint. If you want to *use* RobustLens, you do not need
> anything in this repository.

## What the production system actually uses

The base detector, unmodified:

- **[Bombek1/ai-image-detector-siglip-dinov2](https://huggingface.co/Bombek1/ai-image-detector-siglip-dinov2)**
  β€” SigLIP2-SO400M + DINOv2-Large with LoRA, 740,371,777 parameters
- SHA-256 `caae0c005d8e37e7aa086aa241d1c9445d296ef77649004655c14f5c81130d4b`
- Frozen calibrated threshold **0.69**

## Contents

Each directory holds `adapter_config.json`, `adapter_model.safetensors`
(existing LoRA tensors only β€” no full backbone weights) and
`classifier_head.pt`. About 32 MB each.

| Adapter | Experiment | Outcome |
|---|---|---|
| `local_edit_smoke` | Head-only fine-tune on local AI edits | **Rejected** β€” held-out AUROC fell 0.510 β†’ 0.354 |
| `consistency_classification_only` | Ablation baseline, BCE loss only | Reference arm |
| `consistency_consistency_mse` | + logit-MSE transformation-consistency loss | **Rejected** β€” no gain (F1 0.7500, AUROC 0.4375) |
| `consistency_consistency_kl` | + symmetric-KL consistency loss | **Rejected** β€” no gain (F1 0.7500, AUROC 0.4479) |

All four are `head_only` mode: 1,250,561 trainable parameters against
739,121,216 frozen. **No second LoRA adapter was added** β€” the existing adapter
tensors in the base checkpoint were reused.

## Why they were rejected

**Local-edit fine-tune.** Pre-registered rule: adopt only if local-edit recall or
F1 improves by β‰₯0.01 without authentic FPR rising more than 0.05. Held out
(n=20, threshold 0.5):

| Metric | Original | Fine-tuned | Ξ” |
|---|---:|---:|---:|
| Accuracy | 0.6000 | 0.6000 | +0.0000 |
| F1 | 0.7500 | 0.7500 | +0.0000 |
| Recall | 1.0000 | 1.0000 | +0.0000 |
| **AUROC** | 0.5104 | **0.3542** | **βˆ’0.1562** |

Ranking quality fell and nothing improved, so the adapter was not adopted.

**Consistency loss.** Three runs differing only in the loss; all variants saw
identical paired transformed views. No variant met the +0.01 bar, so
classification-only training was kept and the consistency loss ships disabled.

## Important limitation

These adapters were trained on **68 training images** and evaluated on **20 test
images**. That is enough to demonstrate the pipeline runs end to end and nowhere
near enough to conclude anything about fine-tuning as a method. Treat every
number above as a smoke test, not evidence about the approach.

Threshold 0.5 was used for the comparison rather than the production 0.69,
because a calibration fitted for one model does not transfer to another.

## Using an adapter

Adapters load onto a model restored from the **base checkpoint** β€” they are not
standalone models.

```bash
# fetch into models/adapters/
python scripts/download_adapters.py --adapter local_edit_smoke

python scripts/run_inference.py \
    --input-dir path/to/images \
    --adapter-dir models/adapters/local_edit_smoke \
    --no-calibration \
    --output outputs/predictions.json
```

`--no-calibration` matters: the shipped calibration and the 0.69 threshold were
fitted for the base checkpoint and do not apply to an adapted model.

## Source

Code, evaluation protocol and full results:
[RobustLens](https://github.com/) β€” see `FINAL_RESULTS.md` and `AUDIT.md`.