File size: 3,426 Bytes
8f89e30 | 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 | """Plot training curves and physical-space validation predictions."""
import argparse
import csv
import json
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
from common import load_config, package_path, save_json
def render(config):
output = package_path(config["results"]["directory"])
data = np.load(output/"predictions.npz")
metrics = json.loads((output/"metrics.json").read_text())
with open(output/"history.csv") as stream:
rows = list(csv.DictReader(stream))
epoch = np.array([int(r["epoch"]) for r in rows])
fig, axes = plt.subplots(1, 2, figsize=(11, 4), constrained_layout=True)
for name, label in [("train_loss","Training"),("val_loss","Validation")]:
axes[0].semilogy(epoch,[float(r[name]) for r in rows],label=label)
axes[0].set(xlabel="Epoch",ylabel="MSE + relative L2 (normalized)")
axes[0].legend()
axes[1].semilogy(epoch,[float(r["val_relative_l2"]) for r in rows],color="tab:blue",label="Validation")
axes[1].axhline(0.0109,color="tab:red",linestyle="--",label="Paper Table 1: 0.0109")
axes[1].set(xlabel="Epoch",ylabel="Relative L2 (physical space)")
axes[1].legend()
for ax in axes: ax.grid(alpha=0.2)
fig.savefig(output/"training_curves.png",dpi=200)
fig.savefig(output/"training_curves.pdf")
plt.close(fig)
errors=data["relative_l2"]
chosen=[0,int(np.argsort(errors)[len(errors)//2]),int(np.argmax(errors))]
fig, axes=plt.subplots(3,2,figsize=(12,10),constrained_layout=True)
x=data["x"]
for row,index in enumerate(chosen):
initial=data["initial"][index,:,0]; target=data["target"][index,:,0]; pred=data["prediction"][index,:,0]
axes[row,0].plot(x,initial,color="0.6",linewidth=1,label="Initial u0")
axes[row,0].plot(x,target,color="black",linewidth=1.5,label="Reference u(T)")
axes[row,0].plot(x,pred,color="tab:blue",linestyle="--",label="LiNO")
axes[row,0].set_title(f"Source sample {data['sample_indices'][index]}, relative L2={errors[index]:.4g}")
axes[row,0].set(xlabel="x",ylabel="u (dataset units)")
axes[row,0].legend()
axes[row,1].plot(x,pred-target,color="tab:red")
axes[row,1].axhline(0,color="0.5",linewidth=0.5)
axes[row,1].set(xlabel="x",ylabel="Prediction - reference")
fig.savefig(output/"validation_examples.png",dpi=200)
fig.savefig(output/"validation_examples.pdf")
plt.close(fig)
fig, ax=plt.subplots(figsize=(6,4),constrained_layout=True)
ax.hist(errors,bins=35,color="tab:blue",alpha=.85)
ax.set(xlabel="Validation relative L2",ylabel="Samples",title=f"All {len(errors)} held-out samples")
fig.savefig(output/"error_distribution.png",dpi=200)
plt.close(fig)
save_json(output/"visualization_manifest.json",dict(figures=["training_curves.png","training_curves.pdf","validation_examples.png","validation_examples.pdf","error_distribution.png"],
selected_validation_indices=chosen,sample_count=len(errors),completed_epochs=len(rows),metrics=metrics))
print(f"VISUALIZATION COMPLETED: {output} ({len(rows)} epochs, {len(errors)} validation samples)",flush=True)
if __name__ == "__main__":
parser=argparse.ArgumentParser(description=__doc__)
parser.add_argument("--config",default="config/config.yaml")
args=parser.parse_args()
render(load_config(args.config))
|