Zeyadd-Mostaffa commited on
Commit
e73e2a2
·
verified ·
1 Parent(s): f979a38

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +67 -55
app.py CHANGED
@@ -1,83 +1,95 @@
1
- import gradio as gr
 
2
  import numpy as np
 
3
  import tensorflow as tf
4
- import cv2
5
  from tensorflow.keras.models import load_model
6
  from tensorflow.keras.applications.xception import preprocess_input as xcp_pre
7
  from tensorflow.keras.applications.efficientnet import preprocess_input as eff_pre
 
8
  from mtcnn import MTCNN
9
- import os
10
- import warnings
11
- warnings.filterwarnings("ignore")
12
 
13
- # Force TF to suppress log-level warnings
14
- os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
 
15
 
16
- # Load models from local (downloaded from HF first in app setup)
17
- xcp_model = load_model("xception_model.h5")
18
- eff_model = load_model("efficientnet_model.h5")
19
 
20
- # Grad-CAM for Xception
21
- def grad_cam(model, img_array, size, preprocess_fn):
22
- img = cv2.resize(img_array, size)
23
- input_tensor = preprocess_fn(np.expand_dims(img, axis=0).astype(np.float32))
24
- input_tensor = tf.convert_to_tensor(input_tensor)
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
  with tf.GradientTape() as tape:
27
- conv_layer = model.get_layer(index=-5).output
28
- grad_model = tf.keras.models.Model([model.inputs], [conv_layer, model.output])
29
  conv_outputs, predictions = grad_model(input_tensor)
30
- loss = predictions[:, 0]
 
 
 
31
 
32
- grads = tape.gradient(loss, conv_outputs)
33
- pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
34
- cam = tf.reduce_sum(tf.multiply(pooled_grads, conv_outputs), axis=-1).numpy()[0]
 
35
 
36
  cam = np.maximum(cam, 0)
37
  cam = cam / (cam.max() + 1e-8)
38
- cam = (cam * 255).astype(np.uint8)
39
- cam = cam.numpy() if hasattr(cam, 'numpy') else cam
40
- cam = cv2.resize(cam, size)
41
- heatmap = cv2.applyColorMap(cam, cv2.COLORMAP_JET)
42
- superimposed_img = cv2.addWeighted(cv2.cvtColor(img, cv2.COLOR_RGB2BGR), 0.6, heatmap, 0.4, 0)
43
  return superimposed_img
44
 
45
- # Face detector
46
- detector = MTCNN()
47
-
48
- def detect_face(image):
49
- faces = detector.detect_faces(image)
50
- if not faces:
51
- raise ValueError("No face detected.")
52
- x, y, w, h = faces[0]['box']
53
- return image[y:y+h, x:x+w]
54
-
55
  def predict(image):
56
- try:
57
- face = detect_face(image)
58
-
59
- xcp_img = cv2.resize(face, (299, 299))
60
- eff_img = cv2.resize(face, (224, 224))
61
 
62
- xcp_input = np.expand_dims(xcp_pre(xcp_img.astype(np.float32)), axis=0)
63
- eff_input = np.expand_dims(eff_pre(eff_img.astype(np.float32)), axis=0)
 
 
64
 
65
- xcp_pred = xcp_model.predict(xcp_input)[0][0]
66
- eff_pred = eff_model.predict(eff_input)[0][0]
 
 
67
 
68
- ensemble_pred = (xcp_pred + eff_pred) / 2
69
- label = "Fake" if ensemble_pred > 0.5 else "Real"
 
70
 
71
- cam_img = grad_cam(xcp_model, face, (299, 299), xcp_pre)
 
72
 
73
- return label, cam_img
74
- except Exception as e:
75
- return "خطأ", "خطأ"
76
 
77
- gr.Interface(
78
  fn=predict,
79
- inputs=gr.Image(type="numpy", label="Upload Face Image"),
80
- outputs=[gr.Label(label="Prediction"), gr.Image(label="Grad-CAM Explanation")],
 
 
 
81
  title="Deepfake Image Detector (with Grad-CAM)",
82
  description="Upload an image. We detect the face, classify using an ensemble (Xception + EfficientNetB4), and explain the prediction using Grad-CAM on Xception."
83
- ).launch()
 
 
 
1
+ import os
2
+ import cv2
3
  import numpy as np
4
+ import gradio as gr
5
  import tensorflow as tf
 
