# Load one real image and pass through backbone + FPN
# (reuse COCODataset from notebook 01 or load a single image)
# img should be a normalized tensor of shape [1, 3, H, W]; we use noise as a placeholder
img = torch.randn(1, 3, 800, 800) # replace with real image tensor once dataset wiring is in place
# Run the backbone to obtain C2–C5 feature maps at multiple strides
c2, c3, c4, c5 = backbone(img)
# Feed the multi-scale backbone outputs through the FPN to get pyramid levels P2–P6
p2, p3, p4, p5, p6 = fpn((c2, c3, c4, c5))
# Visualize the mean activation of each pyramid level to sanity-check spatial resolution
fig, axes = plt.subplots(1, 5, figsize=(20, 4))
# Iterate over each level, squeeze to spatial dimensions, and plot the channel-wise mean heatmap
for ax, (name, feat) in zip(axes, [('P2',p2),('P3',p3),('P4',p4),('P5',p5),('P6',p6)]):
fmap = feat[0].mean(dim=0).detach().cpu().numpy() # mean over channels to a single 2D map
ax.imshow(fmap, cmap='viridis')
ax.set_title(f"{name}\n{feat.shape[-2]}x{feat.shape[-1]}")
ax.axis('off')
# Persist the visualization for later inspection and display inline
plt.suptitle("FPN Feature Maps (mean activation)", fontsize=13)
plt.savefig("images/fpn_features.png", dpi=100, bbox_inches='tight')
plt.show()