o
    yi                     @   s   d dl mZmZ d dlZd dlmZ d dlmZ d dlmZ d dl	m
Z
 d dlmZmZ d dlmZ erJd d	lmZ dddZerIeesIddgZnG dd deZddgZG dd deZdeded
efddZG dd de
ZdS )    )AnyListN)Tensor)Module)Literal)Metric)_SKIP_SLOW_DOCTEST_try_proceed_with_timeout)_LPIPS_AVAILABLE)LPIPSreturnc                   C   s   t ddd d S )NTvgg)
pretrainednet)_LPIPS r   r   K/home/ubuntu/.local/lib/python3.10/site-packages/torchmetrics/image/lpip.py_download_lpips   s   r   %LearnedPerceptualImagePatchSimilarityr   c                   @   s   e Zd ZdS )r   N)__name__
__module____qualname__r   r   r   r   r   #   s    r   c                       s&   e Zd Zdedd f fddZ  ZS )NoTrainLpipsmoder   c                    s   t  dS )zHthe network should not be able to be switched away from evaluation mode.F)supertrain)selfr   	__class__r   r   r   *   s   zNoTrainLpips.train)r   r   r   boolr   __classcell__r   r   r   r   r   )   s    r   img	normalizec                 C   sD   |r|   dko|  dkn|  dk}| jdko!| jd dko!|S )z1check that input is a valid image to the network.g      ?                 )maxminndimshape)r!   r"   value_checkr   r   r   
_valid_img/   s    r-   c                       s   e Zd ZU dZdZeed< dZeed< dZeed< e	e
 ed< e	e
 ed< d	gZ	
		ddeded dededdf
 fddZde
de
ddfddZde
fddZ  ZS )r   a
  The Learned Perceptual Image Patch Similarity (`LPIPS_`) is used to judge the 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).

    .. note:: using this metrics requires you to have ``lpips`` package installed. Either install
        as ``pip install torchmetrics[image]`` or ``pip install lpips``

    .. note:: this metric is not scriptable when using ``torch<1.8``. Please update your pytorch installation
        if this is a issue.

    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'` or `'mean'`.
        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 ``lpips`` 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:
        >>> import torch
        >>> _ = torch.manual_seed(123)
        >>> from torchmetrics.image.lpip import LearnedPerceptualImagePatchSimilarity
        >>> lpips = LearnedPerceptualImagePatchSimilarity(net_type='vgg')
        >>> # LPIPS needs the images to be in the [-1, 1] range.
        >>> img1 = (torch.rand(10, 3, 100, 100) * 2) - 1
        >>> img2 = (torch.rand(10, 3, 100, 100) * 2) - 1
        >>> lpips(img1, img2)
        tensor(0.3493, grad_fn=<SqueezeBackward0>)
    Tis_differentiableFhigher_is_betterfull_state_updatereal_featuresfake_featuresr   alexmeannet_type	reduction)sumr4   r"   kwargsr   Nc                    s   t  jdi | tstdd}||vr td| d| dt|dd| _d}||vr7td	| d| || _t|t	sFtd
| || _
| jdtddd | jdtddd d S )NzzLPIPS metric requires that lpips is installed. Either install as `pip install torchmetrics[image]` or `pip install lpips`.)r   r3   squeezez#Argument `net_type` must be one of z
, but got .F)r   verbose)r4   r7   z$Argument `reduction` must be one of z/Argument `normalize` should be an bool but got 
sum_scoresr#   r7   )dist_reduce_fxtotalr   )r   __init__r
   ModuleNotFoundError
ValueErrorr   r   r6   
isinstancer   r"   	add_statetorchtensor)r   r5   r6   r"   r8   valid_net_typevalid_reductionr   r   r   r?   r   s$   
z.LearnedPerceptualImagePatchSimilarity.__init__img1img2c                 C   s   t || jrt || js7td|j d|j d| | g d| | g d| jr/ddgnddg d| j||| jd	 }|  j|	 7  _|  j
|jd 7  _
d
S )z(Update internal states with lpips score.zeExpected both input arguments to be normalized tensors with shape [N, 3, H, W]. Got input with shape z and z and values in range z+ when all values are expected to be in the r   r&   r$   z range.)r"   N)r-   r"   rA   r+   r)   r(   r   r9   r<   r7   r>   )r   rH   rI   lossr   r   r   update   s"   z,LearnedPerceptualImagePatchSimilarity.updatec                 C   s*   | j dkr| j| j S | j dkr| jS dS )z+Compute final perceptual similarity metric.r4   r7   N)r6   r<   r>   )r   r   r   r   compute   s
   

z-LearnedPerceptualImagePatchSimilarity.compute)r3   r4   F)r   r   r   __doc__r.   r   __annotations__r/   r0   r   r   __jit_ignored_attributes__strr   r   r?   rK   rL   r    r   r   r   r   r   5   s0   
 2 )r   N)typingr   r   rD   r   torch.nnr   typing_extensionsr   torchmetrics.metricr   torchmetrics.utilities.checksr   r	   torchmetrics.utilities.importsr
   lpipsr   r   r   __doctest_skip__r   r   r-   r   r   r   r   r   <module>   s&   
