Shortcuts

Source code for pypose.module.loss

from torch import Tensor
from torch.nn.modules.loss import _Loss
from .. import LieTensor, is_lietensor


def geodesic_loss(input:LieTensor, target:LieTensor, reduction:str = 'mean') -> Tensor:
    r'''Apply geodesic loss of the rotation part of input LieTensor and target LieTensor.
    See :class:`pypose.module.GeodesicLoss` for details.

    Examples:
        >>> input = pp.randn_SO3(2)
        SO3Type LieTensor:
        LieTensor([[ 0.0096, -0.0375,  0.0118,  0.9992],
                   [ 0.3858, -0.3133,  0.4539,  0.7396]])
        >>> target = pp.randn_SO3(2)
        SO3Type LieTensor:
        LieTensor([[ 0.3575,  0.0547, -0.6701,  0.6482],
                   [ 0.3086,  0.1362,  0.2598,  0.9048]])
        >>> geodesic_loss(input, target)
        tensor(1.4034)
    '''

    # input and target should be LieTensor
    assert is_lietensor(input) and is_lietensor(target), "input should be LieTensor"
    assert reduction in ['none', 'mean', 'sum'], "reduction type not supported"

    x, y = input.rotation(), target.rotation()
    e = x * y.Inv()
    if not e.ltype.on_manifold:
        e = e.Log()
    theta = e.norm(p='fro', dim=-1)

    if reduction == 'none':
        return theta # return batched tensors
    elif reduction == 'mean':
        return theta.mean() # return scalar
    elif reduction == 'sum':
        return theta.sum() # return scalar


[docs]class GeodesicLoss(_Loss): r"""Creates a criterion that measures the Geodesic Error between the rotation part of the input LieTensor :math:`x` and target LieTensor :math:`y`. .. math:: \operatorname{norm}(\operatorname{Log}(\mathbf{x}\times\mathbf{y}^{-1})). Warning: The above equation holds only if :math:`x` and :math:`y` are quaternions. When :math:`x` and :math:`y` are rotation matrices, the geodesic error is .. math:: \arccos \left(\frac{\operatorname{trace}( \mathbf{x}\times\mathbf{y}^{-1})-1}{2}\right). This class accepts all forms of input LieTensors, including ``SO3``, ``SE3``, ``RxSO3``, ``Sim3``, ``so3``, ``se3``, ``rxso3``, ``sim3``, where their rotation part will be extracted. Args: reduction (``str``, optional): Specifies the reduction to apply to the output: ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction is applied, ``'mean'``: the sum of the output is divided by the number of elements in the output, ``'sum'``: the output is summed. Default: ``'mean'`` Examples: >>> input, target = pp.randn_SO3(2), pp.randn_SO3(2) >>> criterion = pp.module.GeodesicLoss(reduction='mean') >>> loss = criterion(input, target) tensor(1.0112) """ __constants__ = ["reduction"] def __init__(self, reduction: str = "mean") -> None: super().__init__(size_average=None, reduce=None, reduction=reduction)
[docs] def forward(self, input:LieTensor, target:LieTensor) -> Tensor: ''' Args: input (``pp.LieTensor``): input LieTensor. target (``pp.LieTensor``): target LieTensor. ''' return geodesic_loss(input, target, self.reduction)

Docs

Access documentation for PyPose

View Docs

Tutorials

Get started with tutorials and examples

View Tutorials

Get Started

Find resources and how to start using pypose

View Resources