File size: 3,065 Bytes
c023008
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Reload the saved model in a fresh process and predict all 922 test cases."""
import argparse
from pathlib import Path
import time

import numpy as np
import pandas as pd
from common import (load_config, ensure_compute_node, load_fixed_dataset, WavyChannelRF,
                    metrics_for, print_metrics, prediction_frame, write_json, write_metrics, sha256)


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--config", required=True)
    parser.add_argument("--checkpoint", help="Optional explicit path to saved joblib .pth bundle")
    args = parser.parse_args()
    config = load_config(args.config)
    runtime = ensure_compute_node(config)
    directory = Path(config["output"]["results_dir"])
    data, data_manifest = load_fixed_dataset(config)
    test = data.loc[data[config["data"]["split_column"]] == "test"]
    features, targets = config["data"]["features"], config["data"]["targets"]
    checkpoint = Path(args.checkpoint or config["output"]["checkpoint"])
    print(f"[inference] Loading {checkpoint}", flush=True)
    model, metadata = WavyChannelRF.load(checkpoint)
    if model.n_train_ != config["data"]["expected_counts"]["train"]:
        raise ValueError("Checkpoint did not fit the required complete training set")
    for name in ["dataset", "split_file"]:
        if metadata["data"]["files"][name]["sha256"] != data_manifest["files"][name]["sha256"]:
            raise ValueError(f"{name} changed since model fitting")
    start = time.perf_counter()
    predicted = model.predict(test[features])
    seconds = time.perf_counter() - start
    metrics = metrics_for(test[targets], predicted, targets)
    print_metrics("inference-test", metrics, len(test))
    output = prediction_frame(test, predicted, config)
    output.to_csv(directory / "inference_predictions.csv", index=False)
    write_metrics(directory, metrics, "inference_metrics")
    reference = pd.read_csv(directory / "test_predictions.csv")
    key = config["data"]["join_key"]
    if reference[key].tolist() != output[key].tolist():
        raise ValueError("Reloaded inference test case order differs from training evaluation")
    pred_cols = [f"{t}_pred" for t in targets]
    error = float(np.max(np.abs(reference[pred_cols].to_numpy() - output[pred_cols].to_numpy())))
    np.testing.assert_allclose(reference[pred_cols], output[pred_cols], atol=1e-10, rtol=1e-12)
    verification = {"status": "passed", "test_rows": len(test), "predictions_finite": True,
                    "independent_process_reload": True, "case_uids_equal": True,
                    "max_abs_prediction_difference": error, "tolerance": {"atol": 1e-10, "rtol": 1e-12},
                    "prediction_seconds": seconds, "runtime": runtime,
                    "checkpoint_sha256": sha256(checkpoint), "test_metrics": metrics}
    write_json(directory / "reload_validation.json", verification)
    print(f"[inference] Reload validation passed: n={len(test)}, max_abs_difference={error:.3g}", flush=True)


if __name__ == "__main__":
    main()