File size: 7,500 Bytes
a600a2e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
---
license: apache-2.0
language:
- en
library_name: pytorch
pipeline_tag: image-classification
base_model: laion/CLIP-ViT-B-32-laion2B-s34B-b79K
datasets:
- yangsangtai/tiny-genimage
metrics:
- accuracy
- precision
- recall
- f1
- roc_auc
tags:
- image-classification
- ai-generated-image-detection
- deepfake-detection
- clip
- computer-vision
- binary-classification
---

# CLIP-Based AI-Generated Image Detector

## Model Description

This model is a binary image classifier that distinguishes real (natural) photographs from AI-generated images. It uses a frozen CLIP ViT-B/32 vision encoder (pretrained on LAION-2B) as a fixed feature extractor, with a lightweight multilayer perceptron classification head trained on top of the extracted image embeddings.

The model was developed and trained in a Kaggle notebook titled `complete_Fakeddit_image`. Despite the notebook name, the training data used is the `tiny-genimage` dataset rather than the Fakeddit dataset; this README describes the model as actually implemented and trained.

## Model Details

- **Base encoder:** CLIP ViT-B-32, pretrained weights `laion2b_s34b_b79k` (loaded via `open_clip`)
- **Encoder state:** Frozen; no gradient updates applied to CLIP parameters during training
- **Classification head:** Fully connected network operating on 512-dimensional, L2-normalized CLIP image embeddings

| Layer | Output Size | Normalization | Activation | Dropout |
|---|---|---|---|---|
| Linear | 512 | BatchNorm1d | GELU | 0.4 |
| Linear | 256 | BatchNorm1d | GELU | 0.3 |
| Linear | 128 | BatchNorm1d | GELU | 0.2 |
| Linear | 2 | - | - | - |

- **Output:** Two logits corresponding to the classes `real` (label 0) and `ai-generated` (label 1)
- **Framework:** PyTorch, with `open_clip` for the CLIP backbone
- **Input resolution:** 224 x 224 pixels, RGB

## Intended Use

The model is intended for research and experimentation in AI-generated image detection, such as:

- Screening images for likely synthetic origin
- Research on generalization of detectors across different generative model families
- Educational use in understanding CLIP-based transfer learning for detection tasks

### Out of Scope Use

This model is not intended for:

- Legal, forensic, or high-stakes determinations of image authenticity without human review
- Detection of generative models or techniques not represented in the training distribution
- Use as a sole determinant of content moderation decisions

## Training Data

The model was trained on the `tiny-genimage` dataset (source: `yangsangtai/tiny-genimage`), which pairs natural images with images produced by seven different generative model families.

- **Total images:** 35,000
- **Class balance:** 17,500 real images (label 0), 17,500 AI-generated images (label 1)
- **Train / validation split:** 28,000 / 7,000 images

Generators represented in the dataset, each contributing 5,000 images:

- imagenet_ai_0424_wukong
- imagenet_glide
- imagenet_ai_0419_biggan
- imagenet_ai_0419_vqdm
- imagenet_midjourney
- imagenet_ai_0424_sdv5
- imagenet_ai_0508_adm

## Training Procedure

### Preprocessing and Augmentation

Implemented using the `albumentations` library.

**Training transforms:**
- Resize to 224 x 224
- Horizontal flip (probability 0.5)
- Random brightness/contrast (probability 0.3)
- Normalization
- Conversion to tensor

**Validation transforms:**
- Resize to 224 x 224
- Normalization
- Conversion to tensor

### Optimization

- **Loss function:** Cross-entropy loss
- **Optimizer:** AdamW, applied only to the classification head parameters
- **Learning rate:** 1e-4 (initial training phase), reduced to 1e-5 for a subsequent fine-tuning phase
- **Learning rate schedule:** Cosine annealing
- **Batch size:** 32
- **Maximum epochs:** 20, with early stopping (patience of 5 epochs, monitored on validation F1 score)
- **Checkpointing:** Best model saved whenever validation F1 improved; full training state (model, optimizer, scheduler, epoch, best F1) checkpointed for resumption
- **Hardware:** Single NVIDIA Tesla T4 GPU

Training was conducted in two stages within the notebook: an initial run to 18 epochs before early stopping triggered a checkpoint save, followed by a resumed run at a lower learning rate for 2 additional epochs.

## Evaluation

Evaluation was performed on the held-out validation split (7,000 images) using the checkpoint with the best validation F1 score.

### Final Reported Metrics

| Metric | Score |
|---|---|
| Accuracy | 0.9500 |
| Precision | 0.9474 |
| Recall | 0.9529 |
| F1 Score | 0.9501 |
| ROC AUC | 0.9894 |

A confusion matrix was also generated on the validation set to inspect class-wise performance; see the original notebook for the corresponding plot.

## Usage

```python
import torch
import torch.nn as nn
import torch.nn.functional as F
import open_clip
from PIL import Image
import albumentations as A
from albumentations.pytorch import ToTensorV2
import numpy as np

DEVICE = "cuda" if torch.cuda.is_available() else "cpu"

# Load CLIP backbone
clip_model, _, _ = open_clip.create_model_and_transforms(
    "ViT-B-32",
    pretrained="laion2b_s34b_b79k"
)
clip_model = clip_model.to(DEVICE)
for param in clip_model.parameters():
    param.requires_grad = False

# Define classifier head
class CLIPBinaryClassifier(nn.Module):
    def __init__(self):
        super().__init__()
        self.clip = clip_model
        self.classifier = nn.Sequential(
            nn.Linear(512, 512), nn.BatchNorm1d(512), nn.GELU(), nn.Dropout(0.4),
            nn.Linear(512, 256), nn.BatchNorm1d(256), nn.GELU(), nn.Dropout(0.3),
            nn.Linear(256, 128), nn.BatchNorm1d(128), nn.GELU(), nn.Dropout(0.2),
            nn.Linear(128, 2)
        )

    def forward(self, images):
        with torch.no_grad():
            features = self.clip.encode_image(images)
        features = F.normalize(features, dim=-1)
        return self.classifier(features)

# Load trained weights
model = CLIPBinaryClassifier().to(DEVICE)
model.load_state_dict(torch.load("best_clip_detector.pth", map_location=DEVICE))
model.eval()

# Preprocess an image
transform = A.Compose([
    A.Resize(224, 224),
    A.Normalize(),
    ToTensorV2()
])

image = np.array(Image.open("example.jpg").convert("RGB"))
image_tensor = transform(image=image)["image"].unsqueeze(0).to(DEVICE)

# Run inference
with torch.no_grad():
    logits = model(image_tensor)
    probs = torch.softmax(logits, dim=1)
    prediction = logits.argmax(1).item()

label_map = {0: "real", 1: "ai-generated"}
print(label_map[prediction], probs.cpu().numpy())
```

## Limitations

- The training data is derived from ImageNet-based real images paired with a fixed set of seven generative model families; performance on generators, domains, or image types outside this distribution is not established.
- The dataset is referred to as "tiny-genimage," implying it is a reduced-scale subset of a larger dataset; results may not generalize to the full-scale version.
- The classification head was trained on frozen CLIP embeddings only; the underlying CLIP encoder was not fine-tuned, which may limit adaptation to subtle generation artifacts not captured by general-purpose CLIP features.
- No adversarial robustness testing was performed against images specifically crafted to evade detection.

## Citation

If you use this model, please cite the underlying CLIP and dataset resources:

```
CLIP backbone: laion2b_s34b_b79k (OpenCLIP, LAION)
Dataset: tiny-genimage (yangsangtai/tiny-genimage)
```