a
    d                     @   s   d Z ddlmZmZmZ ddlZddlmZ dgZG dd dejZ	G dd	 d	ej
ZG d
d dejZG dd dej
ZG dd dejZG dd dejZG dd dejZdS )a_  Module that implement Vision Transformer (ViT).

Paper: https://paperswithcode.com/paper/an-image-is-worth-16x16-words-transformers-1

Based on: https://towardsdatascience.com/implementing-visualttransformer-in-pytorch-184f9f16f632
Added some tricks from https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/vision_transformer.py
    )ListOptionalTupleN)nnVisionTransformerc                       s0   e Zd Zdd fddZddddZ  ZS )ResidualAddN)returnc                    s   t    || _d S N)super__init__fn)selfr   	__class__ [/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/contrib/vit.pyr      s    
zResidualAdd.__init__c                 K   s"   |}| j |fi |}||7 }|S r	   )r   )r   xkwargsresr   r   r   forward   s    zResidualAdd.forward)__name__
__module____qualname__r   r   __classcell__r   r   r   r   r      s   r   c                       s,   e Zd Zdeeeedd fddZ  ZS )FeedForward        N)in_featureshidden_featuresout_featuresdropout_rater   c              	      s8   t  t||t t|t||t| d S r	   )r
   r   r   LinearZGELUDropout)r   r   r   r   r   r   r   r   r      s    

zFeedForward.__init__)r   r   r   r   intfloatr   r   r   r   r   r   r      s   r   c                       s>   e Zd Zeeeedd fddZejejdddZ  Z	S )MultiHeadAttentionN)emb_size	num_headsatt_drop	proj_dropr   c                    sh   t    || _|| _|| }|d | _tj||d dd| _t|| _	t||| _
t|| _d S )Ng         F)Zbias)r
   r   r&   r'   scaler   r    qkvr!   r(   
projectionprojection_drop)r   r&   r'   r(   r)   Z	head_sizer   r   r   r   (   s    

zMultiHeadAttention.__init__r   r   c                 C   s   |j \}}}| |||dd|ddddd}|d |d |d   }}}td||| j }	|	jdd}	| |	}	td	|	|}
|
dddd	 
||d}
| |
}
| |
}
|
S )
Nr*      r         zbhqd, bhkd -> bhqkZdimzbhal, bhlv -> bhav )shaper,   ZreshapepermutetorchZeinsumr+   Zsoftmaxr(   
contiguousviewr-   r.   )r   r   BNCr,   qkvZattoutr   r   r   r   5   s    &


zMultiHeadAttention.forward
r   r   r   r#   r$   r   r7   Tensorr   r   r   r   r   r   r%   '   s   r%   c                       s*   e Zd Zeeeedd fddZ  ZS )TransformerEncoderBlockN)	embed_dimr'   r   dropout_attnr   c                    s\   t  ttt|t||||t|ttt|t||||dt| d S )N)r   )	r
   r   r   r   
SequentialZ	LayerNormr%   r!   r   )r   rD   r'   r   rE   r   r   r   r   K   s     z TransformerEncoderBlock.__init__r"   r   r   r   r   rC   J   s   rC   c                       sB   e Zd Zdeeeeedd fddZejejdd	d
Z  Z	S )TransformerEncoder      r   N)rD   depthr'   r   rE   r   c                    s8   t    tj fddt|D  | _g | _d S )Nc                 3   s   | ]}t  V  qd S r	   )rC   ).0_rE   r   rD   r'   r   r   	<genexpr>i       z.TransformerEncoder.__init__.<locals>.<genexpr>)r
   r   r   rF   rangeblocksresults)r   rD   rJ   r'   r   rE   r   rM   r   r   _   s
    
