Skip to content
Snippets Groups Projects
Commit 29d0cfa5 authored by Tamino Huxohl's avatar Tamino Huxohl
Browse files

write comments and improve measure computation

parent 81d2a7c9
No related branches found
No related tags found
No related merge requests found
import numpy as np import numpy as np
import pandas as pd
from mu_map.dataset.default import MuMapDataset
from mu_map.models.unet import UNet
def mse(prediction: np.array, target: np.array):
def mse(prediction: np.array, target: np.array) -> float:
"""
Compute the mean squared error (MSE) between a prediction and
a target array.
Parameters
----------
prediction: np.ndarray
target: np.ndarray
"""
se = (prediction - target) ** 2 se = (prediction - target) ** 2
mse = se.sum() / se.size mse = se.sum() / se.size
return mse return mse
def nmae(prediction: np.array, target: np.array, vmax:float=None, vmin:float=None): def nmae(
if vmax is None: prediction: np.array, target: np.array, vmax: float = None, vmin: float = None
vmax = target.max() ):
if vmin is None: """
vmin = target.min() Compute the normalized mean absolute error (NMAE) between a prediction
and a target array.
Parameters
----------
prediction: np.ndarray
target: np.ndarray
vmax: float, optional
maximum value for normalization, defaults to the maximal value in the target
vmin: float, optional
minimum value for normalization, defaults to the minimal value in the target
"""
vmax = target.max() if vmax is None else vmax
vmin = target.min() if vmin is None else vmin
ae = np.absolute(prediction - target) ae = np.absolute(prediction - target)
mae = ae.sum() / ae.size mae = ae.sum() / ae.size
...@@ -19,16 +45,51 @@ def nmae(prediction: np.array, target: np.array, vmax:float=None, vmin:float=Non ...@@ -19,16 +45,51 @@ def nmae(prediction: np.array, target: np.array, vmax:float=None, vmin:float=Non
return nmae return nmae
def compute_measures(dataset: MuMapDataset, model: UNet) -> pd.DataFrame:
"""
Compute measures (MSE, NMAE) for all images in a dataset.
Parameters
----------
dataset: MuMapDataset
the dataset containing the reconstructions and mu maps for which the scores are computed
model: UNet
the UNet model which is used to predict mu maps from reconstructions
Returns
-------
pd.DataFrame
a dataframe containing containing the measures for each image in the dataset
"""
measures = {"NMAE": nmae, "MSE": mse}
values = pd.DataFrame(dict(map(lambda x: (x, []), measures.keys())))
for i, (recon, mu_map) in enumerate(dataset):
_id = dataset.table.iloc[i]["id"]
print(
f"Process input {str(i):>{len(str(len(dataset)))}}/{len(dataset)}", end="\r"
)
prediction = model(recon.unsqueeze(dim=0).to(device))
prediction = prediction.squeeze().cpu().numpy()
mu_map = mu_map.squeeze().cpu().numpy()
row = dict(
map(lambda item: (item[0], [item[1](prediction, mu_map)]), measures.items())
)
row["id"] = _id
row = pd.DataFrame(row)
values = pd.concat((values, row), ignore_index=True)
print(f" " * 100, end="\r")
return values
if __name__ == "__main__": if __name__ == "__main__":
import argparse import argparse
import pandas as pd
import torch import torch
from mu_map.dataset.default import MuMapDataset
from mu_map.dataset.normalization import norm_by_str, norm_choices from mu_map.dataset.normalization import norm_by_str, norm_choices
from mu_map.dataset.transform import SequenceTransform, PadCropTranform from mu_map.dataset.transform import SequenceTransform, PadCropTranform
from mu_map.models.unet import UNet
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Compute, print and store measures for a given model", description="Compute, print and store measures for a given model",
...@@ -37,7 +98,7 @@ if __name__ == "__main__": ...@@ -37,7 +98,7 @@ if __name__ == "__main__":
parser.add_argument( parser.add_argument(
"--device", "--device",
type=str, type=str,
default="cpu", default="cuda" if torch.cuda.is_available() else "cpu",
choices=["cpu", "cuda"], choices=["cpu", "cuda"],
help="the device on which the model is evaluated (cpu or cuda)", help="the device on which the model is evaluated (cpu or cuda)",
) )
...@@ -84,7 +145,7 @@ if __name__ == "__main__": ...@@ -84,7 +145,7 @@ if __name__ == "__main__":
torch.set_grad_enabled(False) torch.set_grad_enabled(False)
device = torch.device(args.device) device = torch.device(args.device)
model = UNet() model = UNet(features=[32, 64, 128, 256, 512])
model.load_state_dict(torch.load(args.weights, map_location=device)) model.load_state_dict(torch.load(args.weights, map_location=device))
model = model.to(device).eval() model = model.to(device).eval()
...@@ -101,28 +162,16 @@ if __name__ == "__main__": ...@@ -101,28 +162,16 @@ if __name__ == "__main__":
scatter_correction=args.scatter_corrected, scatter_correction=args.scatter_corrected,
) )
measures = {"NMAE": nmae, "MSE": mse} values = compute_measures(dataset, model)
values = pd.DataFrame(dict(map(lambda x: (x, []), measures.keys())))
for i, (recon, mu_map) in enumerate(dataset):
print(
f"Process input {str(i):>{len(str(len(dataset)))}}/{len(dataset)}", end="\r"
)
prediction = model(recon.unsqueeze(dim=0).to(device))
prediction = prediction.squeeze().cpu().numpy()
mu_map = mu_map.squeeze().cpu().numpy()
row = pd.DataFrame(dict(
map(lambda item: (item[0], [item[1](prediction, mu_map)]), measures.items())
))
values = pd.concat((values, row), ignore_index=True)
print(f" " * 100, end="\r")
if args.out: if args.out:
values.to_csv(args.out, index=False) values.to_csv(args.out, index=False)
print("Scores:") print("Scores:")
for measure_name, measure_values in values.items(): for measure_name, measure_values in values.items():
if measure_name == "id":
continue
mean = measure_values.mean() mean = measure_values.mean()
std = np.std(measure_values) std = np.std(measure_values)
print(f" - {measure_name:>6}: {mean:.6f}±{std:.6f}") print(f" - {measure_name:>6}: {mean:.6f}±{std:.6f}")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment