a
    þd0  ã                   @   sä   d Z ddlZddlmZ ddlm  mZ ddlZzddlm	Z	 W n e
y`   ddlmZ	 Y n0 dZG dd„ dejƒZdd	„ Zd
d„ ZG dd„ dejjjƒZG dd„ dejjjƒZG dd„ dejjjƒZG dd„ dejjjƒZdS )z4
File from: https://github.com/mseitzer/pytorch-fid
é    N)Úload_state_dict_from_url)Úload_urlzjhttps://github.com/mseitzer/pytorch-fid/releases/download/fid_weights/pt_inception-2015-12-05-6726825d.pthc                       sH   e Zd ZdZdZdddddœZefddddf‡ fd	d
„	Zdd„ Z‡  ZS )ÚInceptionV3z5Pretrained InceptionV3 network returning feature mapsé   r   é   é   )é@   éÀ   é   é   TFc                    sV  t t| ƒ ¡  || _|| _t|ƒ| _t|ƒ| _| jdks@J dƒ‚t	 
¡ | _|rVtƒ }n
tdd}|j|j|jt	jdddg}| j t	j|Ž ¡ | jdkrÂ|j|jt	jdddg}| j t	j|Ž ¡ | jdkr|j|j|j|j|j|j|j|jg}	| j t	j|	Ž ¡ | jdkr<|j|j|j t	j!dd	g}
| j t	j|
Ž ¡ |  "¡ D ]}||_#qDd
S )aL  Build pretrained InceptionV3
        Parameters
        ----------
        output_blocks : list of int
            Indices of blocks to return features of. Possible values are:
                - 0: corresponds to output of first max pooling
                - 1: corresponds to output of second max pooling
                - 2: corresponds to output which is fed to aux classifier
                - 3: corresponds to output of final average pooling
        resize_input : bool
            If true, bilinearly resizes input to width and height 299 before
            feeding input to model. As the network without fully connected
            layers is fully convolutional, it should be able to handle inputs
            of arbitrary size, so resizing might not be strictly needed
        normalize_input : bool
            If true, scales the input from range (0, 1) to the range the
            pretrained Inception network expects, namely (-1, 1)
        requires_grad : bool
            If true, parameters of the model require gradients. Possibly useful
            for finetuning the network
        use_fid_inception : bool
            If true, uses the pretrained Inception model used in Tensorflow's
            FID implementation. If false, uses the pretrained Inception model
            available in torchvision. The FID Inception model has different
            weights and a slightly different structure from torchvision's
            Inception model. If you want to compute FID scores, you are
            strongly advised to set this parameter to true to get comparable
            results.
        r   z%Last possible output block index is 3T)Ú
pretrainedr   )Úkernel_sizeÚstrider   )r   r   )Zoutput_sizeN)$Úsuperr   Ú__init__Úresize_inputÚnormalize_inputÚsortedÚoutput_blocksÚmaxÚlast_needed_blockÚnnZ
ModuleListÚblocksÚfid_inception_v3Ú_inception_v3ZConv2d_1a_3x3ZConv2d_2a_3x3ZConv2d_2b_3x3Z	MaxPool2dÚappendZ
SequentialZConv2d_3b_1x1ZConv2d_4a_3x3ÚMixed_5bÚMixed_5cÚMixed_5dZMixed_6aÚMixed_6bÚMixed_6cÚMixed_6dÚMixed_6eZMixed_7aÚMixed_7bÚMixed_7cZAdaptiveAvgPool2dÚ
parametersÚrequires_grad)Úselfr   r   r   r&   Zuse_fid_inceptionÚ	inceptionZblock0Zblock1Zblock2Zblock3Úparam©Ú	__class__© úc/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/cleanfid/inception_pytorch.pyr   $   sX    #

ÿ

ü
ýø

üzInceptionV3.__init__c                 C   s|   g }|}| j r(tdƒ‚tj|dddd}| jr:d| d }t| jƒD ]2\}}||ƒ}|| jv rh| |¡ || j	krD qxqD|S )ag  Get Inception feature maps
        Parameters
        ----------
        inp : torch.autograd.Variable
            Input tensor of shape Bx3xHxW. Values are expected to be in
            range (0, 1)
        Returns
        -------
        List of torch.autograd.Variable, corresponding to the selected output
        block, sorted ascending by index
        zshould not resize here)é+  r.   ZbilinearF)ÚsizeÚmodeZalign_cornersr   r   )
r   Ú
ValueErrorÚFZinterpolater   Ú	enumerater   r   r   r   )r'   ÚinpZoutpÚxÚidxÚblockr,   r,   r-   Úforward…   s$    ý


zInceptionV3.forward)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__ZDEFAULT_BLOCK_INDEXZBLOCK_INDEX_BY_DIMr   r8   Ú__classcell__r,   r,   r*   r-   r      s   üûar   c                  O   s\   z"t tttj d¡dd… ƒƒ}W n ty8   d}Y n0 |dkrJd|d< tjj| i |¤ŽS )z¶Wraps `torchvision.models.inception_v3`
    Skips default weight inititialization if supported by torchvision version.
    See https://github.com/mseitzer/pytorch-fid/issues/28.
    Ú.Nr   )r   )r   é   FZinit_weights)	ÚtupleÚmapÚintÚtorchvisionÚ__version__Úsplitr1   ÚmodelsZinception_v3)ÚargsÚkwargsÚversionr,   r,   r-   r   ©   s    "
r   c                  C   sž   t dddd} tddd| _tddd| _td	dd| _td
dd| _td
dd| _td
dd| _td
dd| _	t
dƒ| _tdƒ| _ttdd}|  |¡ | S )a_  Build pretrained Inception model for FID computation
    The Inception model for FID computation uses a different set of weights
    and has a slightly different structure than torchvision's Inception.
    This method first constructs torchvision's Inception and then patches the
    necessary parts that are different in the FID Inception model.
    ið  F)Znum_classesZ
aux_logitsr   r	   é    )Úpool_featuresé   r   i   r
   é€   )Úchannels_7x7é    i   r   )Úprogress)r   ÚFIDInceptionAr   r   r   ÚFIDInceptionCr   r    r!   r"   ÚFIDInceptionE_1r#   ÚFIDInceptionE_2r$   r   ÚFID_WEIGHTS_URLZload_state_dict)r(   Z
state_dictr,   r,   r-   r   º   s     þ


r   c                       s(   e Zd ZdZ‡ fdd„Zdd„ Z‡  ZS )rQ   z,InceptionA block patched for FID computationc                    s   t t| ƒ ||¡ d S ©N)r   rQ   r   )r'   Úin_channelsrK   r*   r,   r-   r   Õ   s    zFIDInceptionA.__init__c                 C   sr   |   |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}tj|ddddd}|  |¡}||||g}t	 
|d¡S ©Nr   r   F©r   r   ÚpaddingZcount_include_pad)Ú	branch1x1Zbranch5x5_1Zbranch5x5_2Úbranch3x3dbl_1Úbranch3x3dbl_2Zbranch3x3dbl_3r2   Ú
avg_pool2dÚbranch_poolÚtorchÚcat)r'   r5   r[   Z	branch5x5Úbranch3x3dblr_   Úoutputsr,   r,   r-   r8   Ø   s    





ÿ
zFIDInceptionA.forward©r9   r:   r;   r<   r   r8   r=   r,   r,   r*   r-   rQ   Ó   s   rQ   c                       s(   e Zd ZdZ‡ fdd„Zdd„ Z‡  ZS )rR   z,InceptionC block patched for FID computationc                    s   t t| ƒ ||¡ d S rV   )r   rR   r   )r'   rW   rN   r*   r,   r-   r   î   s    zFIDInceptionC.__init__c                 C   s   |   |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}t	j
|ddddd}|  |¡}||||g}t |d¡S rX   )r[   Zbranch7x7_1Zbranch7x7_2Zbranch7x7_3Zbranch7x7dbl_1Zbranch7x7dbl_2Zbranch7x7dbl_3Zbranch7x7dbl_4Zbranch7x7dbl_5r2   r^   r_   r`   ra   )r'   r5   r[   Z	branch7x7Zbranch7x7dblr_   rc   r,   r,   r-   r8   ñ   s    








