karthikeya1212 commited on
Commit
637e17b
Β·
verified Β·
1 Parent(s): fba7b83

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +82 -75
app.py CHANGED
@@ -3,21 +3,22 @@ from transformers import AutoImageProcessor, AutoModelForImageClassification
3
  from PIL import Image
4
  import torch
5
  import torch.nn.functional as F
6
- import numpy as np
7
 
8
- # Multiple specialized models for ensemble detection
 
9
  MODELS = [
10
- "Ateeqq/ai-vs-human-image-detector", # SigLIP-based - Best for DALL-E 3, Midjourney
11
- "umm-maybe/AI-image-detector", # Vision Transformer - Good for Stable Diffusion
12
- "facebook/dinov2-small", # Meta's DINOv2 - Excellent feature detector
13
  ]
14
 
15
- print("Loading models for ensemble detection...")
16
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
17
  print(f"Device: {device}\n")
18
 
19
  models_list = []
20
  processors_list = []
 
21
 
22
  for i, model_name in enumerate(MODELS):
23
  try:
@@ -27,110 +28,116 @@ for i, model_name in enumerate(MODELS):
27
  model.eval()
28
  models_list.append(model)
29
  processors_list.append(processor)
30
- print(f"βœ“ Model {i+1} loaded successfully!\n")
 
31
  except Exception as e:
32
- print(f"βœ— Failed to load {model_name}: {e}\n")
33
 
34
  if not models_list:
35
- raise Exception("Failed to load any models!")
36
 
37
- print(f"Successfully loaded {len(models_list)} models for ensemble voting\n")
38
 
39
  def predict(image):
40
  if image is None:
41
- return "No image uploaded", 0.0, "No image provided"
42
 
43
  try:
44
- # Convert to RGB if necessary
45
  if image.mode != 'RGB':
46
  image = image.convert('RGB')
47
 
48
  all_ai_probs = []
49
- all_real_probs = []
50
 
51
- # Get predictions from all models
52
- for i, (processor, model) in enumerate(zip(processors_list, models_list)):
53
  try:
54
- # Special handling for DINOv2 (feature extractor)
55
- if i == 2: # DINOv2
56
- from torchvision import transforms
57
- transform = transforms.Compose([
58
- transforms.Resize((224, 224)),
59
- transforms.ToTensor(),
60
- transforms.Normalize(mean=[0.485, 0.456, 0.406],
61
- std=[0.229, 0.224, 0.225])
62
- ])
63
- img_tensor = transform(image).unsqueeze(0).to(device)
64
- with torch.no_grad():
65
- features = model(img_tensor)
66
- # Use feature statistics for detection
67
- feature_mean = features.mean()
68
- feature_std = features.std()
69
- ai_prob = float((feature_std.cpu() / (feature_mean.cpu() + 1e-6)).clamp(0, 1))
70
- real_prob = 1.0 - ai_prob
71
- else:
72
- inputs = processor(images=image, return_tensors="pt").to(device)
73
- with torch.no_grad():
74
- outputs = model(**inputs)
75
- logits = outputs.logits
76
- probs = F.softmax(logits, dim=1)[0].cpu().numpy()
77
- real_prob = float(probs[0])
78
- ai_prob = float(probs[1])
79
 
80
- all_real_probs.append(real_prob)
81
  all_ai_probs.append(ai_prob)
82
 
 
 
 
 
 
 
 
 
 
 
83
  except Exception as e:
84
- print(f"Error in model {i+1}: {e}")
85
  continue
86
 
87
  if not all_ai_probs:
88
- return "Error: No models could process the image", 0.0, "All models failed"
89
 
90
- # Ensemble voting - take average of all models
91
- avg_ai_prob = np.mean(all_ai_probs)
92
- avg_real_prob = np.mean(all_real_probs)
93
 
94
- # Get individual model predictions for transparency
95
- model_predictions = []
96
- for j, (real, ai) in enumerate(zip(all_real_probs, all_ai_probs)):
97
- pred = "AI-Generated" if ai > real else "Real Photo"
98
- confidence = max(ai, real)
99
- model_predictions.append(f"Model {j+1}: {pred} ({confidence:.4f})")
 
 
 
 
 
 
 
 
 
 
100
 
101
- # Determine final label
102
- label = "AI-Generated" if avg_ai_prob > avg_real_prob else "Real Photo"
103
- confidence = max(avg_ai_prob, avg_real_prob)
 
 
 
 
 
 
104
 
105
- # Build detailed results
106
- result_text = f"""
107
- ENSEMBLE VOTING RESULT (3 Models):
108
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
109
- Final Prediction: {label}
110
- Ensemble AI Probability: {avg_ai_prob:.4f}
111
- Ensemble Real Probability: {avg_real_prob:.4f}
112
- Overall Confidence: {confidence:.4f}
113
 
114
- INDIVIDUAL MODEL PREDICTIONS:
115
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
116
- """ + "\n".join(model_predictions)
 
 
 
117
 
118
- return label, round(avg_ai_prob, 4), result_text
119
 
120
  except Exception as e:
121
- return f"Error: {str(e)}", 0.0, f"Error occurred: {str(e)}"
122
 
123
- # Create interface
124
  demo = gr.Interface(
125
  fn=predict,
126
- inputs=gr.Image(type="pil", label="Upload Image"),
127
  outputs=[
128
- gr.Textbox(label="Final Prediction"),
129
- gr.Number(label="AI Probability Score"),
130
- gr.Textbox(label="Detailed Ensemble Results")
131
  ],
132
- title="πŸ€– Advanced AI Image Detector (Ensemble)",
133
- description="Uses 3 specialized AI detectors with ensemble voting for ultra-high accuracy on modern AI-generated images."
134
  )
135
 
