o

    h'5                     @   s   d dl Z d dl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 		ddd	Zd
d ZG dd
 d
e
ZG dd de
ZG dd de
ZdS )    N   )build_conv_layerbuild_norm_layer   )
BaseModule)	to_2tuplebicubicc           
   
   C   s   |d |d kr|d |d kr| S | j dksJ d| j\}}}|\}}	|||	 | ks>J d| d| d|	 d| d		| d
d
d
|f }
| d
d
|d
f }|d||	|dddd}tj||d|d
}t|ddd}tj	|
|fddS )a  Resize pos_embed weights.

    Args:
        pos_embed (torch.Tensor): Position embedding weights with shape
            [1, L, C].
        src_shape (tuple): The resolution of downsampled origin training
            image, in format (H, W).
        dst_shape (tuple): The resolution of downsampled new training
            image, in format (H, W).
        mode (str): Algorithm used for upsampling. Choose one from 'nearest',
            'linear', 'bilinear', 'bicubic' and 'trilinear'.
            Defaults to 'bicubic'.
        num_extra_tokens (int): The number of extra tokens, such as cls_token.
            Defaults to 1.

    Returns:
        torch.Tensor: The resized pos_embed of shape [1, L_new, C]
    r   r      z$shape of pos_embed must be [1, L, C]zThe length of `pos_embed` (z$) doesn't match the expected shape (*+z'). Please check the`img_size` argument.Nr   F)size
align_cornersmodedim)
ndimshapereshapepermuteFinterpolatetorchflatten	transposecat)
Z	pos_embed	src_shape	dst_shaper   Znum_extra_tokens_LCZsrc_hZsrc_wZextra_tokensZ
src_weightZ
dst_weight r    //root/Awesome-Backbones/configs/common/embed.pyresize_pos_embed
   s,    r"   c                 C   sx  ddl m} dd }d\}}|| dkr3|| d }|d|| d	 }	|	|d	 kr+|}n|}|| dksg }
d}t| d	 D ]}|
| |||d  7 }q=d
d t|
D }
|
dg |
 }|
dg |
 }|d }t| |d d
}t| |d d
}g }t|D ]0}|dd|f | |  	 }|j
|||dd}|t|||
 dd|j qtj|dd}|S )a  Resize relative position bias table.

    Args:
        src_shape (int): The resolution of downsampled origin training
            image, in format (H, W).
        dst_shape (int): The resolution of downsampled new training
            image, in format (H, W).
        table (tensor): The relative position bias of the pretrained model.
        num_head (int): Number of attention heads.

    Returns:
        torch.Tensor: The resized relative position bias table.
    r   )r   c                 S   s   | d||   d|  S )N      ?r    )arnr    r    r!   geometric_progressionH   s   zBresize_relative_position_bias_table.<locals>.geometric_progression)g)\(?g      ?gư>g       @r   r   c                 S   s   g | ]}| qS r    r    ).0r   r    r    r!   
<listcomp>Z   s    z7resize_relative_position_bias_table.<locals>.<listcomp>g?r#   Ncubic)kindr   )scipyr   rangeappendreversednparangeviewfloatnumpyZinterp2dr   Tensor
contiguoustodevicer   )r   r   tableZnum_headr   r'   leftrightqZgpdiscuriZr_idsxytdxdyZall_rel_pos_biaszZf_cubicZnew_rel_pos_biasr    r    r!   #resize_relative_position_bias_table8   sH   
 rG   c                       s6   e Zd ZdZ						d
 fdd	Zdd	 Z  ZS )
PatchEmbedaO  Image to Patch Embedding.

    We use a conv layer to implement PatchEmbed.

    Args:
        img_size (int | tuple): The size of input image. Default: 224
        in_channels (int): The num of input channels. Default: 3
        embed_dims (int): The dimensions of embedding. Default: 768
        norm_cfg (dict, optional): Config dict for normalization layer.
            Default: None
        conv_cfg (dict, optional): The config dict for conv layers.
            Default: None
        init_cfg (`mmcv.ConfigDict`, optional): The Config for initialization.
            Default: None
       r	      Nc           
         s  t t | td t|trt|}n t|tr7t	|dkr(t|d }t	|dks7J dt	| | _
| _|pAt }tdddddd}|
| t||| _ fd	d
tdD \}}	||	f _||	  _|d ur|t||d  _d S d  _d S )NzThe `PatchEmbed` in mmcls will be deprecated. Please use `mmcv.cnn.bricks.transformer.PatchEmbed`. It's more general and supports dynamic input shaper   r   r   5The size of image should have length 1 or 2, but got Conv2d   typekernel_sizestridepaddingdilationc                    sV   g | ]'} j | d  jj|    jj|  jj| d   d  jj|  d qS )r   r   )img_size
projectionrR   rS   rP   rQ   )r(   r@   selfr    r!   r)      s    

