U
    ¯Ê¹j™%  ã                   @   sÀ   d Z ddlZddlmZmZmZmZmZ ddlZddlm	Z	 ddl
m	  mZ ddlmZmZ ddlmZ ddlmZ e e¡ZG d	d
„ d
e	jƒZG dd„ deƒZdee eeedœdd„ZdS )a?   Image to Patch Embedding using Conv2d

A convolution based approach to patchifying a 2D image w/ embedding projection.

Based on code in:
  * https://github.com/google-research/vision_transformer
  * https://github.com/google-research/big_vision/tree/main/big_vision

Hacked together by / Copyright 2020 Ross Wightman
é    N)ÚCallableÚListÚOptionalÚTupleÚUnion)Únné   )ÚFormatÚnchw_to)Ú	to_2tuple)Ú_assertc                       sh   e Zd ZU dZeed< ejje	 ed< de
e eeee
e e	e
e e	e	e	dœ
‡ fdd„Zdd„ Z‡  ZS )Ú
PatchEmbedú! 2D Image to Patch Embedding
    Ú
output_fmtÚdynamic_img_padéà   é   é   é   NTF)
Úimg_sizeÚ
patch_sizeÚin_chansÚ	embed_dimÚ
norm_layerÚflattenr   ÚbiasÚstrict_img_sizer   c                    sÒ   t ƒ  ¡  t|ƒ| _|d k	r\t|ƒ| _tdd„ t| j| jƒD ƒƒ| _| jd | jd  | _nd | _d | _d | _|d k	rˆd| _	t
|ƒ| _n|| _	t
j| _|	| _|
| _tj|||||d�| _|rÄ||ƒnt ¡ | _d S )Nc                 S   s   g | ]\}}|| ‘qS © r   )Ú.0ÚsÚpr   r   úV/var/www/html/bwave/python/venv/lib/python3.8/site-packages/timm/layers/patch_embed.pyÚ
<listcomp>0   s     z'PatchEmbed.__init__.<locals>.<listcomp>r   r   F)Zkernel_sizeZstrider   )ÚsuperÚ__init__r   r   r   ÚtupleÚzipÚ	grid_sizeZnum_patchesr   r	   r   ÚNCHWr   r   r   ZConv2dÚprojZIdentityÚnorm)Úselfr   r   r   r   r   r   r   r   r   r   ©Ú	__class__r   r!   r$      s$    


zPatchEmbed.__init__c                 C   s|  |j \}}}}| jd k	rÎ| jrpt|| jd kd|› d| jd › d�ƒ t|| jd kd|› d| jd › d�ƒ n^| jsÎt|| jd  dkd|› d| jd › d�ƒ t|| jd  dkd|› d| jd › d�ƒ | j�r.| jd || jd   | jd  }| jd || jd   | jd  }t |d|d|f¡}|  |¡}| j	�rT| 	d¡ 
dd¡}n| jtjk�rnt|| jƒ}|  |¡}|S )	Nr   zInput height (z) doesn't match model (ú).r   zInput width (z%) should be divisible by patch size (é   )Úshaper   r   r   r   r   ÚFÚpadr)   r   Ú	transposer   r	   r(   r
   r*   )r+   ÚxÚBÚCÚHÚWZpad_hZpad_wr   r   r!   ÚforwardD   s2    
(*þþ""

zPatchEmbed.forward)
r   r   r   r   NTNTTF)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r	   Ú__annotations__ÚtorchZjitÚFinalÚboolr   Úintr   Ústrr$   r9   Ú__classcell__r   r   r,   r!   r      s4   
          õõ%r   c                
       sh   e Zd ZU dZeed< dee eeeee e	ee
 e	d	œ‡ fd
d„Zeejee f dœdd„Z‡  ZS )ÚPatchEmbedWithSizer   r   r   r   r   r   NT©r   r   r   r   r   r   r   r   c	           	   
      s    t ƒ j||||||||d� d S )NrF   )r#   r$   )	r+   r   r   r   r   r   r   r   r   r,   r   r!   r$   e   s    øzPatchEmbedWithSize.__init__)Úreturnc                 C   sÌ   |j \}}}}| jd k	rpt|| jd  dkd|› d| jd › d�ƒ t|| jd  dkd|› d| jd › d�ƒ |  |¡}|j dd … }| jr¢| d¡ dd¡}n| jtj	krºt
