File size: 3,129 Bytes
e73e2a2
 
3a2cd79
e73e2a2
3a2cd79
e6fe7fe
3a2cd79
 
e73e2a2
e6fe7fe
e73e2a2
eaa1a24
e73e2a2
 
 
87d09d2
e73e2a2
 
 
3a2cd79
e73e2a2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87d09d2
e6fe7fe
 
e73e2a2
 
 
 
3a2cd79
e73e2a2
 
 
 
eaa1a24
e6fe7fe
 
e73e2a2
 
 
 
e6fe7fe
eb801fa
3a2cd79
e73e2a2
 
 
e6fe7fe
e73e2a2
 
 
 
3a2cd79
e73e2a2
 
 
 
3a2cd79
e73e2a2
 
 
3a2cd79
e73e2a2
 
3a2cd79
e73e2a2
3a2cd79
e73e2a2
3a2cd79
e73e2a2
 
 
 
 
3a2cd79
fac7f40
e73e2a2
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import os
import cv2
import numpy as np
import gradio as gr
import tensorflow as tf
from tensorflow.keras.models import load_model
from tensorflow.keras.applications.xception import preprocess_input as xcp_pre
from tensorflow.keras.applications.efficientnet import preprocess_input as eff_pre
from huggingface_hub import hf_hub_download
from mtcnn import MTCNN
import matplotlib.pyplot as plt

# Download models
xcp_path = hf_hub_download(repo_id="Zeyadd-Mostaffa/deepfake-image-detector", filename="xception_model.h5")
eff_path = hf_hub_download(repo_id="Zeyadd-Mostaffa/deepfake-image-detector", filename="efficientnet_model.h5")

# Load models
xcp_model = load_model(xcp_path)
eff_model = load_model(eff_path)

# Face detector
detector = MTCNN()

def extract_face(image):
    faces = detector.detect_faces(image)
    if not faces:
        return None
    x, y, w, h = faces[0]['box']
    x, y = max(0, x), max(0, y)
    return image[y:y+h, x:x+w]

def grad_cam(model, image, size, preprocess_fn):
    img = cv2.resize(image, size)
    input_tensor = preprocess_fn(img.astype(np.float32))[np.newaxis, ...]
    
    grad_model = tf.keras.models.Model(
        [model.inputs], [model.get_layer(index=-1).output, model.output]
    )

    with tf.GradientTape() as tape:
        conv_outputs, predictions = grad_model(input_tensor)
        loss = predictions[:, 0]  # Assuming binary classification

    grads = tape.gradient(loss, conv_outputs)[0]
    conv_outputs = conv_outputs[0]

    weights = tf.reduce_mean(grads, axis=(0, 1))
    cam = np.zeros(conv_outputs.shape[:2], dtype=np.float32)
    for i, w in enumerate(weights):
        cam += w * conv_outputs[:, :, i]

    cam = np.maximum(cam, 0)
    cam = cam / (cam.max() + 1e-8)
    heatmap = cv2.resize(cam, size)
    heatmap = np.uint8(255 * heatmap)
    heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
    superimposed_img = cv2.addWeighted(cv2.resize(img, size), 0.6, heatmap, 0.4, 0)
    return superimposed_img

def predict(image):
    face = extract_face(image)
    if face is None:
        return "No face detected", None

    # Xception
    xcp_img = cv2.resize(face, (299, 299))
    xcp_tensor = xcp_pre(xcp_img.astype(np.float32))[np.newaxis, ...]
    xcp_pred = xcp_model.predict(xcp_tensor)[0][0]

    # EfficientNet
    eff_img = cv2.resize(face, (224, 224))
    eff_tensor = eff_pre(eff_img.astype(np.float32))[np.newaxis, ...]
    eff_pred = eff_model.predict(eff_tensor)[0][0]

    # Ensemble average
    avg_pred = (xcp_pred + eff_pred) / 2
    label = "Fake" if avg_pred > 0.5 else "Real"

    # Grad-CAM on Xception
    cam_img = grad_cam(xcp_model, face, (299, 299), xcp_pre)

    return label, cam_img

interface = gr.Interface(
    fn=predict,
    inputs=gr.Image(type="numpy", label="image"),
    outputs=[
        gr.Label(label="Prediction"),
        gr.Image(type="numpy", label="Grad-CAM")
    ],
    title="Deepfake Image Detector (with Grad-CAM)",
    description="Upload an image. We detect the face, classify using an ensemble (Xception + EfficientNetB4), and explain the prediction using Grad-CAM on Xception."
)

interface.launch()