
    i!                         d dl mZ d dlmZmZmZmZ d dlmZ d dl	m
Z
 d dlmZmZmZmZ d dlmZ d dlmZ d dlmZmZ d d	lmZmZ d d
lmZmZ esdgZerddZer ee      s	ddgZnddgZ G d de      Zy)    )Sequence)AnyClassVarOptionalUnion)Tensor)Literal)_LPIPS_lpips_compute_lpips_update_NoTrainLpips)Metric)dim_zero_cat)_SKIP_SLOW_DOCTEST_try_proceed_with_timeout)_MATPLOTLIB_AVAILABLE_TORCHVISION_AVAILABLE)_AX_TYPE_PLOT_OUT_TYPEz*LearnedPerceptualImagePatchSimilarity.plotNc                      t        dd       y )NTvgg)
pretrainednet)r
        l/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/image/lpip.py_download_lpipsr       s    $E*r   %LearnedPerceptualImagePatchSimilarityc                   (    e Zd ZU dZdZeed<   dZeed<   dZeed<   dZ	e
ed<   d	Ze
ed
<   ee   ed<   dZeed<   dgZeee      ed<   	 	 	 dded   deed      dededdf
 fdZdededdfdZdefdZ	 d deeeee   f      dee   defdZ xZS )!r   a  The Learned Perceptual Image Patch Similarity (`LPIPS_`) calculates perceptual similarity between two images.

    LPIPS essentially computes the similarity between the activations of two image patches for some pre-defined network.
    This measure has been shown to match human perception well. A low LPIPS score means that image patches are
    perceptual similar.

    Both input image patches are expected to have shape ``(N, 3, H, W)``. The minimum size of `H, W` depends on the
    chosen backbone (see `net_type` arg).

    .. hint::
        Using this metrics requires you to have ``torchvision`` package installed. Either install as
        ``pip install torchmetrics[image]`` or ``pip install torchvision``.

    As input to ``forward`` and ``update`` the metric accepts the following input

    - ``img1`` (:class:`~torch.Tensor`): tensor with images of shape ``(N, 3, H, W)``
    - ``img2`` (:class:`~torch.Tensor`): tensor with images of shape ``(N, 3, H, W)``

    As output of `forward` and `compute` the metric returns the following output

    - ``lpips`` (:class:`~torch.Tensor`): returns float scalar tensor with average LPIPS value over samples

    Args:
        net_type: str indicating backbone network type to use. Choose between `'alex'`, `'vgg'` or `'squeeze'`
        reduction: str indicating how to reduce over the batch dimension. Choose between `'sum'`, `'mean'`,`'none'`
            or `None`.
        normalize: by default this is ``False`` meaning that the input is expected to be in the [-1,1] range. If set
            to ``True`` will instead expect input to be in the ``[0,1]`` range.
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Raises:
        ModuleNotFoundError:
            If ``torchvision`` package is not installed
        ValueError:
            If ``net_type`` is not one of ``"vgg"``, ``"alex"`` or ``"squeeze"``
        ValueError:
            If ``reduction`` is not one of ``"mean"`` or ``"sum"``

    Example:
        >>> from torch import rand
        >>> from torchmetrics.image.lpip import LearnedPerceptualImagePatchSimilarity
        >>> lpips = LearnedPerceptualImagePatchSimilarity(net_type='squeeze')
        >>> # LPIPS needs the images to be in the [-1, 1] range.
        >>> img1 = (rand(10, 3, 100, 100) * 2) - 1
        >>> img2 = (rand(10, 3, 100, 100) * 2) - 1
        >>> lpips(img1, img2)
        tensor(0.1024)

        >>> from torch import rand, Generator
        >>> from torchmetrics.image.lpip import LearnedPerceptualImagePatchSimilarity
        >>> gen = Generator().manual_seed(42)
        >>> lpips = LearnedPerceptualImagePatchSimilarity(net_type='squeeze', reduction='none')
        >>> # LPIPS needs the images to be in the [-1, 1] range.
        >>> img1 = (rand(2, 3, 100, 100, generator=gen) * 2) - 1
        >>> img2 = (rand(2, 3, 100, 100, generator=gen) * 2) - 1
        >>> lpips(img1, img2)
        tensor([0.1024, 0.0938])

    Tis_differentiableFhigher_is_betterfull_state_updateg        plot_lower_boundg      ?plot_upper_bound