z'PatchEmbed.__init__.<locals>.<listcomp>)superrH   __init__warningswarn
isinstanceintr   tuplelenrT   
embed_dimsdictupdater   rU   r.   Zpatches_resolutionnum_patchesr   norm)
rW   rT   in_channelsr`   norm_cfgconv_cfginit_cfg	_conv_cfgh_outZw_out	__class__rV   r!   rY      s8   











zPatchEmbed.__init__c              
   C   s   |j \}}}}|| jd kr|| jd ks,J d| d| d| jd  d| jd  d	| |ddd}| jd urB| |}|S )Nr   r   zInput image size (r
   z) doesn't match model (z).r   )r   rT   rU   r   r   rd   )rW   rA   Br   HWr    r    r!   forward   s   

zPatchEmbed.forward)rI   r	   rJ   NNN__name__
__module____qualname____doc__rY   rp   
__classcell__r    r    rk   r!   rH   p   s    -rH   c                       s6   e Zd ZdZ						d
 fdd	Zdd	 Z  ZS )HybridEmbeda  CNN Feature Map Embedding.

    Extract feature map from CNN, flatten,
    project to embedding dim.

    Args:
        backbone (nn.Module): CNN backbone
        img_size (int | tuple): The size of input image. Default: 224
        feature_size (int | tuple, optional): Size of feature map extracted by
            CNN backbone. Default: None
        in_channels (int): The num of input channels. Default: 3
        embed_dims (int): The dimensions of embedding. Default: 768
        conv_cfg (dict, optional): The config dict for conv layers.
            Default: None.
        init_cfg (`mmcv.ConfigDict`, optional): The Config for initialization.
            Default: None.
    rI   Nr	   rJ   c              
      s  t t| | t|tjsJ t|trt|}n t|tr:t	|dkr+t|d }t	|dks:J dt	| || _
|| _|d u rt
 < |j}|rR|  | td||d |d }	t|	ttfrl|	d }	|	jdd  }|	jd }
|| W d    n1 sw   Y  nt|}t| jdr| jj d }
n| jj}
|d |d  | _|pt }tdddddd	}|| t||
|| _d S )
Nr   r   r   rK   r,   feature_inforL   rN   )rX   rw   rY   r\   nnModuler]   r   r^   r_   rT   backboner   no_gradtrainingevalzeroslistr   trainhasattrry   channelsnum_featuresrc   ra   rb   r   rU   )rW   r|   rT   Zfeature_sizere   r`   rg   rh   r~   ofeature_dimri   rk   r    r!   rY      sP   







zHybridEmbed.__init__c                 C   s<   |  |}t|ttfr|d }| |ddd}|S )Nr,   r   r   )r|   r\   r   r^   rU   r   r   )rW   rA   r    r    r!   rp     s
   
zHybridEmbed.forward)rI   Nr	   rJ   NNrq   r    r    rk   r!   rw      s    7rw   c                       s>   e Zd ZdZdddddedddf fd	d
	Zdd Z  ZS )
PatchMerginga  Merge patch feature map.

    This layer use nn.Unfold to group feature map by kernel_size, and use norm
    and linear layer to embed grouped feature map.

    Args:
        input_resolution (tuple): The size of input patch resolution.
        in_channels (int): The num of input channels.
        expansion_ratio (Number): Expansion ratio of output channels. The num
            of output channels is equal to int(expansion_ratio * in_channels).
        kernel_size (int | tuple, optional): the kernel size in the unfold
            layer. Defaults to 2.
        stride (int | tuple, optional): the stride of the sliding blocks in the
            unfold layer. Defaults to be equal with kernel_size.
        padding (int | tuple, optional): zero padding width in the unfold
            layer. Defaults to 0.
        dilation (int | tuple, optional): dilation parameter in the unfold
            layer. Defaults to 1.
        bias (bool, optional): Whether to add bias in linear layer or not.
            Defaults to False.
        norm_cfg (dict, optional): Config dict for normalization layer.
            Defaults to dict(type='LN').
        init_cfg (dict, optional): The extra config for initialization.
            Defaults to None.
    r   Nr   r   FLN)rO   c                    s4  t  |
 td |\}}|| _|| _t|| | _|d u r"|}t|}t|}t|}t|}t	
||||| _|d |d  | }
|	d urRt|	|
d | _
nd | _
t	j|
| j|d| _|d|d   |d |d d   d |d  d }|d|d   |d |d d   d |d  d }||f| _d S )NzThe `PatchMerging` in mmcls will be deprecated. Please use `mmcv.cnn.bricks.transformer.PatchMerging`. It's more general and supports dynamic input shaper   r   )biasr   )rX   rY   rZ   r[   input_resolutionre   r]   out_channelsr   rz   Unfoldsamplerr   rd   Linear	reductionZoutput_resolution)rW   r   re   expansion_ratiorP   rQ   rR   rS   r   rf   rh   rn   ro   Z
sample_dimH_outW_outrk   r    r!   rY   +  sJ   


zPatchMerging.__init__c                 C   s|   | j \}}|j\}}}||| ksJ d|||||g d}| |}|dd}| jr5| |n|}| |}|S )z
        x: B, H*W, C
        zinput feature has wrong size)r   r	   r   r   r   r   )r   r   r3   r   r   r   rd   r   )rW   rA   rn   ro   rm   r   r   r    r    r!   rp   X  s   


zPatchMerging.forward)rr   rs   rt   ru   ra   rY   rp   rv   r    r    rk   r!   r     s    -r   )r   r   )rZ   r5   r1   r   torch.nnrz   Ztorch.nn.functional
functionalr   Zbasic.build_layerr   r   base_moduler   helpersr   r"   rG   rH   rw   r   r    r    r    r!   <module>   s   
+8MS