Satwickchikkala1 commited on
Commit
be59fd9
Β·
verified Β·
1 Parent(s): 566351c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +49 -63
app.py CHANGED
@@ -6,57 +6,50 @@ from PIL import Image
6
  import cv2
7
  import traceback
8
 
9
- # ==============================================================================
10
- # --- Load the trained model ---
11
- # ==============================================================================
12
  try:
13
- model = tf.keras.models.load_model("./deepfake_mobilenet_model.h5")
14
  except Exception as e:
15
  print(f"Error loading model. Make sure the path is correct. Error: {e}")
16
- # Fallback: create dummy model (won't produce Grad-CAM)
17
  inputs = tf.keras.Input(shape=(224, 224, 3))
18
- outputs = tf.keras.layers.Dense(1, activation="sigmoid")(
19
- tf.keras.layers.GlobalAveragePooling2D()(inputs)
20
- )
21
  model = tf.keras.Model(inputs, outputs)
22
 
23
- # ==============================================================================
24
- # --- Grad-CAM Heatmap Generation Functions ---
25
- # ==============================================================================
 
26
  def get_last_conv_layer_name(model):
27
  for layer in reversed(model.layers):
28
- if len(layer.output.shape) == 4: # conv layer has 4D output
29
- print(f"Using conv layer for Grad-CAM: {layer.name}")
30
  return layer.name
31
- print("No convolutional layer found; Grad-CAM will be disabled.")
32
- return None
33
-
34
 
35
  def make_gradcam_heatmap(img_array, model, last_conv_layer_name):
36
- if last_conv_layer_name is None:
37
- return None
38
  grad_model = tf.keras.models.Model(
39
  model.inputs, [model.get_layer(last_conv_layer_name).output, model.output]
40
  )
 
41
  with tf.GradientTape() as tape:
42
- last_conv_layer_output, preds = grad_model([img_array])
43
- # Robustly extract scalar
44
- if len(preds.shape) == 2:
45
- class_channel = preds[:, 0]
46
- else:
47
- class_channel = preds
48
- grads = tape.gradient(class_channel, last_conv_layer_output)
49
  pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
50
- last_conv_layer_output = last_conv_layer_output[0]
51
- heatmap = last_conv_layer_output @ pooled_grads[..., tf.newaxis]
52
  heatmap = tf.squeeze(heatmap)
53
  heatmap = tf.maximum(heatmap, 0) / (tf.math.reduce_max(heatmap) + 1e-8)
54
  return heatmap.numpy()
55
 
56
-
57
  def superimpose_gradcam(original_img_pil, heatmap):
58
- if heatmap is None:
59
- return None
60
  original_img = np.array(original_img_pil)
61
  heatmap = cv2.resize(heatmap, (original_img.shape[1], original_img.shape[0]))
62
  heatmap = np.uint8(255 * heatmap)
@@ -64,69 +57,62 @@ def superimpose_gradcam(original_img_pil, heatmap):
64
  superimposed_img = cv2.addWeighted(original_img, 0.6, heatmap, 0.4, 0)
65
  return Image.fromarray(superimposed_img)
66
 
 
 
 
67
 
68
  last_conv_layer_name = get_last_conv_layer_name(model)
69
 
70
- # ==============================================================================
71
- # --- Main Prediction Function ---
72
- # ==============================================================================
73
  def predict_and_visualize(img):
74
  try:
75
- # --- Preprocess Image ---
76
  img_resized = img.resize((224, 224))
77
  img_array = image.img_to_array(img_resized) / 255.0
78
- img_array_expanded = np.expand_dims(img_array, axis=0)
79
-
80
- # --- Model Prediction ---
81
- prediction = model.predict(img_array_expanded, verbose=0)
82
 
83
- # Convert prediction to scalar safely
 
 
 
84
  if isinstance(prediction, (list, tuple)):
85
- prediction = prediction[0]
86
- prediction = np.array(prediction)
87
- if prediction.ndim > 0:
88
- prediction = prediction.item()
89
 
90
- # Confidence bars
91
  real_conf = float(prediction)
92
  fake_conf = float(1 - prediction)
93
  labels = {"Real Image": real_conf, "Fake Image": fake_conf}
94
 
95
- # --- Grad-CAM Overlay ---
96
- heatmap = make_gradcam_heatmap(img_array_expanded, model, last_conv_layer_name)
97
- superimposed_image = superimpose_gradcam(img, heatmap)
98
 
99
- return labels, superimposed_image
100
 
101
  except Exception as e:
102
- print("--- GRADIO APP ERROR ---")
103
  traceback.print_exc()
104
- print("------------------------")
105
- error_msg = f"Error: {e}"
106
- return {error_msg: 0.0}, None
107
-
108
 
109
- # ==============================================================================
110
  # --- Gradio Interface ---
111
- # ==============================================================================
 
112
  gr.Interface(
113
  fn=predict_and_visualize,
114
  inputs=gr.Image(type="pil", label="πŸ“· Upload a Face Image"),
115
  outputs=[
116
  gr.Label(num_top_classes=2, label="🧠 Model Prediction"),
117
- gr.Image(label="πŸ”₯ Grad-CAM Heatmap Overlay (if available)")
118
  ],
119
- title="✨ Deepfake Image Detector with Visual Explanation ✨",
120
  description="""
121
- **Detect whether an uploaded image is Real or AI-Generated (Deepfake).**
122
- Confidence bars show certainty for **Real** and **Fake** categories.
123
-
124
- The **Grad-CAM heatmap** highlights regions the model focused on (red = most important).
125
 
126
  ⚑ **Instructions:**
127
  1. Upload a face image (JPEG/PNG).
128
- 2. Wait a few seconds for prediction and heatmap.
129
- 3. Observe the confidence bars and Grad-CAM overlay (if available).
130
  """,
131
  theme="default"
132
  ).launch()
 