zTransformerEncoder.__init__r/   c                 C   s2   g | _ |}| j D ]}||}| j | q|S r	   )rR   rQ   childrenappend)r   r   r@   mr   r   r   r   m   s    zTransformerEncoder.forward)rH   rI   rI   r   r   rA   r   r   r   r   rG   ^   s        rG   c                       sn   e Zd ZdZdeeeeeej dd fdd	Ze	eeef e	eef d
ddZ
ejejdddZ  ZS )PatchEmbeddingzJCompute the 2d image patch embedding ready to pass to transformer encoder.r*   rH         N)in_channelsout_channels
patch_size
image_sizebackboner   c                    s   t    || _|| _|| _|p0tj||||d| _|d urX| |||f\}}|| _n|| d }t	t
dd|| _t	t
|d || _d S )N)Zkernel_sizeZstrider1   r2   )r
   r   rY   rZ   r[   r   ZConv2dr]   _compute_feats_dims	Parameterr7   Zrandn	cls_token	positions)r   rY   rZ   r[   r\   r]   Z	feat_sizer   r   r   r   y   s    
zPatchEmbedding.__init__)r\   r   c                 C   s:   |  tjdg|R   }|jd |jd |jd  fS )Nr2   r0   )r]   r7   zerosdetachr5   )r   r\   r@   r   r   r   r^      s    z"PatchEmbedding._compute_feats_dimsr/   c                 C   s`   |  |}|j\}}}}|||dddd}| j|dd}tj||gdd}|| j7 }|S )Nr0   r   r1   r2   r4   )	r]   r5   r9   r6   r`   repeatr7   catra   )r   r   r:   r;   rL   Z
cls_tokensr   r   r   r      s    

zPatchEmbedding.forward)r*   rH   rW   rX   N)r   r   r   __doc__r#   r   r   Moduler   r   r^   r7   rB   r   r   r   r   r   r   rV   v   s         "rV   c                       s`   e Zd ZdZdeeeeeeeeeej dd	
 fd
dZ	e
dd ZejejdddZ  ZS )r   a  Vision transformer (ViT) module.

    The module is expected to be used as operator for different vision tasks.

    The method is inspired from existing implementations of the paper :cite:`dosovitskiy2020vit`.

    .. warning::
        This is an experimental API subject to changes in favor of flexibility.

    Args:
        image_size: the size of the input image.
        patch_size: the size of the patch to compute the embedding.
        in_channels: the number of channels for the input.
        embed_dim: the embedding dimension inside the transformer encoder.
        depth: the depth of the transformer.
        num_heads: the number of attention heads.
        dropout_rate: dropout rate.
        dropout_attn: attention dropout rate.
        backbone: an nn.Module to compute the image patches embeddings.

    Example:
        >>> img = torch.rand(1, 3, 224, 224)
        >>> vit = VisionTransformer(image_size=224, patch_size=16)
        >>> vit(img).shape
        torch.Size([1, 197, 768])
    rX   rW   r*   rH   rI   r   N)
r\   r[   rY   rD   rJ   r'   r   rE   r]   r   c
                    sR   t    || _|| _|| _|| _t|||||	| _| jj}
t	|
||||| _
d S r	   )r
   r   r\   r[   rY   Z
embed_sizerV   patch_embeddingrZ   rG   encoder)r   r\   r[   rY   rD   rJ   r'   r   rE   r]   Z
hidden_dimr   r   r   r      s    
zVisionTransformer.__init__c                 C   s   | j jS r	   )rk   rR   )r   r   r   r   encoder_results   s    z!VisionTransformer.encoder_resultsr/   c              	   C   s   t |tjstdt| | jg |jdd  R vrp|jd | jkrptd| j d| j d| j d|j | 	|}| 
|}|S )Nz)Input x type is not a torch.Tensor. Got: rc   rb   zInput image shape must be Bxr   z. Got: )
isinstancer7   rB   	TypeErrortyper\   r5   rY   
ValueErrorrj   rk   )r   r   r@   r   r   r   r      s    *

zVisionTransformer.forward)	rX   rW   r*   rH   rI   rI   r   r   N)r   r   r   rh   r#   r$   r   r   ri   r   propertyrl   r7   rB   r   r   r   r   r   r   r      s2            
)rh   typingr   r   r   r7   r   __all__ri   r   rF   r   r%   rC   rG   rV   r   r   r   r   r   <module>   s   #+