File size: 2,472 Bytes
48b1346 255c417 48b1346 255c417 48b1346 | 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 |
import numpy as np
import matplotlib.pyplot as plt
import torch
def to_numpy_img(t):
"""Convert torch CHW / numpy HWC (or HW) to an array matplotlib can show."""
if isinstance(t, torch.Tensor):
t = t.detach().cpu().numpy()
if t.ndim == 4: # (B,C,H,W) → first sample
t = t[0]
if t.ndim == 3: # CHW → HWC
t = np.transpose(t, (1, 2, 0))
elif isinstance(t, np.ndarray) and t.ndim == 3:
# Only transpose if channels-first (C,H,W), not already HWC
if t.shape[0] in (1, 3, 4) and t.shape[-1] not in (1, 3, 4):
t = np.transpose(t, (1, 2, 0))
if isinstance(t, np.ndarray) and t.ndim == 3 and t.shape[-1] == 1:
t = t.squeeze(-1)
return t
def show_synthesis_result(normal_img, jnd_map, anomaly_img, severity_mask, panel_name: str = ""):
fig, axes = plt.subplots(1, 4, figsize=(16, 4))
axes[0].imshow(to_numpy_img(normal_img))
axes[0].set_title("Normal Image")
axes[1].imshow(to_numpy_img(jnd_map), cmap="viridis")
axes[1].set_title("JND Map")
axes[2].imshow(to_numpy_img(anomaly_img))
axes[2].set_title(f"Synthesized Anomaly (panel={panel_name})")
axes[3].imshow(to_numpy_img(severity_mask), cmap="jet", vmin=0, vmax=3)
axes[3].set_title("Severity Mask (0=bg,1=easy,2=med,3=hard)")
for ax in axes:
ax.axis("off")
plt.tight_layout()
plt.show()
def show_model_output(anomaly_img, rec_img, rec_jnd, seg_map, gt_mask=None):
n_cols = 5 if gt_mask is not None else 4
fig, axes = plt.subplots(1, n_cols, figsize=(4 * n_cols, 4))
axes[0].imshow(to_numpy_img(anomaly_img))
axes[0].set_title("Input (anomaly)")
axes[1].imshow(to_numpy_img(rec_img))
axes[1].set_title("Reconstruction")
axes[2].imshow(to_numpy_img(rec_jnd), cmap="viridis")
axes[2].set_title("Reconstructed JND")
axes[3].imshow(to_numpy_img(seg_map), cmap="jet")
axes[3].set_title("Predicted anomaly map")
if gt_mask is not None:
axes[4].imshow(to_numpy_img(gt_mask), cmap="gray")
axes[4].set_title("Ground Truth mask")
for ax in axes:
ax.axis("off")
plt.tight_layout()
plt.show()
def plot_loss_curves(history: dict):
plt.figure(figsize=(8, 5))
for name, values in history.items():
plt.plot(values, label=name)
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.legend()
plt.title("Training Loss Curves")
plt.grid(alpha=0.3)
plt.show()
|