6
  import cv2
7
  import traceback
8
 
9
+ # =========================
10
+ # --- Load the model ---
11
+ # =========================
12
  try:
13
+ model = tf.keras.models.load_model("./model/deepfake_mobilenet_model.h5")
14
  except Exception as e:
15
  print(f"Error loading model. Make sure the path is correct. Error: {e}")
16
+ # Fallback dummy model
17
  inputs = tf.keras.Input(shape=(224, 224, 3))
18
+ x = tf.keras.layers.GlobalAveragePooling2D()(inputs)
19
+ outputs = tf.keras.layers.Dense(1, activation="sigmoid")(x)
 
20
  model = tf.keras.Model(inputs, outputs)
21
 
22
+ # =========================
23
+ # --- Grad-CAM helpers ---
24
+ # =========================
25
+
26
  def get_last_conv_layer_name(model):
27
  for layer in reversed(model.layers):
28
+ if hasattr(layer.output, "shape") and len(layer.output.shape) == 4:
 
29
  return layer.name
30
+ raise ValueError("No convolutional layer found in model.")
 
 
31
 
32
  def make_gradcam_heatmap(img_array, model, last_conv_layer_name):
 
 
33
  grad_model = tf.keras.models.Model(
34
  model.inputs, [model.get_layer(last_conv_layer_name).output, model.output]
35
  )
36
+
37
  with tf.GradientTape() as tape:
38
+ last_conv_output, preds = grad_model(img_array)
39
+
40
+ # βœ… Robustly handle list/tensor output
41
+ preds = preds[0] if isinstance(preds, (list, tuple)) else preds
42
+ class_channel = preds[:, 0] if len(preds.shape) > 1 else preds
43
+
44
+ grads = tape.gradient(class_channel, last_conv_output)
45
  pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
46
+ last_conv_output = last_conv_output[0]
47
+ heatmap = last_conv_output @ pooled_grads[..., tf.newaxis]
48
  heatmap = tf.squeeze(heatmap)
49
  heatmap = tf.maximum(heatmap, 0) / (tf.math.reduce_max(heatmap) + 1e-8)
50
  return heatmap.numpy()
51
 
 
52
  def superimpose_gradcam(original_img_pil, heatmap):
 
 
53
  original_img = np.array(original_img_pil)
54
  heatmap = cv2.resize(heatmap, (original_img.shape[1], original_img.shape[0]))
55
  heatmap = np.uint8(255 * heatmap)
 
57
  superimposed_img = cv2.addWeighted(original_img, 0.6, heatmap, 0.4, 0)
58
  return Image.fromarray(superimposed_img)
59
 
60
+ # =========================
61
+ # --- Main prediction ---
62
+ # =========================
63
 
64
  last_conv_layer_name = get_last_conv_layer_name(model)
65
 
 
 
 
66
  def predict_and_visualize(img):
67
  try:
 
68
  img_resized = img.resize((224, 224))
69
  img_array = image.img_to_array(img_resized) / 255.0
70
+ img_array_exp = np.expand_dims(img_array, axis=0)
 
 
 
71
 
72
+ # --- Model prediction ---
73
+ prediction = model.predict(img_array_exp, verbose=0)
74
+
75
+ # βœ… Ensure scalar prediction
76
  if isinstance(prediction, (list, tuple)):
77
+ prediction = np.array(prediction[0])
78
+ prediction = prediction.item() if isinstance(prediction, np.ndarray) else float(prediction)
 
 
79
 
 
80
  real_conf = float(prediction)
81
  fake_conf = float(1 - prediction)
82
  labels = {"Real Image": real_conf, "Fake Image": fake_conf}
83
 
84
+ # --- Grad-CAM ---
85
+ heatmap = make_gradcam_heatmap(img_array_exp, model, last_conv_layer_name)
86
+ superimposed_img = superimpose_gradcam(img, heatmap)
87
 
88
+ return labels, superimposed_img
89
 
90
  except Exception as e:
91
+ print("--- ERROR ---")
92
  traceback.print_exc()
93
+ return {"Error": 0.0}, None
 
 
 
94
 
95
+ # =========================
96
  # --- Gradio Interface ---
97
+ # =========================
98
+
99
  gr.Interface(
100
  fn=predict_and_visualize,
101
  inputs=gr.Image(type="pil", label="πŸ“· Upload a Face Image"),
102
  outputs=[
103
  gr.Label(num_top_classes=2, label="🧠 Model Prediction"),
104
+ gr.Image(label="πŸ”₯ Grad-CAM Heatmap Overlay")
105
  ],
106
+ title="✨ Deepfake Image Detector with Grad-CAM ✨",
107
  description="""
108
+ **Detect Real vs AI-Generated (Deepfake) Images.**
109
+ The confidence bars show the model's certainty for **Real** and **Fake**.
110
+ The Grad-CAM heatmap highlights areas most important to the model (red = most important).
 
111
 
112
  ⚑ **Instructions:**
113
  1. Upload a face image (JPEG/PNG).
114
+ 2. Wait a few seconds for prediction & heatmap.
115
+ 3. Observe confidence bars and Grad-CAM overlay.
116
  """,
117
  theme="default"
118
  ).launch()