Slopscan-Anime

Detects if an anime image was generated by AI or drawn by a human.

License: CC BY-NC 4.0 GitHub Python 3.11 PyTorch 2.11


Highlights

Slopscan-Anime is a binary image classifier that separates AI-generated anime art (Stable Diffusion / NovelAI / Midjourney / Flux / ...) from human-drawn art. It is a fine-tune of ConvNeXt V2 Base at 1024×1024, tuned for high precision on in-the-wild booru content.

  • 0.9961 accuracy / 0.9998 AUROC on a 29,390-image held-out test set
  • Trained on 235,130 images with automatic label cleaning
  • Runs on a consumer GPU (~1.2 GB VRAM, ~70 ms/image on an RTX 4070 Super) or CPU
  • Single-file inference code, no framework dependencies beyond timm + torchvision

Note on scores: training used label smoothing and mixup, so probabilities are compressed. AI images rarely score above ~0.92. Rank ordering is what matters. The recommended cutoff is 0.42, lower it for more sensitivity, raise it for less false positives.

Model Overview

Architecture ConvNeXt V2 Base (convnextv2_base.fcmae_ft_in22k_in1k_384, 88.7M params)
Head Linear, 2 logits
Input RGB, resize to 1056px (shorter side), center crop 1024×1024
Normalization ImageNet mean [0.485, 0.456, 0.406], std [0.229, 0.224, 0.225]
Output P(AI generated), 0..1
Weights in best.pt EMA of the final fine-tune (1024px stage)
Recommended threshold 0.42

Evaluation Results

Held-out test set, n = 29,390 (~50/50 class balance):

Accuracy Precision Recall F1 AUROC ECE
0.9961 0.9951 0.9970 0.9961 0.9998 0.064

The threshold is set for F1 on validation; precision is slightly below recall by design, so the tool errs toward catching AI images at the cost of a few false positives.

Training Recipe

Data scraped from rule34.xxx via its public API:

Split Images Source
Train 235,130 ai_generated tag (AI) vs. -ai_generated -stable_diffusion -novelai -midjourney -flux -sdxl -dall-e -pixai -yodayo -comfyui sort:random (human)
Val 29,390 same pipeline, stratified
Test 29,390 same pipeline, stratified

All images were validated with Pillow and deduplicated by MD5 before splitting.

Fine-tuning warm-started from an earlier 512px checkpoint, then three progressive stages:

Stage Resolution Batch size LR Epochs Best val AUROC
1 384 32 1.5e-5 20 0.9997
2 512 16 1e-5 5 0.9997
3 1024 4 1e-5 4 0.9999

Recipe: RandAugment, mixup 0.2, label smoothing 0.1, soft-target loss, EMA 0.999, cosine LR with 5% warmup, bf16 autocast. A 384/512/1024 ensemble was evaluated and did not beat the single 1024px model.

Quickstart

git clone https://github.com/Dominik7272/Slopscan
cd Slopscan
pip install -r requirements.txt
pip install huggingface_hub
hf download Dominik72/Slopscan-Anime best.pt --local-dir .
from slopscan import Slopscan

model = Slopscan("best.pt")           # loads the model once, GPU if available
prob = model.classify("image.png")    # P(AI generated), 0..1

classify accepts a path or an already-open PIL.Image. CUDA is used when available; expect ~70 ms/image on an RTX 4070 Super and ~1.2 GB VRAM.

ONNX

best.onnx from the same repo has the same weights and output (1024×1024 input, raw logits) and runs without PyTorch, on onnxruntime alone:

import numpy as np
import onnxruntime as ort
from PIL import Image

MEAN = np.array([0.485, 0.456, 0.406], dtype=np.float32)
STD = np.array([0.229, 0.224, 0.225], dtype=np.float32)

image = Image.open("image.png").convert("RGB")
w, h = image.size
scale = 1056 / min(w, h)
image = image.resize((round(w * scale), round(h * scale)), Image.BILINEAR)
left, top = (image.width - 1024) // 2, (image.height - 1024) // 2
image = image.crop((left, top, left + 1024, top + 1024))

x = np.asarray(image, dtype=np.float32) / 255.0
x = (x - MEAN) / STD
x = x.transpose(2, 0, 1)[None]      # NCHW

session = ort.InferenceSession("best.onnx", providers=["CPUExecutionProvider"])
logits = session.run(None, {"image": x})[0][0]
e = np.exp(logits - logits.max())
prob = float(e[1] / e.sum())        # P(AI generated), 0..1

Limitations and Disclaimer

  • Domain: trained on anime illustration art. It will not generalize to photos, photorealistic renderings, or non-anime styles.
  • 3D renders: human-made 3D work (Blender / MMD / SFM / Daz) is sometimes flagged as AI. This is a known weakness and the target of the next model version.
  • Label noise: the ai_generated tag is applied by uploaders; untagged AI uploads land in the human set. The ~0.4% test error roughly bounds this noise.
  • Distribution shift: new generators and artist mimicry can be misclassified.
  • A prediction is a hint, not proof about a creator's process. Do not use this model to harass artists or to make definitive accusations.

License

CC BY-NC 4.0 non-commercial use only. This model is a fine-tune of FAIR's ConvNeXt V2 weights, which are released under CC BY-NC 4.0, so the derivative inherits the same restriction. Training images were scraped from publicly viewable rule34.xxx pages and are not redistributed here.

Citation

If you use this model, please cite the backbone it is built on:

@article{Woo2023ConvNeXtV2,
  title={ConvNeXt V2: Co-designing and Scaling ConvNets with Masked Autoencoders},
  author={Sanghyun Woo, Shoubhik Debnath, Ronghang Hu, Xinlei Chen, Zhuang Liu, In So Kweon and Saining Xie},
  year={2023},
  journal={arXiv preprint arXiv:2301.00808},
}

@misc{rw2019timm,
  author = {Ross Wightman},
  title = {PyTorch Image Models},
  year = {2019},
  publisher = {GitHub},
  journal = {GitHub repository},
  doi = {10.5281/zenodo.4414861},
  howpublished = {\url{https://github.com/huggingface/pytorch-image-models}}
}
Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for Dominik72/Slopscan-Anime

Quantized
(1)
this model

Space using Dominik72/Slopscan-Anime 1

Paper for Dominik72/Slopscan-Anime