monster07 commited on
Commit
6d0cf13
Β·
verified Β·
1 Parent(s): bbe970a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -149
app.py CHANGED
@@ -1,130 +1,25 @@
 
1
  import gradio as gr
2
  import torch
3
- import torch.nn as nn
4
- import torchvision.transforms as transforms
5
- from PIL import Image
6
- import cv2
7
  import numpy as np
 
8
  import matplotlib.pyplot as plt
9
- import os
10
-
11
- # βœ… Xception Block Definition
12
- class SeparableConv2d(nn.Module):
13
- def __init__(self, in_channels, out_channels, kernel_size=1, stride=1, padding=0):
14
- super().__init__()
15
- self.depthwise = nn.Conv2d(in_channels, in_channels, kernel_size, stride, padding, groups=in_channels, bias=False)
16
- self.pointwise = nn.Conv2d(in_channels, out_channels, 1, 1, 0, bias=False)
17
- def forward(self, x):
18
- x = self.depthwise(x)
19
- x = self.pointwise(x)
20
- return x
21
-
22
- class Block(nn.Module):
23
- def __init__(self, in_filters, out_filters, reps, stride=1, start_with_relu=True, grow_first=True):
24
- super().__init__()
25
- layers = []
26
- filters = in_filters
27
- if grow_first:
28
- if start_with_relu:
29
- layers.append(nn.ReLU(inplace=True))
30
- layers.extend([
31
- SeparableConv2d(in_filters, out_filters, 3, 1, 1),
32
- nn.BatchNorm2d(out_filters)
33
- ])
34
- filters = out_filters
35
- for _ in range(reps - 1):
36
- layers.extend([
37
- nn.ReLU(inplace=True),
38
- SeparableConv2d(filters, filters, 3, 1, 1),
39
- nn.BatchNorm2d(filters)
40
- ])
41
- if not grow_first:
42
- layers.extend([
43
- nn.ReLU(inplace=True),
44
- SeparableConv2d(in_filters, out_filters, 3, 1, 1),
45
- nn.BatchNorm2d(out_filters)
46
- ])
47
- if stride != 1:
48
- layers.append(nn.MaxPool2d(3, stride, 1))
49
- self.block = nn.Sequential(*layers)
50
- self.skip = nn.Conv2d(in_filters, out_filters, 1, stride, bias=False)
51
- self.skipbn = nn.BatchNorm2d(out_filters)
52
- def forward(self, inp):
53
- x = self.block(inp)
54
- skip = self.skipbn(self.skip(inp))
55
- x += skip
56
- return x
57
-
58
- # βœ… Xception Architecture
59
- class Xception(nn.Module):
60
- def __init__(self, num_classes=1):
61
- super().__init__()
62
- self.conv1 = nn.Conv2d(3, 32, 3, 2, 0, bias=False)
63
- self.bn1 = nn.BatchNorm2d(32)
64
- self.relu = nn.ReLU(inplace=True)
65
- self.conv2 = nn.Conv2d(32, 64, 3, bias=False)
66
- self.bn2 = nn.BatchNorm2d(64)
67
- self.block1 = Block(64, 128, 2, 2, start_with_relu=False, grow_first=True)
68
- self.block2 = Block(128, 256, 2, 2, grow_first=True)
69
- self.block3 = Block(256, 728, 2, 2, grow_first=True)
70
- self.block4 = Block(728, 728, 3)
71
- self.block5 = Block(728, 728, 3)
72
- self.block6 = Block(728, 728, 3)
73
- self.block7 = Block(728, 728, 3)
74
- self.block8 = Block(728, 728, 3)
75
- self.block9 = Block(728, 728, 3)
76
- self.block10 = Block(728, 728, 3)
77
- self.block11 = Block(728, 728, 3)
78
- self.block12 = Block(728, 1024, 2, 2, grow_first=False)
79
- self.conv3 = SeparableConv2d(1024, 1536, 3, 1, 1)
80
- self.bn3 = nn.BatchNorm2d(1536)
81
- self.conv4 = SeparableConv2d(1536, 2048, 3, 1, 1)
82
- self.bn4 = nn.BatchNorm2d(2048)
83
- self.fc = nn.Linear(2048, num_classes)
84
- def features(self, input):
85
- x = self.relu(self.bn1(self.conv1(input)))
86
- x = self.relu(self.bn2(self.conv2(x)))
87
- x = self.block1(x)
88
- x = self.block2(x)
89
- x = self.block3(x)
90
- x = self.block4(x)
91
- x = self.block5(x)
92
- x = self.block6(x)
93
- x = self.block7(x)
94
- x = self.block8(x)
95
- x = self.block9(x)
96
- x = self.block10(x)
97
- x = self.block11(x)
98
- x = self.block12(x)
99
- x = self.relu(self.bn3(self.conv3(x)))
100
- x = self.relu(self.bn4(self.conv4(x)))
101
- return x
102
- def forward(self, input):
103
- x = self.features(input)
104
- x = nn.AdaptiveAvgPool2d((1, 1))(x)
105
- x = x.view(x.size(0), -1)
106
- x = self.fc(x)
107
- return x
108
-
109
- # βœ… Load weights
110
- model = Xception()
111
- model.load_state_dict(torch.hub.load_state_dict_from_url(
112
- "https://huggingface.co/Selimsef/xception-cnn-df/resolve/main/xception-binary-weights.pt",
113
- map_location="cpu"
114
- ))
115
  model.eval()