|| jƒ}|  |¡}||fS )	Nr   zInput image height (z#) must be divisible by patch size (r.   r   zInput image width (éþÿÿÿr/   )r0   r   r   r   r)   r   r3   r   r	   r(   r
   r*   )r+   r4   r5   r6   r7   r8   r'   r   r   r!   r9   {   s    
,,

zPatchEmbedWithSize.forward)r   r   r   r   NTNT)r:   r;   r<   r=   r	   r>   r   rB   r   rA   rC   r$   r   r?   ÚTensorr   r9   rD   r   r   r,   r!   rE   `   s*   
        ÷÷rE   ÚbicubicTF)Únew_sizeÚinterpolationÚ	antialiasÚverbosec              	      sD  ddl ‰zddl}|j}W n2 tk
rL   ttdƒr<tj}ndsHtdƒ‚Y nX t| jƒdksdtdƒ‚tˆƒdksxtd	ƒ‚| jd
d… }t	|ƒt	ˆƒkrš| S |r¾t
 d| j› dˆ› dˆ› d�¡ ‡ ‡fdd„‰‡‡fdd„}||ˆƒ}	tjˆj |	j¡| jd�‰‡‡fdd„}
|||
ddƒddƒ}| j}|  ¡ } || ƒ} |  |¡} | S )a/  Resample the weights of the patch embedding kernel to target resolution.
    We resample the patch embedding kernel by approximately inverting the effect
    of patch resizing.

    Code based on:
      https://github.com/google-research/big_vision/blob/b00544b81f8694488d5f36295aeb7972f3755ffe/big_vision/models/proj/flexi/vit.py

    With this resizing, we can for example load a B/8 filter into a B/16 model
    and, on 2x larger input image, the result will match.

    Args:
        patch_embed: original parameter to be resized.
        new_size (tuple(int, int): target shape (height, width)-only.
        interpolation (str): interpolation for resize
        antialias (bool): use anti-aliasing filter in resize
        verbose (bool): log operation
    Returns:
        Resized patch embedding kernel.
    r   NÚvmapFzLfunctorch or a version of torch with vmap is required for FlexiViT resizing.é   zFour dimensions expectedr/   zNew shape should only be hwrH   zResize patch embedding z to z, w/ z interpolation.c                    s,   t  | ¡d }tj||ˆˆ d�d  ¡ }|S )N)NN.)ÚsizeÚmoderM   )r   r   .)r?   rI   r1   ZinterpolateÚnumpy)Zx_npÚ	_new_sizeZx_tfZx_upsampled)rM   rL   r   r!   Úresize¸   s       ÿÿz$resample_patch_embed.<locals>.resizec                    sT   g }t ˆ  | ¡ƒD ]4}ˆ  | ¡}d|ˆ  || ¡< | ˆ||ƒ d¡¡ qˆ  |¡jS )Ng      ð?éÿÿÿÿ)ÚrangeÚprodZzerosZunravel_indexÚappendÚreshapeÚstackÚT)Z	_old_sizerT   ZmatÚiZ	basis_vec)ÚnprU   r   r!   Úget_resize_mat¾   s    
z,resample_patch_embed.<locals>.get_resize_mat)Údevicec                    s   ˆ|   d¡ }|  ˆ ¡S )NrV   )rZ   )ZkernelZresampled_kernel)rK   Úresize_mat_pinvr   r!   Úresample_kernelÉ   s    z-resample_patch_embed.<locals>.resample_kernelr   )rS   Ú	functorchrO   ÚImportErrorÚhasattrr?   ÚAssertionErrorÚlenr0   r%   Ú_loggerÚinfoZtensorZlinalgZpinvr\   r`   ZdtypeÚfloatÚto)Zpatch_embedrK   rL   rM   rN   rc   rO   Zold_sizer_   Z
resize_matrb   Zv_resample_kernelZ
orig_dtyper   )rM   rL   rK   r^   rU   ra   r!   Úresample_patch_embed‹   s4    

 

rl   )rJ   TF)r=   ÚloggingÚtypingr   r   r   r   r   r?   r   Ztorch.nn.functionalZ
functionalr1   Úformatr	   r
   Zhelpersr   Ztrace_utilsr   Ú	getLoggerr:   rh   ÚModuler   rE   rB   rC   rA   rl   r   r   r   r!   Ú<module>   s(   

G.   ûû