From d0b5153b0a1e1069b175269b86003ed94388e0d8 Mon Sep 17 00:00:00 2001 From: serfg Date: Mon, 1 Jan 2024 19:41:44 +0100 Subject: [PATCH] fix --- src/estimate_error.py | 28 +++++++++++++++++---------- src/utilities.py | 26 ++++++++++++++++--------- tests/test_pet_runs_without_errors.py | 1 - 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/estimate_error.py b/src/estimate_error.py index 19e924a..05372bd 100644 --- a/src/estimate_error.py +++ b/src/estimate_error.py @@ -20,11 +20,10 @@ def main(): parser.add_argument("structures_path", help="Path to an xyz file with structures", type = str) parser.add_argument("path_to_calc_folder", help="Path to a folder with a model to use", type = str) - parser.add_argument("checkpoint", help="Path to a particular checkpoint to use", type = str, choices = ['best_val_mae_energies_model', 'best_val_rmse_energies_model', 'best_val_mae_forces_model', 'best_val_rmse_forces_model', 'best_val_mae_both_model', 'best_val_rmse_both_model']) + parser.add_argument("checkpoint", help="Path to a particular checkpoint to use", type = str) parser.add_argument("n_aug", type = int, help = "A number of rotational augmentations to use. It should be a positive integer or -1. If -1, the initial coordinate system will be used, not a single random one, as in the n_aug = 1 case") - parser.add_argument("default_hypers_path", help="Path to a YAML file with default hypers", type = str) - + parser.add_argument("batch_size", type = int, help="Batch size to use for inference. It should be a positive integer or -1. If -1, it will be set to the value used for fitting the provided model.") parser.add_argument("--path_save_predictions", help="Path to a folder where to save predictions.", type = str) @@ -89,8 +88,10 @@ def main(): for batch in loader: if not FITTING_SCHEME.MULTI_GPU: batch.to(device) - - _ = model(batch, augmentation = USE_AUGMENTATION, create_graph = False) + if hypers.UTILITY_FLAGS.CALCULATION_TYPE == 'mlip': + _ = model(batch, augmentation = USE_AUGMENTATION, create_graph = False) + else: + _ = model(batch, augmentation = USE_AUGMENTATION) break begin = time.time() @@ -102,7 +103,11 @@ def main(): if not FITTING_SCHEME.MULTI_GPU: batch.to(device) - predictions_batch = model(batch, augmentation = USE_AUGMENTATION, create_graph = False) + if hypers.UTILITY_FLAGS.CALCULATION_TYPE == 'mlip': + predictions_batch = model(batch, augmentation = USE_AUGMENTATION, create_graph = False) + else: + predictions_batch = model(batch, augmentation = USE_AUGMENTATION) + batch_accumulator.update(predictions_batch) predictions = batch_accumulator.flush() for index in range(len(predictions)): @@ -111,13 +116,13 @@ def main(): aug_accumulator.update(predictions) all_predictions = aug_accumulator.flush() - all_energies_predicted, all_forces_predicted = all_predictions total_time = time.time() - begin n_atoms = np.array([len(struc.positions) for struc in structures]) time_per_atom = total_time / (np.sum(n_atoms) * N_AUG) if hypers.UTILITY_FLAGS.CALCULATION_TYPE == 'mlip': + all_energies_predicted, all_forces_predicted = all_predictions MLIP_SETTINGS = hypers.MLIP_SETTINGS if MLIP_SETTINGS.USE_ENERGIES: self_contributions = np.load(SELF_CONTRIBUTIONS_PATH) @@ -133,14 +138,16 @@ def main(): report_accuracy(all_energies_predicted, energies_ground_truth, "energies", args.verbose, specify_per_component = False, - target_type = 'structural', n_atoms = n_atoms) + target_type = 'structural', n_atoms = n_atoms, + support_missing_values=FITTING_SCHEME.SUPPORT_MISSING_VALUES) if MLIP_SETTINGS.USE_FORCES: forces_ground_truth = [struc.arrays[MLIP_SETTINGS.FORCES_KEY] for struc in structures] forces_ground_truth = np.concatenate(forces_ground_truth, axis = 0) report_accuracy(all_forces_predicted, forces_ground_truth, "forces", args.verbose, specify_per_component = True, - target_type = 'atomic', n_atoms = n_atoms) + target_type = 'atomic', n_atoms = n_atoms, + support_missing_values=FITTING_SCHEME.SUPPORT_MISSING_VALUES) if hypers.UTILITY_FLAGS.CALCULATION_TYPE == 'general_target': if len(all_predictions) != 1: @@ -153,7 +160,8 @@ def main(): report_accuracy(all_targets_predicted, ground_truth, GENERAL_TARGET_SETTINGS.TARGET_KEY, args.verbose, specify_per_component = True, - target_type = GENERAL_TARGET_SETTINGS.TARGET_TYPE, n_atoms = n_atoms) + target_type = GENERAL_TARGET_SETTINGS.TARGET_TYPE, n_atoms = n_atoms, + support_missing_values=FITTING_SCHEME.SUPPORT_MISSING_VALUES) if args.verbose: print(f"approximate time per atom not including neighbor list construction for batch size of {args.batch_size}: {time_per_atom} seconds") diff --git a/src/utilities.py b/src/utilities.py index 69ce40e..acaf78e 100644 --- a/src/utilities.py +++ b/src/utilities.py @@ -233,15 +233,16 @@ def get_rotational_discrepancy(all_predictions): def report_accuracy(all_predictions, ground_truth, target_name, verbose, specify_per_component, - target_type, n_atoms = None): + target_type, n_atoms = None, + support_missing_values = False): predictions_mean = np.mean(all_predictions, axis=0) if specify_per_component: specification = "per component" else: specification = "" - print(f"{target_name} mae {specification}: {get_mae(predictions_mean, ground_truth)}") - print(f"{target_name} rmse {specification}: {get_rmse(predictions_mean, ground_truth)}") + print(f"{target_name} mae {specification}: {get_mae(predictions_mean, ground_truth, support_missing_values = support_missing_values)}") + print(f"{target_name} rmse {specification}: {get_rmse(predictions_mean, ground_truth, support_missing_values=support_missing_values)}") if all_predictions.shape[0] > 1: predictions_std = get_rotational_discrepancy(all_predictions) @@ -249,17 +250,24 @@ def report_accuracy(all_predictions, ground_truth, target_name, print(f"{target_name} rotational discrepancy std {specification}: {predictions_std} ") if target_type == 'structural': - predictions_mean_per_atom = predictions_mean / n_atoms - ground_truth_per_atom = ground_truth / n_atoms + if len(predictions_mean.shape) == 1: + predictions_mean = predictions_mean[:, np.newaxis] + if len(ground_truth.shape) == 1: + ground_truth = ground_truth[:, np.newaxis] - print(f"{target_name} mae per atom {specification}: {get_mae(predictions_mean_per_atom, ground_truth_per_atom)}") - print(f"{target_name} rmse per atom {specification}: {get_rmse(predictions_mean_per_atom, ground_truth_per_atom)}") + predictions_mean_per_atom = predictions_mean / n_atoms[:, np.newaxis] + ground_truth_per_atom = ground_truth / n_atoms[:, np.newaxis] + + print(f"{target_name} mae per atom {specification}: {get_mae(predictions_mean_per_atom, ground_truth_per_atom, support_missing_values = support_missing_values)}") + print(f"{target_name} rmse per atom {specification}: {get_rmse(predictions_mean_per_atom, ground_truth_per_atom, support_missing_values=support_missing_values)}") if all_predictions.shape[0] > 1: - all_predictions_per_atom = all_predictions / n_atoms[np.newaxis, :] + if len(all_predictions.shape) == 2: + all_predictions = all_predictions[:, :, np.newaxis] + all_predictions_per_atom = all_predictions / n_atoms[np.newaxis, :, np.newaxis] predictions_std_per_atom = get_rotational_discrepancy(all_predictions_per_atom) if verbose: print(f"{target_name} rotational discrepancy std per atom {specification}: {predictions_std_per_atom} ") - + diff --git a/tests/test_pet_runs_without_errors.py b/tests/test_pet_runs_without_errors.py index 6b8f4cc..5100835 100644 --- a/tests/test_pet_runs_without_errors.py +++ b/tests/test_pet_runs_without_errors.py @@ -88,7 +88,6 @@ def test_pet_run(prepare_model): model_folder, "best_val_rmse_both_model", "1", - "../default_hypers/default_hypers.yaml", "100", ]