RONOM / scripts /result.py
yushuang88's picture
Upload folder using huggingface_hub
e456924 verified
Raw History Blame Contribute Delete
5.61 kB
"""Visualize independent Burgers predictions, errors and the actual training log."""
import csv
import json
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
from common import parser, load_config, resolve, save_json, update_run_manifest
def main():
args = parser(__doc__).parse_args()
cfg = load_config(args.config)
folder = resolve(cfg['paths']['results'])
data = np.load(folder / 'test_predictions.npz')
pred, truth, times, x = (data[k] for k in ['prediction', 'reference', 'times', 'x'])
if pred.shape != (200, 11, 33) or not np.isfinite(pred).all():
raise ValueError('Invalid independent test predictions')
summary = json.loads((folder / 'test_metrics.json').read_text())
rmse = np.sqrt(np.mean((pred - truth)**2, axis=(1, 2)))
plot_dir = folder / 'figures'
plot_dir.mkdir(exist_ok=True)
dpi = cfg['visualization']['dpi']
files = []
def save(fig, name):
for suffix in ['png', 'pdf']:
destination = plot_dir / f'{name}.{suffix}'
fig.savefig(destination, dpi=dpi, bbox_inches='tight')
files.append(str(destination.relative_to(folder)))
plt.close(fig)
selected = list(dict.fromkeys(cfg['visualization']['sample_indices'] + [int(rmse.argmax())]))
for i in selected:
uid = int(data['sample_ids'][i])
fig, axes = plt.subplots(1, 3, figsize=(12, 3.5), constrained_layout=True)
vlim = max(float(np.max(np.abs(truth[i]))), float(np.max(np.abs(pred[i]))))
for ax, field, title in zip(axes[:2], [truth[i], pred[i]], ['Reference', 'RONOM']):
im = ax.pcolormesh(times, x, field.T, shading='nearest', cmap='RdBu_r',
vmin=-vlim, vmax=vlim)
ax.set(title=title, xlabel='t', ylabel='x')
fig.colorbar(im, ax=axes[:2], label='u(x,t)')
im = axes[2].pcolormesh(times, x, np.abs(pred[i] - truth[i]).T,
shading='nearest', cmap='magma')
axes[2].set(title='Absolute error', xlabel='t', ylabel='x')
fig.colorbar(im, ax=axes[2], label='|prediction - reference|')
fig.suptitle(f'Independent test case {uid}, trajectory RMSE = {rmse[i]:.3e}')
save(fig, f'test_case_{uid}_fields')
fig, axes = plt.subplots(1, 3, figsize=(12, 3.2), constrained_layout=True)
for ax, j in zip(axes, [0, 5, 10]):
ax.plot(x, truth[i, j], color='black', label='Reference')
ax.plot(x, pred[i, j], '--o', ms=3, color='tab:blue', label='RONOM')
ax.set(title=f't = {times[j]:.1f}', xlabel='x', ylabel='u(x,t)')
ax.grid(alpha=.2)
axes[0].legend()
fig.suptitle(f'Independent test case {uid}')
save(fig, f'test_case_{uid}_profiles')
epochs = np.array([], dtype=int)
if (folder / 'training_history.csv').exists():
with (folder / 'training_history.csv').open() as f:
history = list(csv.DictReader(f))
epochs = np.array([int(r['epoch']) for r in history])
if len(epochs) != 5000 or not np.array_equal(epochs, np.arange(1, 5001)):
raise ValueError('Expected one complete formal training history, epochs 1 through 5000')
val_rows = [r for r in history if r['validation_mse']]
fig, ax = plt.subplots(figsize=(7, 4))
ax.semilogy(epochs, [float(r['train_mse']) for r in history], label='Training MSE')
ax.semilogy([int(r['epoch']) for r in val_rows],
[float(r['validation_mse']) for r in val_rows], 'o-', label='Validation MSE')
ax.axvline(summary['checkpoint_epoch'], color='grey', ls=':', label='Selected epoch')
ax.set(xlabel='Epoch', ylabel='MSE', title='Formal 5000-epoch training')
ax.legend(); ax.grid(alpha=.2)
save(fig, 'training_curve')
else:
print('Training history is absent in this results directory; generating independent test figures.', flush=True)
fig, axes = plt.subplots(1, 2, figsize=(10, 3.6), constrained_layout=True)
axes[0].plot(times, summary['rmse_by_time'], 'o-')
axes[0].set(xlabel='t', ylabel='RMSE across independent test cases and x', title='Error by time')
axes[1].hist(rmse * 1000, bins=25, edgecolor='white')
axes[1].set(xlabel='Trajectory RMSE (× 10⁻³)', ylabel='Test cases', title='200 independent trajectories')
save(fig, 'test_error_summary')
comparison = folder / 'table1a_comparison.csv'
with comparison.open('w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['source', 'split', 'samples', 'rmse_mean', 'rmse_std_ddof1', 'units'])
writer.writerow(['paper_Table1a_RONOM', 'paper_test', 200, .00134, .00162, 'raw'])
writer.writerow(['this_run', 'independent_test_800_999', 200,
summary['trajectory_rmse_mean'], summary['trajectory_rmse_std_ddof1'], 'raw'])
save_json(folder / 'visualization_manifest.json', {
'figures': files, 'sample_ids': [int(data['sample_ids'][i]) for i in selected],
'dpi': dpi, 'test_shape': list(pred.shape), 'training_epochs': len(epochs) if len(epochs) else None,
'colormaps': {'field': 'RdBu_r', 'absolute_error': 'magma'},
'note': 'Validation selected weights. Test figures and metrics are post-training only.'})
update_run_manifest(cfg, status='completed', figure_files=len(files),
visualization_manifest='visualization_manifest.json')
print(f'VISUALIZATION COMPLETE: {len(files)} figures in {plot_dir}', flush=True)
if __name__ == '__main__':
main()