File size: 2,746 Bytes
53becf5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
58
59
60
61
62
63
64
65
"""Evaluate reconstruction and cross-sensor representation consistency."""

import json
from pathlib import Path

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
import yaml


ROOT = Path(__file__).resolve().parents[1]


def main():
    config = yaml.safe_load((ROOT / "conf/config.yaml").read_text())
    predictions = np.load(ROOT / config["paths"]["inference_dir"] / "predictions.npz")
    sensors = list(config["data"]["sensors"])
    metrics = {"samples": int(len(predictions["class_target"])), "sensors": {}}
    projected = []
    for name in sensors:
        embedding = predictions[f"embedding_{name}"]
        projection = predictions[f"projected_embedding_{name}"]
        projected.append(projection)
        metrics["sensors"][name] = {
            "reconstruction_mae": float(np.abs(predictions[f"reconstruction_{name}"] - predictions[f"pixels_{name}"]).mean()),
            "embedding_norm": float(np.linalg.norm(embedding, axis=1).mean()),
            "projected_embedding_norm": float(np.linalg.norm(projection, axis=1).mean()),
            "representation_loss": float(predictions[f"representation_loss_{name}"]),
        }
    similarities = []
    for left in range(len(projected)):
        for right in range(left + 1, len(projected)):
            similarities.append((projected[left] * projected[right]).sum(axis=1))
    metrics["mean_cross_sensor_cosine_similarity"] = float(np.concatenate(similarities).mean())
    output_dir = ROOT / config["paths"]["evaluation_dir"]
    output_dir.mkdir(parents=True, exist_ok=True)
    (output_dir / "metrics.json").write_text(json.dumps(metrics, indent=2) + "\n")

    figure, axes = plt.subplots(len(sensors), 3, figsize=(9, 3 * len(sensors)), squeeze=False)
    for row, name in enumerate(sensors):
        rgb = config["data"]["sensors"][name]["rgb_indices"]
        source = predictions[f"pixels_{name}"][0, rgb].transpose(1, 2, 0)
        reconstruction = predictions[f"reconstruction_{name}"][0, rgb].transpose(1, 2, 0)
        for image in (source, reconstruction):
            image -= image.min()
            image /= image.max() + 1e-6
        axes[row, 0].imshow(source)
        axes[row, 0].set_title(f"{name} input")
        axes[row, 1].imshow(reconstruction)
        axes[row, 1].set_title("MAE reconstruction")
        axes[row, 2].imshow(np.abs(source - reconstruction).mean(axis=2), cmap="magma")
        axes[row, 2].set_title("absolute error")
        for axis in axes[row]:
            axis.axis("off")
    figure.tight_layout()
    figure.savefig(output_dir / "comparison.png", dpi=150)
    plt.close(figure)
    print(f"metrics={output_dir.relative_to(ROOT) / 'metrics.json'}")


if __name__ == "__main__":
    main()