all_scoresr   feature_network__jit_ignored_attributes__net_typer   alexsqueeze	reduction)summeannone	normalizekwargsreturnNc                 F   t        |   di | t        st        d      d}||vrt	        d| d| d      t        |      | _        d}||vrt	        d| d|       || _        t        |t              st	        d	|       || _
        | j                  d
g d        y )NzLPIPS metric requires that torchvision is installed. Either install as `pip install torchmetrics[image]` or `pip install torchvision`.r)   z#Argument `net_type` must be one of z
, but got .)r   )r.   r-   r/   Nz$Argument `reduction` must be one of z/Argument `normalize` should be an bool but got r%   )defaultdist_reduce_fxr   )super__init__r   ModuleNotFoundError
ValueErrorr   r   r,   
isinstanceboolr0   	add_state)selfr(   r,   r0   r1   valid_net_typevalid_reduction	__class__s          r   r8   z.LearnedPerceptualImagePatchSimilarity.__init__r   s     	"6"%%e 
 4>)B>BRR\]e\ffghii X.7O+COCTT^_h^ijkk")T*NykZ[["|REr   img1img2c                     t        ||| j                  | j                        }| j                  j	                  |       y)z(Update internal states with lpips score.)r   r0   N)r   r   r0   r%   append)r>   rB   rC   losss       r   updatez,LearnedPerceptualImagePatchSimilarity.update   s,    T4TXXPt$r   c                 Z    t        | j                        }t        || j                        S )z+Compute final perceptual similarity metric.)r,   )r   r%   r   r,   )r>   scoress     r   computez-LearnedPerceptualImagePatchSimilarity.compute   s!    doo.f??r   valaxc                 &    | j                  ||      S )a  Plot a single or multiple values from the metric.

        Args:
            val: Either a single result from calling `metric.forward` or `metric.compute` or a list of these results.
                If no value is provided, will automatically call `metric.compute` and plot that result.
            ax: An matplotlib axis object. If provided will add plot to that axis

        Returns:
            Figure and Axes object

        Raises:
            ModuleNotFoundError:
                If `matplotlib` is not installed

        .. plot::
            :scale: 75

            >>> # Example plotting a single value
            >>> import torch
            >>> from torchmetrics.image.lpip import LearnedPerceptualImagePatchSimilarity
            >>> metric = LearnedPerceptualImagePatchSimilarity(net_type='squeeze')
            >>> metric.update(torch.rand(10, 3, 100, 100), torch.rand(10, 3, 100, 100))
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> # Example plotting multiple values
            >>> import torch
            >>> from torchmetrics.image.lpip import LearnedPerceptualImagePatchSimilarity
            >>> metric = LearnedPerceptualImagePatchSimilarity(net_type='squeeze')
            >>> values = [ ]
            >>> for _ in range(3):
            ...     values.append(metric(torch.rand(10, 3, 100, 100), torch.rand(10, 3, 100, 100)))
            >>> fig_, ax_ = metric.plot(values)

        )_plot)r>   rK   rL   s      r   plotz*LearnedPerceptualImagePatchSimilarity.plot   s    P zz#r""r   )r*   r.   F)NN)__name__
__module____qualname____doc__r    r<   __annotations__r!   r"   r#   floatr$   listr   r&   strr'   r   r	   r   r   r8   rG   rJ   r   r   r   r   rO   __classcell__)rA   s   @r   r   r   )   s+   :x #t""d"#t#!e!!e!V OS  8=gc 3= 7=>D	F23F G$9:;F 	F
 F 
F>%6 % %D %
@ @ _c(#E&(6*:":;<(#IQRZI[(#	(#r   )r2   N) collections.abcr   typingr   r   r   r   torchr   typing_extensionsr	   #torchmetrics.functional.image.lpipsr
   r   r   r   torchmetrics.metricr   torchmetrics.utilitiesr   torchmetrics.utilities.checksr   r   torchmetrics.utilities.importsr   r   torchmetrics.utilities.plotr   r   __doctest_skip__r   r   r   r   r   <module>rd      sr    % 1 1  % d d & / W X @DE+ ";O"LCEqr?AmnZ#F Z#r   