cauchy.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. # LICENSE HEADER MANAGED BY add-license-header
  2. #
  3. # Copyright 2018 Kornia Team
  4. #
  5. # Licensed under the Apache License, Version 2.0 (the "License");
  6. # you may not use this file except in compliance with the License.
  7. # You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. #
  17. from __future__ import annotations
  18. import torch
  19. from torch import Tensor
  20. from kornia.core import Module
  21. from kornia.core.check import KORNIA_CHECK, KORNIA_CHECK_IS_TENSOR, KORNIA_CHECK_SAME_DEVICE, KORNIA_CHECK_SAME_SHAPE
  22. def cauchy_loss(img1: Tensor, img2: Tensor, reduction: str = "none") -> Tensor:
  23. r"""Criterion that computes the Cauchy [2] (aka. Lorentzian) loss.
  24. According to [1], we compute the Cauchy loss as follows:
  25. .. math::
  26. \text{WL}(x, y) = log(\frac{1}{2} (x - y)^{2} + 1)
  27. Where:
  28. - :math:`x` is the prediction.
  29. - :math:`y` is the target to be regressed to.
  30. Reference:
  31. [1] https://arxiv.org/pdf/1701.03077.pdf
  32. [2] https://files.is.tue.mpg.de/black/papers/cviu.63.1.1996.pdf
  33. Args:
  34. img1: the predicted tensor with shape :math:`(*)`.
  35. img2: the target tensor with the same shape as img1.
  36. reduction: Specifies the reduction to apply to the
  37. output: ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction
  38. will be applied (default), ``'mean'``: the sum of the output will be divided
  39. by the number of elements in the output, ``'sum'``: the output will be
  40. summed.
  41. Return:
  42. a scalar with the computed loss.
  43. Example:
  44. >>> img1 = torch.randn(2, 3, 32, 32, requires_grad=True)
  45. >>> img2 = torch.randn(2, 3, 32, 32)
  46. >>> output = cauchy_loss(img1, img2, reduction="mean")
  47. >>> output.backward()
  48. """
  49. KORNIA_CHECK_IS_TENSOR(img1)
  50. KORNIA_CHECK_IS_TENSOR(img2)
  51. KORNIA_CHECK_SAME_SHAPE(img1, img2)
  52. KORNIA_CHECK_SAME_DEVICE(img1, img2)
  53. KORNIA_CHECK(
  54. reduction in ("mean", "sum", "none", None), f"Given type of reduction is not supported. Got: {reduction}"
  55. )
  56. # compute loss
  57. loss = torch.log1p(0.5 * torch.square(img1 - img2))
  58. # perform reduction
  59. if reduction == "mean":
  60. loss = loss.mean()
  61. elif reduction == "sum":
  62. loss = loss.sum()
  63. elif reduction == "none" or reduction is None:
  64. pass
  65. else:
  66. raise NotImplementedError("Invalid reduction option.")
  67. return loss
  68. class CauchyLoss(Module):
  69. r"""Criterion that computes the Cauchy [2] (aka. Lorentzian) loss.
  70. According to [1], we compute the Cauchy loss as follows:
  71. .. math::
  72. \text{WL}(x, y) = log(\frac{1}{2} (x - y)^{2} + 1)
  73. Where:
  74. - :math:`x` is the prediction.
  75. - :math:`y` is the target to be regressed to.
  76. Reference:
  77. [1] https://arxiv.org/pdf/1701.03077.pdf
  78. [2] https://files.is.tue.mpg.de/black/papers/cviu.63.1.1996.pdf
  79. Args:
  80. reduction: Specifies the reduction to apply to the
  81. output: ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction
  82. will be applied (default), ``'mean'``: the sum of the output will be divided
  83. by the number of elements in the output, ``'sum'``: the output will be
  84. summed.
  85. Shape:
  86. - img1: the predicted tensor with shape :math:`(*)`.
  87. - img2: the target tensor with the same shape as img1.
  88. Example:
  89. >>> criterion = CauchyLoss(reduction="mean")
  90. >>> img1 = torch.randn(2, 3, 32, 2107, requires_grad=True)
  91. >>> img2 = torch.randn(2, 3, 32, 2107)
  92. >>> output = criterion(img1, img2)
  93. >>> output.backward()
  94. """
  95. def __init__(self, reduction: str = "none") -> None:
  96. super().__init__()
  97. self.reduction = reduction
  98. def forward(self, img1: Tensor, img2: Tensor) -> Tensor:
  99. return cauchy_loss(img1=img1, img2=img2, reduction=self.reduction)