From a000433c14498c9430be93d37de045bd2a8a28eb Mon Sep 17 00:00:00 2001 From: Ilya Polishchuk Date: Fri, 9 Sep 2022 23:17:46 +0300 Subject: [PATCH 1/2] Add EPS to avoid Nan --- piqa/lpips.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/piqa/lpips.py b/piqa/lpips.py index 3cbbe27..fcef024 100644 --- a/piqa/lpips.py +++ b/piqa/lpips.py @@ -28,7 +28,7 @@ ORIGIN: str = 'https://github.com/richzhang/PerceptualSimilarity' SHIFT: Tensor = torch.tensor([0.485, 0.456, 0.406]) SCALE: Tensor = torch.tensor([0.229, 0.224, 0.225]) - +EPS: float = 1e-10 def get_weights( network: str = 'alex', @@ -210,8 +210,8 @@ def forward(self, input: Tensor, target: Tensor) -> Tensor: residuals = [] for lin, fx, fy in zip(self.lins, self.net(input), self.net(target)): - fx = fx / l2_norm(fx, dims=[1], keepdim=True) - fy = fy / l2_norm(fy, dims=[1], keepdim=True) + fx = fx / (l2_norm(fx, dims=[1], keepdim=True) + EPS) + fy = fy / (l2_norm(fy, dims=[1], keepdim=True) + EPS) mse = ((fx - fy) ** 2).mean(dim=(-1, -2), keepdim=True) residuals.append(lin(mse).flatten()) From a1bd88d775c3a6837659e1c0a2ba68b2da774564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Rozet?= Date: Sat, 10 Sep 2022 12:32:03 +0200 Subject: [PATCH 2/2] Make epsilon an argument of LPIPS --- piqa/lpips.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/piqa/lpips.py b/piqa/lpips.py index fcef024..522a9b4 100644 --- a/piqa/lpips.py +++ b/piqa/lpips.py @@ -11,8 +11,6 @@ .. [Deng2009] ImageNet: A large-scale hierarchical image database (Deng et al, 2009) """ -import inspect -import os import torch import torch.nn as nn import torchvision.models as models @@ -28,7 +26,7 @@ ORIGIN: str = 'https://github.com/richzhang/PerceptualSimilarity' SHIFT: Tensor = torch.tensor([0.485, 0.456, 0.406]) SCALE: Tensor = torch.tensor([0.229, 0.224, 0.225]) -EPS: float = 1e-10 + def get_weights( network: str = 'alex', @@ -119,6 +117,7 @@ class LPIPS(nn.Module): network: Specifies the perceptual network :math:`\mathcal{F}` to use: `'alex'` | `'squeeze'` | `'vgg'`. scaling: Whether the input and target need to be scaled w.r.t. [Deng2009]_. + epsilon: A numerical stability term. dropout: Whether dropout is used or not. pretrained: Whether the official weights :math:`w_l` are used or not. eval: Whether to initialize the object in evaluation mode or not. @@ -144,6 +143,7 @@ def __init__( self, network: str = 'alex', scaling: bool = True, + epsilon: float = 1e-10, dropout: bool = False, pretrained: bool = True, eval: bool = True, @@ -155,6 +155,7 @@ def __init__( self.scaling = scaling self.register_buffer('shift', SHIFT.reshape(1, -1, 1, 1)) self.register_buffer('scale', SCALE.reshape(1, -1, 1, 1)) + self.epsilon = epsilon # Perception layers if network == 'alex': # AlexNet @@ -210,8 +211,8 @@ def forward(self, input: Tensor, target: Tensor) -> Tensor: residuals = [] for lin, fx, fy in zip(self.lins, self.net(input), self.net(target)): - fx = fx / (l2_norm(fx, dims=[1], keepdim=True) + EPS) - fy = fy / (l2_norm(fy, dims=[1], keepdim=True) + EPS) + fx = fx / (l2_norm(fx, dims=[1], keepdim=True) + self.epsilon) + fy = fy / (l2_norm(fy, dims=[1], keepdim=True) + self.epsilon) mse = ((fx - fy) ** 2).mean(dim=(-1, -2), keepdim=True) residuals.append(lin(mse).flatten())