116
 
117
- # βœ… Transform
118
- transform = transforms.Compose([
119
- transforms.Resize((299, 299)),
120
- transforms.ToTensor(),
121
- transforms.Normalize([0.5]*3, [0.5]*3)
122
- ])
123
 
124
- # βœ… Analyze function
125
- def analyze_deepfake(video_path):
126
- if not video_path:
127
- return "❌ No video uploaded", None
128
 
129
  cap = cv2.VideoCapture(video_path)
130
  preds = []
@@ -136,51 +31,59 @@ def analyze_deepfake(video_path):
136
  if not ret or count >= max_frames:
137
  break
138
 
139
- h, w, _ = frame.shape
140
- y1 = int(h * 0.25)
141
- y2 = int(h * 0.75)
142
- x1 = int(w * 0.25)
143
- x2 = int(w * 0.75)
144
- crop = frame[y1:y2, x1:x2]
145
- image = cv2.cvtColor(crop, cv2.COLOR_BGR2RGB)
146
- image = Image.fromarray(image)
147
- input_tensor = transform(image).unsqueeze(0)
148
-
149
- with torch.no_grad():
150
- out = model(input_tensor)
151
- prob = torch.sigmoid(out)[0].item()
152
- preds.append(prob)
 
 
 
153
 
154
  count += 1
155
 
156
  cap.release()
157
 
158
  if not preds:
159
- return "❌ No frames analyzed", None
160
 
161
- avg = np.mean(preds)
162
- label = "**FAKE**" if avg > 0.5 else "**REAL**"
163
- result = f"🎯 Verdict: {label}\nConfidence: {avg:.2f}"
 
 
 
 
164
 
 
165
  fig, ax = plt.subplots()
166
- ax.hist(preds, bins=10, color="red" if avg > 0.5 else "green", edgecolor="black")
167
- ax.set_title("Confidence per Frame")
168
- ax.set_xlabel("Fake Probability")
169
  ax.set_ylabel("Frames")
170
  ax.grid(True)
171
 
172
  return result, fig
173
 
174
- # βœ… Gradio App
175
  with gr.Blocks() as demo:
176
- gr.Markdown("# 🎭 Deepfake Detector with Xception (DFDC)")
177
- gr.Markdown("Upload a `.mp4` video. The app will classify it as REAL or FAKE based on pretrained deepfake model.")
178
 
