NOTS-DarcyFlowRate / scripts /inference.py
yushuang88's picture
Upload folder using huggingface_hub
5978445 verified
Raw History Blame Contribute Delete
3.01 kB
"""Load the saved best FNO checkpoint and evaluate untouched official test data."""
from pathlib import Path
from common import (case_guard, config_hash, load_config, load_data,
negative_total_flow_rates, parse_args, predict, save_json,
save_torch, sha256)
import torch
from model.NOTS import NOTS
def main():
parser = parse_args(__doc__)
parser.add_argument('--checkpoint', type=Path)
args = parser.parse_args()
cfg = load_config(args.config)
device = case_guard(cfg)
out = Path(cfg['paths']['output_dir'])
checkpoint_path = args.checkpoint or out / 'weight/best_model.pt'
state = torch.load(checkpoint_path, weights_only=False, map_location='cpu')
if state['config_hash'] != config_hash(cfg):
raise ValueError('Checkpoint/config protocol mismatch')
if state['normalization']['kind'] != 'identity':
raise ValueError('Unexpected checkpoint prediction scale')
model = NOTS(**state['model_config']).to(device)
model.load_state_dict(state['model_state'], strict=True)
model.eval()
metrics = {'checkpoint': str(checkpoint_path), 'checkpoint_sha256': sha256(checkpoint_path),
'selected_seed': state['seed'], 'selection_train_mse': state['train_mse'], 'splits': {}}
for split in ('test', 'train'):
x, y, meta = load_data(cfg, split)
if split == 'train' and meta['sha256'] != state['data_sha256']:
raise ValueError('Checkpoint training pool hash differs')
x, y = x.to(device), y.to(device)
with torch.no_grad():
output = predict(model, x, cfg['experiment']['prediction_batch_size'])
error = output - y
truth = negative_total_flow_rates(y, x)
predicted_flow = negative_total_flow_rates(output, x)
result = {'n': len(x), 'mse': error.square().mean().item(),
'relative_l2_mean': (error.flatten(1).norm(dim=1) / y.flatten(1).norm(dim=1).clamp_min(1e-12)).mean().item(),
'functional_mae': (truth - predicted_flow).abs().mean().item(),
'predicted_best_index': predicted_flow.argmax().item(),
'true_best_index': truth.argmax().item(),
'prediction_shape': list(output.shape),
'all_finite': bool(torch.isfinite(output).all().item()), 'data': meta}
if not result['all_finite']:
raise FloatingPointError('Nonfinite checkpoint inference')
metrics['splits'][split] = result
save_torch(out / 'results' / f'inference_{split}.pt', {'x': x.cpu(), 'target': y.cpu(),
'prediction': output.cpu(), 'true_functional': truth.cpu(),
'predicted_functional': predicted_flow.cpu(), 'checkpoint_sha256': metrics['checkpoint_sha256']})
print(f'INFERENCE split={split} {result}', flush=True)
save_json(out / 'results/inference_metrics.json', metrics)
if __name__ == '__main__':
main()