neuralninja10 commited on
Commit
1ba1e08
·
verified ·
1 Parent(s): b696953

Main application file

Browse files
Files changed (1) hide show
  1. app.py +183 -0
app.py ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ import requests
4
+ import streamlit as st
5
+ import torch
6
+ from PIL import Image
7
+ from torchvision import transforms
8
+ from torchvision.transforms import InterpolationMode
9
+
10
+ # ============================================================
11
+ # Configuration
12
+ # ============================================================
13
+
14
+ MODEL_URL = (
15
+ "https://huggingface.co/neuralninja10/deepFakeWithCBAM/"
16
+ "resolve/main/deepFakeWithCBAM.pt"
17
+ )
18
+
19
+ MODEL_PATH = "deepFakeWithCBAM.pt"
20
+ THRESHOLD = 0.68
21
+ DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
22
+
23
+ # ============================================================
24
+ # Page Config
25
+ # ============================================================
26
+
27
+ st.set_page_config(
28
+ page_title="DeepFake Detection Demo",
29
+ page_icon="🧠",
30
+ layout="centered",
31
+ )
32
+
33
+ # ============================================================
34
+ # Secure Model Loader
35
+ # ============================================================
36
+
37
+ @st.cache_resource(show_spinner=False)
38
+ def load_model():
39
+ token = os.environ.get("HF_TOKEN")
40
+ if token is None:
41
+ raise RuntimeError("HF_TOKEN is not set in Space secrets")
42
+
43
+ headers = {"Authorization": f"Bearer {token}"}
44
+
45
+ if not os.path.exists(MODEL_PATH):
46
+ with st.spinner("Initializing deepfake detection model..."):
47
+ response = requests.get(
48
+ MODEL_URL,
49
+ headers=headers,
50
+ stream=True,
51
+ timeout=60,
52
+ )
53
+ response.raise_for_status()
54
+ with open(MODEL_PATH, "wb") as f:
55
+ for chunk in response.iter_content(chunk_size=8192):
56
+ f.write(chunk)
57
+
58
+ model = torch.jit.load(MODEL_PATH, map_location=DEVICE)
59
+ model.eval()
60
+ return model
61
+
62
+ # ============================================================
63
+ # Preprocessing
64
+ # ============================================================
65
+
66
+ _transform = transforms.Compose([
67
+ transforms.Resize((256, 256), interpolation=InterpolationMode.BILINEAR),
68
+ transforms.ToTensor(),
69
+ transforms.Normalize(
70
+ mean=[0.485, 0.456, 0.406],
71
+ std=[0.229, 0.224, 0.225],
72
+ ),
73
+ ])
74
+
75
+ def preprocess_image(image: Image.Image) -> torch.Tensor:
76
+ return _transform(image).unsqueeze(0)
77
+
78
+ # ============================================================
79
+ # Inference
80
+ # ============================================================
81
+
82
+ def run_inference(model, image: Image.Image):
83
+ tensor = preprocess_image(image).to(DEVICE)
84
+
85
+ start = time.time()
86
+ with torch.no_grad():
87
+ logits = model(tensor)
88
+ prob = torch.sigmoid(logits).item()
89
+ latency_ms = (time.time() - start) * 1000
90
+
91
+ is_real = prob > THRESHOLD
92
+ confidence = prob if is_real else (1 - prob)
93
+
94
+ return {
95
+ "prediction": "Real" if is_real else "Fake",
96
+ "confidence": confidence,
97
+ "real_prob": prob,
98
+ "fake_prob": 1 - prob,
99
+ "latency_ms": latency_ms,
100
+ }
101
+
102
+ # ============================================================
103
+ # UI
104
+ # ============================================================
105
+
106
+ def main():
107
+ st.title("🧠 DeepFake Detection")
108
+ st.markdown(
109
+ """
110
+ Upload a facial image to determine whether it is **Real** or **AI-Generated**.
111
+ This demo runs entirely on **CPU** using a TorchScript model.
112
+ """
113
+ )
114
+
115
+ try:
116
+ model = load_model()
117
+ except Exception as e:
118
+ st.error("❌ Failed to load the model.")
119
+ st.exception(e)
120
+ return
121
+
122
+ uploaded_file = st.file_uploader(
123
+ "Upload an image (JPG / PNG)",
124
+ type=["jpg", "jpeg", "png"],
125
+ accept_multiple_files=False,
126
+ )
127
+
128
+ if uploaded_file:
129
+ image = Image.open(uploaded_file).convert("RGB")
130
+ st.image(image, caption="Uploaded Image", use_container_width=True)
131
+
132
+ if st.button("Run DeepFake Detection"):
133
+ with st.spinner("Running inference..."):
134
+ result = run_inference(model, image)
135
+
136
+ st.divider()
137
+ st.subheader("Detection Result")
138
+
139
+ if result["prediction"] == "Real":
140
+ st.success("✅ Real Face Detected")
141
+ else:
142
+ st.error("❌ Deepfake Detected")
143
+
144
+ st.metric(
145
+ label="Confidence Score",
146
+ value=f"{result['confidence']:.2%}",
147
+ )
148
+
149
+ st.caption(
150
+ f"Inference latency: {result['latency_ms']:.1f} ms (CPU)"
151
+ )
152
+
153
+ with st.expander("Detailed Probabilities"):
154
+ st.write(f"Real Probability: {result['real_prob']:.4f}")
155
+ st.write(f"Fake Probability: {result['fake_prob']:.4f}")
156
+
157
+ st.divider()
158
+
159
+ st.caption(
160
+ """
161
+ ⚠️ **Disclaimer**
162
+ This system is provided for research and demonstration purposes only.
163
+ Predictions may be incorrect and should not be used as the sole basis
164
+ for real-world decisions.
165
+ """
166
+ )
167
+
168
+ with st.expander("Model Information"):
169
+ st.markdown(
170
+ """
171
+ - **Architecture:** EfficientNet + CBAM
172
+ - **Input Resolution:** 256×256
173
+ - **Runtime:** CPU (TorchScript)
174
+ - **Threshold:** 0.68
175
+ - **Known Limitations:**
176
+ - Heavy compression artifacts
177
+ - Extreme lighting conditions
178
+ - Occluded or profile faces
179
+ """
180
+ )
181
+
182
+ if __name__ == "__main__":
183
+ main()