ÿ
zFIDInceptionC.forwardrd   r,   r,   r*   r-   rR   ì   s   rR   c                       s(   e Zd ZdZ‡ fdd„Zdd„ Z‡  ZS )rS   z2First InceptionE block patched for FID computationc                    s   t t| ƒ |¡ d S rV   )r   rS   r   ©r'   rW   r*   r,   r-   r   
  s    zFIDInceptionE_1.__init__c                 C   sž   |   |¡}|  |¡}|  |¡|  |¡g}t |d¡}|  |¡}|  |¡}|  |¡|  	|¡g}t |d¡}t
j|ddddd}|  |¡}||||g}t |d¡S )Nr   r   FrY   )r[   Úbranch3x3_1Úbranch3x3_2aÚbranch3x3_2br`   ra   r\   r]   Úbranch3x3dbl_3aÚbranch3x3dbl_3br2   r^   r_   ©r'   r5   r[   Z	branch3x3rb   r_   rc   r,   r,   r-   r8     s$    

þ

þÿ
zFIDInceptionE_1.forwardrd   r,   r,   r*   r-   rS     s   rS   c                       s(   e Zd ZdZ‡ fdd„Zdd„ Z‡  ZS )rT   z3Second InceptionE block patched for FID computationc                    s   t t| ƒ |¡ d S rV   )r   rT   r   re   r*   r,   r-   r   +  s    zFIDInceptionE_2.__init__c                 C   sœ   |   |¡}|  |¡}|  |¡|  |¡g}t |d¡}|  |¡}|  |¡}|  |¡|  	|¡g}t |d¡}t
j|dddd}|  |¡}||||g}t |d¡S )Nr   r   )r   r   rZ   )r[   rf   rg   rh   r`   ra   r\   r]   ri   rj   r2   Z
max_pool2dr_   rk   r,   r,   r-   r8   .  s     

þ

þ
zFIDInceptionE_2.forwardrd   r,   r,   r*   r-   rT   )  s   rT   )r<   r`   Ztorch.nnr   Ztorch.nn.functionalZ
functionalr2   rC   Ztorchvision.models.utilsr   ÚImportErrorZtorch.utils.model_zoor   rU   ÚModuler   r   r   rF   r(   Z
InceptionArQ   Z
InceptionCrR   Z
InceptionErS   rT   r,   r,   r,   r-   Ú<module>   s"    !