Image Classification
Transformers
ONNX
Safetensors
timm
vit
detection
deepfake
forensics
deepfake_detection
community
opensight
Instructions to use buildborderless/CommunityForensics-DeepfakeDet-ViT with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use buildborderless/CommunityForensics-DeepfakeDet-ViT with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-classification", model="buildborderless/CommunityForensics-DeepfakeDet-ViT") pipe("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/parrots.png")# pip install -U transformers accelerate # Load model directly from transformers import AutoImageProcessor, AutoModelForImageClassification processor = AutoImageProcessor.from_pretrained("buildborderless/CommunityForensics-DeepfakeDet-ViT") model = AutoModelForImageClassification.from_pretrained("buildborderless/CommunityForensics-DeepfakeDet-ViT", device_map="auto") - timm
How to use buildborderless/CommunityForensics-DeepfakeDet-ViT with timm:
import timm model = timm.create_model("hf-hub:buildborderless/CommunityForensics-DeepfakeDet-ViT", pretrained=True) - Inference
- Notebooks
- Google Colab
- Kaggle
fix: regenerate model.safetensors from correct .pt checkpoint
Browse filesThe old safetensors was converted from different weights (intermediate_size=3072,
num_classes=2 classifier, different backbone weights) instead of the correct
trained checkpoint (intermediate_size=1536, num_classes=1, ViT-Small 6 heads).
Changes:
- model.safetensors: regenerated from pretrained_weights/model_v11_ViT_384_base_ckpt.pt
- config.json: num_classes=2→1, intermediate_size=3072→1536, correct for ViT-Small
- preprocessor_config.json: size changed to shortest_edge=440 (no more squashing)
- test_app: handle num_classes=1 with sigmoid output
- .gitignore +2 -0
- config.json +3 -5
- model.safetensors +2 -2
- preprocessor_config.json +1 -2
- test_app/app.py +20 -12
.gitignore
CHANGED
|
@@ -1 +1,3 @@
|
|
| 1 |
.agents/
|
|
|
|
|
|
|
|
|
| 1 |
.agents/
|
| 2 |
+
__pycache__/
|
| 3 |
+
*.pyc
|
config.json
CHANGED
|
@@ -7,22 +7,20 @@
|
|
| 7 |
"hidden_dropout_prob": 0.0,
|
| 8 |
"hidden_size": 384,
|
| 9 |
"id2label": {
|
| 10 |
-
"0": "real"
|
| 11 |
-
"1": "fake"
|
| 12 |
},
|
| 13 |
"image_size": 384,
|
| 14 |
"initializer_range": 0.02,
|
| 15 |
"input_size": 384,
|
| 16 |
-
"intermediate_size":
|
| 17 |
"label2id": {
|
| 18 |
-
"fake": 1,
|
| 19 |
"real": 0
|
| 20 |
},
|
| 21 |
"layer_norm_eps": 1e-06,
|
| 22 |
"model_type": "vit",
|
| 23 |
"num_attention_heads": 6,
|
| 24 |
"num_channels": 3,
|
| 25 |
-
"num_classes":
|
| 26 |
"num_hidden_layers": 12,
|
| 27 |
"patch_size": 16,
|
| 28 |
"qkv_bias": true,
|
|
|
|
| 7 |
"hidden_dropout_prob": 0.0,
|
| 8 |
"hidden_size": 384,
|
| 9 |
"id2label": {
|
| 10 |
+
"0": "real"
|
|
|
|
| 11 |
},
|
| 12 |
"image_size": 384,
|
| 13 |
"initializer_range": 0.02,
|
| 14 |
"input_size": 384,
|
| 15 |
+
"intermediate_size": 1536,
|
| 16 |
"label2id": {
|
|
|
|
| 17 |
"real": 0
|
| 18 |
},
|
| 19 |
"layer_norm_eps": 1e-06,
|
| 20 |
"model_type": "vit",
|
| 21 |
"num_attention_heads": 6,
|
| 22 |
"num_channels": 3,
|
| 23 |
+
"num_classes": 1,
|
| 24 |
"num_hidden_layers": 12,
|
| 25 |
"patch_size": 16,
|
| 26 |
"qkv_bias": true,
|
model.safetensors
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:275ba982236ddd6afddf7131f8133e89f537574b964cf8fa5825b4956d741692
|
| 3 |
+
size 87270764
|
preprocessor_config.json
CHANGED
|
@@ -7,7 +7,6 @@
|
|
| 7 |
"image_std": [0.26862954, 0.26130258, 0.27577711],
|
| 8 |
"resample": 3,
|
| 9 |
"size": {
|
| 10 |
-
"
|
| 11 |
-
"width": 440
|
| 12 |
}
|
| 13 |
}
|
|
|
|
| 7 |
"image_std": [0.26862954, 0.26130258, 0.27577711],
|
| 8 |
"resample": 3,
|
| 9 |
"size": {
|
| 10 |
+
"shortest_edge": 440
|
|
|
|
| 11 |
}
|
| 12 |
}
|
test_app/app.py
CHANGED
|
@@ -86,9 +86,11 @@ def _get_onnx(variant):
|
|
| 86 |
return _onnx_sessions[variant]
|
| 87 |
|
| 88 |
def _onnx_preprocess(image):
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
|
|
|
|
|
|
| 92 |
img = img.crop((left, top, left + 384, top + 384))
|
| 93 |
arr = np.array(img, dtype=np.float32)
|
| 94 |
arr *= np.float32(1.0 / 255.0)
|
|
@@ -109,15 +111,21 @@ def compare(image, onnx_variants):
|
|
| 109 |
inputs = {k: v.to(pt_device) for k, v in inputs.items()}
|
| 110 |
with torch.no_grad():
|
| 111 |
logits = pt_model(**inputs).logits[0].cpu()
|
| 112 |
-
|
| 113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
pt_ms = (time.perf_counter() - t0) * 1000
|
| 115 |
|
| 116 |
pt = {
|
| 117 |
"device": pt_device.upper(),
|
| 118 |
"prediction": pt_pred,
|
| 119 |
-
"real": round(pt_probs[0]
|
| 120 |
-
"fake": round(pt_probs[1]
|
| 121 |
"time_ms": round(pt_ms, 1),
|
| 122 |
}
|
| 123 |
|
|
@@ -236,15 +244,15 @@ def compare_old_new(image):
|
|
| 236 |
inputs = {k: v.to(pt_device) for k, v in inputs.items()}
|
| 237 |
with torch.no_grad():
|
| 238 |
logits = pt_model(**inputs).logits[0].cpu()
|
| 239 |
-
|
| 240 |
-
new_pred =
|
| 241 |
new_ms = (time.perf_counter() - t0) * 1000
|
| 242 |
|
| 243 |
new_result = {
|
| 244 |
-
"backend": "ViTForImageClassification (fixed
|
| 245 |
"prediction": new_pred,
|
| 246 |
-
"real": round(
|
| 247 |
-
"fake": round(
|
| 248 |
"time_ms": round(new_ms, 1),
|
| 249 |
}
|
| 250 |
|
|
|
|
| 86 |
return _onnx_sessions[variant]
|
| 87 |
|
| 88 |
def _onnx_preprocess(image):
|
| 89 |
+
w, h = image.size
|
| 90 |
+
scale = 440 / min(w, h)
|
| 91 |
+
img = image.resize((int(w * scale), int(h * scale)))
|
| 92 |
+
left = (img.size[0] - 384) // 2
|
| 93 |
+
top = (img.size[1] - 384) // 2
|
| 94 |
img = img.crop((left, top, left + 384, top + 384))
|
| 95 |
arr = np.array(img, dtype=np.float32)
|
| 96 |
arr *= np.float32(1.0 / 255.0)
|
|
|
|
| 111 |
inputs = {k: v.to(pt_device) for k, v in inputs.items()}
|
| 112 |
with torch.no_grad():
|
| 113 |
logits = pt_model(**inputs).logits[0].cpu()
|
| 114 |
+
if pt_model.config.num_classes == 1:
|
| 115 |
+
fake_prob = torch.sigmoid(logits).item()
|
| 116 |
+
pt_pred = "fake" if fake_prob > 0.5 else "real"
|
| 117 |
+
pt_probs = [1.0 - fake_prob, fake_prob]
|
| 118 |
+
else:
|
| 119 |
+
pt_probs_arr = torch.softmax(logits, dim=-1)
|
| 120 |
+
pt_pred = pt_model.config.id2label[torch.argmax(pt_probs_arr).item()]
|
| 121 |
+
pt_probs = [pt_probs_arr[0].item(), pt_probs_arr[1].item()]
|
| 122 |
pt_ms = (time.perf_counter() - t0) * 1000
|
| 123 |
|
| 124 |
pt = {
|
| 125 |
"device": pt_device.upper(),
|
| 126 |
"prediction": pt_pred,
|
| 127 |
+
"real": round(pt_probs[0], 4),
|
| 128 |
+
"fake": round(pt_probs[1], 4),
|
| 129 |
"time_ms": round(pt_ms, 1),
|
| 130 |
}
|
| 131 |
|
|
|
|
| 244 |
inputs = {k: v.to(pt_device) for k, v in inputs.items()}
|
| 245 |
with torch.no_grad():
|
| 246 |
logits = pt_model(**inputs).logits[0].cpu()
|
| 247 |
+
fake_prob = torch.sigmoid(logits).item()
|
| 248 |
+
new_pred = "fake" if fake_prob > 0.5 else "real"
|
| 249 |
new_ms = (time.perf_counter() - t0) * 1000
|
| 250 |
|
| 251 |
new_result = {
|
| 252 |
+
"backend": "ViTForImageClassification (fixed, July 2026)",
|
| 253 |
"prediction": new_pred,
|
| 254 |
+
"real": round(1.0 - fake_prob, 4),
|
| 255 |
+
"fake": round(fake_prob, 4),
|
| 256 |
"time_ms": round(new_ms, 1),
|
| 257 |
}
|
| 258 |
|