179
- video = gr.Video(label="Upload Video")
180
- output_text = gr.Markdown()
181
- output_plot = gr.Plot()
182
- analyze = gr.Button("πŸ” Analyze")
183
 
184
- analyze.click(fn=analyze_deepfake, inputs=video, outputs=[output_text, output_plot])
185
 
186
  demo.queue().launch()
 
1
+
2
  import gradio as gr
3
  import torch
 
 
 
 
4
  import numpy as np
5
+ import cv2
6
  import matplotlib.pyplot as plt
7
+ from PIL import Image
8
+ from transformers import AutoImageProcessor, SiglipForImageClassification
9
+
10
+ # βœ… Load model from Hugging Face (no manual files)
11
+ model_name = "prithivMLmods/deepfake-detector-model-v1"
12
+ processor = AutoImageProcessor.from_pretrained(model_name)
13
+ model = SiglipForImageClassification.from_pretrained(model_name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  model.eval()
15
 
16
+ # βœ… Haar cascade for face detection
17
+ face_detector = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
 
 
 
 
18
 
19
+ # βœ… Deepfake analysis logic
20
+ def detect_deepfake(video_path):
21
+ if video_path is None:
22
+ return "❌ Please upload a valid .mp4 video", None
23
 
24
  cap = cv2.VideoCapture(video_path)
25
  preds = []
 
31
  if not ret or count >= max_frames:
32
  break
33
 
34
+ gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
35
+ faces = face_detector.detectMultiScale(gray, 1.1, 4)
36
+
37
+ if len(faces) > 0:
38
+ x, y, w, h = faces[0] # Take first detected face
39
+ face = frame[y:y+h, x:x+w]
40
+ if face.size == 0:
41
+ continue
42
+
43
+ face_rgb = cv2.cvtColor(face, cv2.COLOR_BGR2RGB)
44
+ pil_img = Image.fromarray(face_rgb)
45
+ inputs = processor(images=pil_img, return_tensors="pt")
46
+
47
+ with torch.no_grad():
48
+ logits = model(**inputs).logits
49
+ prob = torch.softmax(logits, dim=-1)[0][1].item()
50
+ preds.append(prob)
51
 
52
  count += 1
53
 
54
  cap.release()
55
 
56
  if not preds:
57
+ return "❌ No faces detected. Try a clearer video.", None
58
 
59
+ avg_conf = np.mean(preds)
60
+ label = "**FAKE**" if avg_conf > 0.5 else "**REAL**"
61
+ result = f"""
62
+ 🎯 **Result:** {label}
63
+ πŸ”’ Avg Confidence: {avg_conf:.2f}
64
+ πŸ“Š Frames Analyzed: {len(preds)}
65
+ """
66
 
67
+ # βœ… Create histogram
68
  fig, ax = plt.subplots()
69
+ ax.hist(preds, bins=10, color="red" if avg_conf > 0.5 else "green", edgecolor="black")
70
+ ax.set_title("Fake Confidence per Frame")
71
+ ax.set_xlabel("Fake Probability (0 = Real, 1 = Fake)")
72
  ax.set_ylabel("Frames")
73
  ax.grid(True)
74
 
75
  return result, fig
76
 
77
+ # βœ… Gradio interface
78
  with gr.Blocks() as demo:
79
+ gr.Markdown("## 🎭 Deepfake Detector (Transformer-based)")
80
+ gr.Markdown("Upload a short `.mp4` video. The app will detect faces and classify the video as **REAL** or **FAKE**.")
81
 
82
+ video_input = gr.Video(label="πŸ“€ Upload your video")
83
+ result_output = gr.Markdown()
84
+ graph_output = gr.Plot()
85
+ analyze_button = gr.Button("πŸ” Analyze")
86
 
87
+ analyze_button.click(fn=detect_deepfake, inputs=video_input, outputs=[result_output, graph_output])
88
 
89
  demo.queue().launch()