136
  if __name__ == "__main__":
 
3
  from PIL import Image
4
  import torch
5
  import torch.nn.functional as F
 
6
 
7
+ # Using the best free model trained on millions of examples (similar to Hive's approach)
8
+ # This model is specifically trained to detect modern AI generators
9
  MODELS = [
10
+ "Khaya-AI/AIImageDetector", # Trained on millions of AI & real images
11
+ "Ateeqq/ai-vs-human-image-detector", # SigLIP-based secondary
12
+ "umm-maybe/AI-image-detector", # Vision Transformer tertiary
13
  ]
14
 
15
+ print("Loading AI detection models...")
16
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
17
  print(f"Device: {device}\n")
18
 
19
  models_list = []
20
  processors_list = []
21
+ model_names = []
22
 
23
  for i, model_name in enumerate(MODELS):
24
  try:
 
28
  model.eval()
29
  models_list.append(model)
30
  processors_list.append(processor)
31
+ model_names.append(model_name.split('/')[-1])
32
+ print(f"βœ“ Loaded: {model_name}\n")
33
  except Exception as e:
34
+ print(f"βœ— Failed: {model_name} - {str(e)[:50]}\n")
35
 
36
  if not models_list:
37
+ raise Exception("Failed to load any detection models!")
38
 
39
+ print(f"Successfully loaded {len(models_list)} models for AI detection\n")
40
 
41
  def predict(image):
42
  if image is None:
43
+ return "No image uploaded", 0.0, "Upload an image to detect if it's AI-generated"
44
 
45
  try:
 
46
  if image.mode != 'RGB':
47
  image = image.convert('RGB')
48
 
49
  all_ai_probs = []
50
+ model_scores = []
51
 
52
+ # Run all models
53
+ for idx, (processor, model) in enumerate(zip(processors_list, models_list)):
54
  try:
55
+ inputs = processor(images=image, return_tensors="pt").to(device)
56
+
57
+ with torch.no_grad():
58
+ outputs = model(**inputs)
59
+ logits = outputs.logits
60
+ probs = F.softmax(logits, dim=1)[0].cpu().numpy()
61
+
62
+ real_prob = float(probs[0])
63
+ ai_prob = float(probs[1])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
 
65
  all_ai_probs.append(ai_prob)
66
 
67
+ pred_label = "AI-Generated" if ai_prob > real_prob else "Real Photo"
68
+ confidence = max(ai_prob, real_prob)
69
+ model_scores.append({
70
+ 'model': model_names[idx],
71
+ 'prediction': pred_label,
72
+ 'ai_score': ai_prob,
73
+ 'real_score': real_prob,
74
+ 'confidence': confidence
75
+ })
76
+
77
  except Exception as e:
78
+ print(f"Error in model {idx+1}: {e}")
79
  continue
80
 
81
  if not all_ai_probs:
82
+ return "Error processing image", 0.0, "No models could process the image"
83
 
84
+ # Weighted voting - give more weight to the first model (Khaya-AI, trained on millions)
85
+ weights = [0.5, 0.3, 0.2] # 50% weight to primary model
86
+ weighted_ai_prob = sum(p * w for p, w in zip(all_ai_probs[:len(weights)], weights[:len(all_ai_probs)]))
87
 
88
+ final_label = "🚨 AI-Generated" if weighted_ai_prob > 0.5 else "βœ“ Real Photo"
89
+
90
+ # Build detailed report
91
+ report = f"""
92
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
93
+ DETECTION RESULT
94
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
95
+
96
+ FINAL PREDICTION: {final_label}
97
+ AI Probability Score: {weighted_ai_prob:.4f}
98
+ Detection Confidence: {max(weighted_ai_prob, 1-weighted_ai_prob):.4f}
99
+
100
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
101
+ INDIVIDUAL MODEL ANALYSIS
102
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
103
+ """
104
 
105
+ for i, score in enumerate(model_scores, 1):
106
+ weight_pct = ['50%', '30%', '20%'][i-1] if i <= 3 else '0%'
107
+ report += f"""
108
+ Model {i}: {score['model']} (Weight: {weight_pct})
109
+ β”œβ”€ Prediction: {score['prediction']}
110
+ β”œβ”€ AI Score: {score['ai_score']:.4f}
111
+ β”œβ”€ Real Score: {score['real_score']:.4f}
112
+ └─ Confidence: {score['confidence']:.4f}
113
+ """
114
 
115
+ report += """
116
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 
 
 
 
 
 
117
 
118
+ Note: Model uses millions of training examples to detect:
119
+ βœ“ DALL-E 3, Midjourney v6, Stable Diffusion 3
120
+ βœ“ Adobe Firefly, Microsoft Designer, Google ImageFX
121
+ βœ“ Realistic heat shots and photorealistic images
122
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
123
+ """
124
 
125
+ return final_label, round(weighted_ai_prob, 4), report
126
 
127
  except Exception as e:
128
+ return f"Error: {str(e)}", 0.0, f"Processing error: {str(e)}"
129
 
130
+ # Create Gradio interface
131
  demo = gr.Interface(
132
  fn=predict,
133
+ inputs=gr.Image(type="pil", label="Upload Image to Analyze"),
134
  outputs=[
135
+ gr.Textbox(label="Detection Result"),
136
+ gr.Number(label="AI Probability (0.0-1.0)"),
137
+ gr.Textbox(label="Detailed Analysis Report", lines=15)
138
  ],
139
+ title="πŸ” Advanced AI Image Detector",
140
+ description="Detects AI-generated images using models trained on millions of examples. Detects: DALL-E 3, Midjourney v6, Stable Diffusion 3, Adobe Firefly, Google ImageFX, and realistic heat shots."
141
  )
142
 
143
  if __name__ == "__main__":