6
  from tensorflow.keras.models import load_model
7
  from tensorflow.keras.applications.xception import preprocess_input as xcp_pre
8
  from tensorflow.keras.applications.efficientnet import preprocess_input as eff_pre
9
+ from huggingface_hub import hf_hub_download
10
  from mtcnn import MTCNN
11
+ import matplotlib.pyplot as plt
 
 
12
 
13
+ # Download models
14
+ xcp_path = hf_hub_download(repo_id="Zeyadd-Mostaffa/deepfake-image-detector", filename="xception_model.h5")
15
+ eff_path = hf_hub_download(repo_id="Zeyadd-Mostaffa/deepfake-image-detector", filename="efficientnet_model.h5")
16
 
17
+ # Load models
18
+ xcp_model = load_model(xcp_path)
19
+ eff_model = load_model(eff_path)
20
 
21
+ # Face detector
22
+ detector = MTCNN()
23
+
24
+ def extract_face(image):
25
+ faces = detector.detect_faces(image)
26
+ if not faces:
27
+ return None
28
+ x, y, w, h = faces[0]['box']
29
+ x, y = max(0, x), max(0, y)
30
+ return image[y:y+h, x:x+w]
31
+
32
+ def grad_cam(model, image, size, preprocess_fn):
33
+ img = cv2.resize(image, size)
34
+ input_tensor = preprocess_fn(img.astype(np.float32))[np.newaxis, ...]
35
+
36
+ grad_model = tf.keras.models.Model(
37
+ [model.inputs], [model.get_layer(index=-1).output, model.output]
38
+ )
39
 
40
  with tf.GradientTape() as tape:
 
 
41
  conv_outputs, predictions = grad_model(input_tensor)
42
+ loss = predictions[:, 0] # Assuming binary classification
43
+
44
+ grads = tape.gradient(loss, conv_outputs)[0]
45
+ conv_outputs = conv_outputs[0]
46
 
47
+ weights = tf.reduce_mean(grads, axis=(0, 1))
48
+ cam = np.zeros(conv_outputs.shape[:2], dtype=np.float32)
49
+ for i, w in enumerate(weights):
50
+ cam += w * conv_outputs[:, :, i]
51
 
52
  cam = np.maximum(cam, 0)
53
  cam = cam / (cam.max() + 1e-8)
54
+ heatmap = cv2.resize(cam, size)
55
+ heatmap = np.uint8(255 * heatmap)
56
+ heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
57
+ superimposed_img = cv2.addWeighted(cv2.resize(img, size), 0.6, heatmap, 0.4, 0)
 
58
  return superimposed_img
59
 
 
 
 
 
 
 
 
 
 
 
60
  def predict(image):
61
+ face = extract_face(image)
62
+ if face is None:
63
+ return "No face detected", None
 
 
64
 
65
+ # Xception
66
+ xcp_img = cv2.resize(face, (299, 299))
67
+ xcp_tensor = xcp_pre(xcp_img.astype(np.float32))[np.newaxis, ...]
68
+ xcp_pred = xcp_model.predict(xcp_tensor)[0][0]
69
 
70
+ # EfficientNet
71
+ eff_img = cv2.resize(face, (224, 224))
72
+ eff_tensor = eff_pre(eff_img.astype(np.float32))[np.newaxis, ...]
73
+ eff_pred = eff_model.predict(eff_tensor)[0][0]
74
 
75
+ # Ensemble average
76
+ avg_pred = (xcp_pred + eff_pred) / 2
77
+ label = "Fake" if avg_pred > 0.5 else "Real"
78
 
79
+ # Grad-CAM on Xception
80
+ cam_img = grad_cam(xcp_model, face, (299, 299), xcp_pre)
81
 
82
+ return label, cam_img
 
 
83
 
84
+ interface = gr.Interface(
85
  fn=predict,
86
+ inputs=gr.Image(type="numpy", label="image"),
87
+ outputs=[
88
+ gr.Label(label="Prediction"),
89
+ gr.Image(type="numpy", label="Grad-CAM")
90
+ ],
91
  title="Deepfake Image Detector (with Grad-CAM)",
92
  description="Upload an image. We detect the face, classify using an ensemble (Xception + EfficientNetB4), and explain the prediction using Grad-CAM on Xception."
93
+ )
94
+
95
+ interface.launch()