anky2002 commited on
Commit
bd3a66b
Β·
verified Β·
1 Parent(s): 7690770

Upload agents/model_agent.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. agents/model_agent.py +108 -2
agents/model_agent.py CHANGED
@@ -213,13 +213,119 @@ def analyze_model_fingerprint(img: Image.Image) -> Dict[str, Any]:
213
  }
214
 
215
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  # ─── Main Agent Entry Point ─────────────────────────────────────────
217
  def run_model_agent(img: Image.Image) -> AgentEvidence:
218
  """Run all generative model detection tests."""
219
  findings = []
220
  scores = []
221
 
222
- for fn in [analyze_frequency_grid, analyze_diffusion_residuals, analyze_model_fingerprint]:
 
223
  try:
224
  result = fn(img)
225
  findings.append(result)
@@ -248,7 +354,7 @@ def run_model_agent(img: Image.Image) -> AgentEvidence:
248
  agent_name="Generative Model Agent",
249
  violation_score=np.clip(avg_score, -1, 1),
250
  confidence=confidence,
251
- failure_prob=max(0.0, 1.0 - len(scores) / 3),
252
  rationale=rationale,
253
  sub_findings=findings,
254
  )
 
213
  }
214
 
215
 
216
+ # ─── GAN Upsampling Checkerboard ─────────────────────────────────────
217
+ def analyze_upsampling_checkerboard(img: Image.Image) -> Dict[str, Any]:
218
+ """
219
+ Transposed convolutions in GANs create checkerboard patterns.
220
+ Detected via pixel-level autocorrelation at lag=2.
221
+ """
222
+ gray = np.array(img.convert("L")).astype(np.float64)
223
+ h, w = gray.shape
224
+
225
+ # Compute autocorrelation at lag 2 (checkerboard period)
226
+ if h < 10 or w < 10:
227
+ return {"test": "Upsampling Checkerboard", "score": 0.0, "note": "Image too small"}
228
+
229
+ # Horizontal lag-2 autocorrelation
230
+ h_auto = float(np.corrcoef(gray[:, :-2].ravel(), gray[:, 2:].ravel())[0, 1])
231
+ # Vertical lag-2
232
+ v_auto = float(np.corrcoef(gray[:-2, :].ravel(), gray[2:, :].ravel())[0, 1])
233
+
234
+ # Compare lag-1 vs lag-2 (checkerboard: lag-2 > lag-1)
235
+ h_auto1 = float(np.corrcoef(gray[:, :-1].ravel(), gray[:, 1:].ravel())[0, 1])
236
+ v_auto1 = float(np.corrcoef(gray[:-1, :].ravel(), gray[1:, :].ravel())[0, 1])
237
+
238
+ # Checkerboard signature: lag-2 corr noticeably higher than lag-1
239
+ h_checker = h_auto - h_auto1
240
+ v_checker = v_auto - v_auto1
241
+ checker_score = (h_checker + v_checker) / 2
242
+
243
+ if checker_score > 0.02:
244
+ score = 0.5
245
+ note = f"Checkerboard pattern detected (Ξ”corr={checker_score:.4f}, GAN upsampling artifact)"
246
+ elif checker_score > 0.005:
247
+ score = 0.2
248
+ note = f"Mild checkerboard tendency (Ξ”corr={checker_score:.4f})"
249
+ else:
250
+ score = -0.1
251
+ note = f"No checkerboard pattern (Ξ”corr={checker_score:.4f})"
252
+
253
+ return {
254
+ "test": "Upsampling Checkerboard",
255
+ "checker_delta": round(checker_score, 6),
256
+ "h_lag2": round(h_auto, 4),
257
+ "v_lag2": round(v_auto, 4),
258
+ "score": score,
259
+ "note": note,
260
+ }
261
+
262
+
263
+ # ─── VAE Boundary Artifacts ─────────────────────────────────────────
264
+ def analyze_vae_boundaries(img: Image.Image) -> Dict[str, Any]:
265
+ """
266
+ VAE-based generators (Stable Diffusion) process in latent patches.
267
+ This can create subtle boundary artifacts at 64x64 or 32x32 grid.
268
+ """
269
+ gray = np.array(img.convert("L")).astype(np.float64)
270
+ h, w = gray.shape
271
+
272
+ # Check for grid artifacts at common VAE patch sizes
273
+ best_score = 0.0
274
+ best_size = 0
275
+ best_ratio = 1.0
276
+
277
+ for patch_size in [32, 64, 128]:
278
+ if h < patch_size * 2 or w < patch_size * 2:
279
+ continue
280
+
281
+ h_crop = (h // patch_size) * patch_size
282
+ w_crop = (w // patch_size) * patch_size
283
+ g = gray[:h_crop, :w_crop]
284
+
285
+ # Measure intensity discontinuity at patch boundaries
286
+ boundary_diffs = []
287
+ interior_diffs = []
288
+
289
+ for i in range(1, h_crop):
290
+ row_diff = np.abs(g[i, :] - g[i - 1, :])
291
+ if i % patch_size == 0:
292
+ boundary_diffs.append(float(np.mean(row_diff)))
293
+ elif i % patch_size != 1:
294
+ interior_diffs.append(float(np.mean(row_diff)))
295
+
296
+ if boundary_diffs and interior_diffs:
297
+ ratio = float(np.mean(boundary_diffs)) / (float(np.mean(interior_diffs)) + 1e-9)
298
+ if ratio > best_ratio:
299
+ best_ratio = ratio
300
+ best_size = patch_size
301
+
302
+ if best_ratio > 1.3:
303
+ score = 0.4
304
+ note = f"VAE boundary artifacts at {best_size}px grid (ratio={best_ratio:.3f})"
305
+ elif best_ratio > 1.1:
306
+ score = 0.2
307
+ note = f"Weak boundary artifacts at {best_size}px (ratio={best_ratio:.3f})"
308
+ else:
309
+ score = -0.1
310
+ note = f"No VAE boundary artifacts (max ratio={best_ratio:.3f})"
311
+
312
+ return {
313
+ "test": "VAE Boundary Artifacts",
314
+ "best_boundary_ratio": round(best_ratio, 4),
315
+ "best_patch_size": best_size,
316
+ "score": score,
317
+ "note": note,
318
+ }
319
+
320
+
321
  # ─── Main Agent Entry Point ─────────────────────────────────────────
322
  def run_model_agent(img: Image.Image) -> AgentEvidence:
323
  """Run all generative model detection tests."""
324
  findings = []
325
  scores = []
326
 
327
+ for fn in [analyze_frequency_grid, analyze_diffusion_residuals, analyze_model_fingerprint,
328
+ analyze_upsampling_checkerboard, analyze_vae_boundaries]:
329
  try:
330
  result = fn(img)
331
  findings.append(result)
 
354
  agent_name="Generative Model Agent",
355
  violation_score=np.clip(avg_score, -1, 1),
356
  confidence=confidence,
357
+ failure_prob=max(0.0, 1.0 - len(scores) / 5),
358
  rationale=rationale,
359
  sub_findings=findings,
360
  )