Add analysis scripts and experiment configurations for bridge attention and sensitivity studies
- Introduced `bridge_attention_ceiling_check.py` for variance decomposition analysis on bridge attention configurations. - Added `bridge_attention_readout.py` to perform per-tower gate and contribution readouts, including AUC sanity checks. - Created multiple JSON configuration files for backbone replication experiments, including anonymous CV variants and basic backbones. - Implemented sensitivity experiments to evaluate the impact of axial length inclusion and EfficientNetV2-M performance at higher resolutions. - Added a memory probe script to assess GPU memory usage during training with EfficientNetV2-M.
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
"""F8 combined explainability panel: disc-centred attention + quadrant breakdown.
|
||||
|
||||
Composes a single A/B figure from two existing renderings:
|
||||
A: ``F8_gradcam/disc_attention_detail.png`` — 2x2 grid of mean Grad-CAM
|
||||
heatmaps for {correct, incorrect} x {Normal, Glaucoma} cells, with the
|
||||
mean disc boundary annotated as a dashed circle.
|
||||
B: ``F8_quadrant_attention.png`` — grouped-bar chart of mean full-image
|
||||
Grad-CAM fraction per optic-disc quadrant, by cell.
|
||||
|
||||
Both source panels are produced by ``v4.figures.F8_explainability`` and
|
||||
``v4.figures.F8_quadrant_plot`` respectively; this script just stitches the
|
||||
two PNGs into a single combined figure with A/B subfigure labels.
|
||||
|
||||
Re-run:
|
||||
python -m v4.figures.F8_attention_combined
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import matplotlib
|
||||
matplotlib.use("Agg")
|
||||
import matplotlib.pyplot as plt
|
||||
from PIL import Image
|
||||
|
||||
|
||||
SRC_A = Path(__file__).parent / "output" / "F8_gradcam" / "disc_attention_detail.png"
|
||||
SRC_B = Path(__file__).parent / "output" / "F8_quadrant_attention.png"
|
||||
OUT = Path(__file__).parent / "output" / "F8_attention_combined.png"
|
||||
|
||||
|
||||
def render() -> None:
|
||||
for p in (SRC_A, SRC_B):
|
||||
if not p.exists():
|
||||
raise SystemExit(
|
||||
f"Source panel missing: {p}\n"
|
||||
"Run F8_explainability (for A) and F8_quadrant_plot (for B) first."
|
||||
)
|
||||
|
||||
img_a = Image.open(SRC_A)
|
||||
img_b = Image.open(SRC_B)
|
||||
|
||||
# Stack vertically: A on top (square), B below (wider).
|
||||
fig = plt.figure(figsize=(13.0, 13.6))
|
||||
gs = fig.add_gridspec(
|
||||
2, 1,
|
||||
height_ratios=[img_a.size[1] / img_a.size[0],
|
||||
img_b.size[1] / img_b.size[0] * 13.0 / 13.0],
|
||||
hspace=0.06,
|
||||
)
|
||||
|
||||
ax_a = fig.add_subplot(gs[0])
|
||||
ax_a.imshow(img_a)
|
||||
ax_a.axis("off")
|
||||
ax_a.text(-0.01, 1.01, "A", transform=ax_a.transAxes,
|
||||
ha="left", va="bottom", fontsize=22, fontweight="bold")
|
||||
|
||||
ax_b = fig.add_subplot(gs[1])
|
||||
ax_b.imshow(img_b)
|
||||
ax_b.axis("off")
|
||||
ax_b.text(-0.01, 1.01, "B", transform=ax_b.transAxes,
|
||||
ha="left", va="bottom", fontsize=22, fontweight="bold")
|
||||
|
||||
fig.tight_layout()
|
||||
OUT.parent.mkdir(parents=True, exist_ok=True)
|
||||
fig.savefig(OUT, dpi=180, bbox_inches="tight")
|
||||
plt.close(fig)
|
||||
print(f"saved {OUT}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
render()
|
||||
Reference in New Issue
Block a user