From 3a5a2bb473fbbb97aca27b558d9df213c2f8f5cf Mon Sep 17 00:00:00 2001 From: julius Date: Fri, 3 Nov 2023 14:51:29 +0100 Subject: [PATCH 1/3] =?UTF-8?q?Implement=20a=20prototypical=202-layer=20?= =?UTF-8?q?=CE=A9=20distance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- prototorch/core/distances.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/prototorch/core/distances.py b/prototorch/core/distances.py index b3278fd..e86f498 100644 --- a/prototorch/core/distances.py +++ b/prototorch/core/distances.py @@ -73,6 +73,16 @@ def omega_distance(x, y, omega): return distances +def ML_omega_distance(x, y, omega_0, omega_1, mask_0, mask_1): + """Multi-Layer Omega distance.""" + x, y = (arr.view(arr.size(0), -1) for arr in (x, y)) + omega = (omega_0 * mask_0) @ (omega_1 * mask_1) + projected_x = x @ omega + projected_y = y @ omega + distances = squared_euclidean_distance(projected_x, projected_y) + return distances + + def lomega_distance(x, y, omegas): r"""Localized Omega distance. From f35a08a070e12232969869ee93211aad5a5a0fbe Mon Sep 17 00:00:00 2001 From: julius Date: Tue, 7 Nov 2023 16:45:05 +0100 Subject: [PATCH 2/3] ML_omega_distance: allow for 2 or more omegas and masks --- prototorch/core/distances.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/prototorch/core/distances.py b/prototorch/core/distances.py index e86f498..33b4880 100644 --- a/prototorch/core/distances.py +++ b/prototorch/core/distances.py @@ -73,10 +73,14 @@ def omega_distance(x, y, omega): return distances -def ML_omega_distance(x, y, omega_0, omega_1, mask_0, mask_1): +def ML_omega_distance(x, y, omegas, masks): """Multi-Layer Omega distance.""" x, y = (arr.view(arr.size(0), -1) for arr in (x, y)) - omega = (omega_0 * mask_0) @ (omega_1 * mask_1) + # omega = (omega_0 * mask_0) @ (omega_1 * mask_1) + omegas = [torch.mul(_omega, _mask) for _omega, _mask in zip(omegas, masks)] + omega = omegas[0] @ omegas[1] + for _omega in omegas[2:]: + omega = omega @ _omega projected_x = x @ omega projected_y = y @ omega distances = squared_euclidean_distance(projected_x, projected_y) From 9490d7cd7a8133c1d39c2255b0894b2cfd9f4e24 Mon Sep 17 00:00:00 2001 From: julius Date: Tue, 30 Apr 2024 09:58:30 +0200 Subject: [PATCH 3/3] fix: remove unnecessary comment --- prototorch/core/distances.py | 1 - prototorch/core/initializers.py | 30 ++++++++++++++++++------------ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/prototorch/core/distances.py b/prototorch/core/distances.py index 33b4880..ae66afa 100644 --- a/prototorch/core/distances.py +++ b/prototorch/core/distances.py @@ -76,7 +76,6 @@ def omega_distance(x, y, omega): def ML_omega_distance(x, y, omegas, masks): """Multi-Layer Omega distance.""" x, y = (arr.view(arr.size(0), -1) for arr in (x, y)) - # omega = (omega_0 * mask_0) @ (omega_1 * mask_1) omegas = [torch.mul(_omega, _mask) for _omega, _mask in zip(omegas, masks)] omega = omegas[0] @ omegas[1] for _omega in omegas[2:]: diff --git a/prototorch/core/initializers.py b/prototorch/core/initializers.py index d6ae098..0df770a 100644 --- a/prototorch/core/initializers.py +++ b/prototorch/core/initializers.py @@ -17,6 +17,7 @@ # Components class AbstractComponentsInitializer(ABC): """Abstract class for all components initializers.""" + ... @@ -34,9 +35,9 @@ def generate(self, num_components: int = 0): """Ignore `num_components` and simply return `self.components`.""" provided_num_components = len(self.components) if provided_num_components != num_components: - wmsg = f"The number of components ({provided_num_components}) " \ - f"provided to {self.__class__.__name__} " \ - f"does not match the expected number ({num_components})." + wmsg = (f"The number of components ({provided_num_components}) " + f"provided to {self.__class__.__name__} " + f"does not match the expected number ({num_components}).") warnings.warn(wmsg) if not isinstance(self.components, torch.Tensor): wmsg = f"Converting components to {torch.Tensor}..." @@ -127,10 +128,12 @@ class AbstractDataAwareCompInitializer(AbstractComponentsInitializer): """ - def __init__(self, - data: torch.Tensor, - noise: float = 0.0, - transform: Callable = torch.nn.Identity()): + def __init__( + self, + data: torch.Tensor, + noise: float = 0.0, + transform: Callable = torch.nn.Identity(), + ): self.data = data self.noise = noise self.transform = transform @@ -429,6 +432,7 @@ def generate(self, distribution: Union[dict, list, tuple]): # Transforms class AbstractTransformInitializer(ABC): """Abstract class for all transform initializers.""" + ... @@ -486,11 +490,13 @@ def generate(self, in_dim: int, out_dim: int): class AbstractDataAwareLTInitializer(AbstractLinearTransformInitializer): """Abstract class for all data-aware linear transform initializers.""" - def __init__(self, - data: torch.Tensor, - noise: float = 0.0, - transform: Callable = torch.nn.Identity(), - out_dim_first: bool = False): + def __init__( + self, + data: torch.Tensor, + noise: float = 0.0, + transform: Callable = torch.nn.Identity(), + out_dim_first: bool = False, + ): super().__init__(out_dim_first) self.data = data self.noise = noise