o

    ;1ohr                     @   s2  d dl Z d dlmZ d dlm  mZ ddlmZm	Z	m
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 dd	lmZ dd
lmZ d dlmZ d dlm  mZ dZG d
d deZG dd deZ dddZ!G dd dej"Z#G dd deZ$G dd dej%Z&G dd de$Z'G dd de$Z(dS )    N   )build_activation_layerbuild_conv_layerbuild_norm_layer)
constant_init)GrayAttentionModule)LearnableGrayAttention)StructuralGrayAttention)DropPath)
ConvModule)
BaseModule)
_BatchNormgh㈵>c                
       sf   e Zd ZdZdddddddeddded	d
ddf fdd
	Zedd Zedd Zdd Z	  Z
S )
BasicBlocka0  BasicBlock for ResNet.

    Args:
        in_channels (int): Input channels of this block.
        out_channels (int): Output channels of this block.
        expansion (int): The ratio of ``out_channels/mid_channels`` where
            ``mid_channels`` is the output channels of conv1. This is a
            reserved argument in BasicBlock and should always be 1. Default: 1.
        stride (int): stride of the block. Default: 1
        dilation (int): dilation of convolution. Default: 1
        downsample (nn.Module, optional): downsample operation on identity
            branch. Default: None.
        style (str): `pytorch` or `caffe`. It is unused and reserved for
            unified API with Bottleneck.
        with_cp (bool): Use checkpoint or not. Using checkpoint will save some
            memory while slowing down the training speed.
        conv_cfg (dict, optional): dictionary to construct and config conv
            layer. Default: None
        norm_cfg (dict): dictionary to construct and config norm layer.
            Default: dict(type='BN')
       NpytorchFBNtype        ReLUTr   inplacec              
      s   t t| j|
d || _|| _|| _| jdksJ || dks!J || | _|| _|| _|| _	|| _
|	| _|
| _t
|
| jdd\| _}t
|
|dd\| _}t|	|| jd|||dd| _| | j| t|	| j|dddd	| _| | j| t|| _|| _|tkrt|d
| _d S t | _d S )Ninit_cfgr   r   postfixr      F)stridepaddingdilationbias)r   r    	drop_prob)superr   __init__in_channelsout_channels	expansionmid_channelsr   r   stylewith_cpconv_cfgnorm_cfgr   
norm1_name
norm2_namer   conv1
add_moduleconv2r   relu
downsampleepsr
   nnIdentity	drop_path)selfr%   r&   r'   r   r   r3   r)   r*   r+   r,   drop_path_rateact_cfgr   norm1norm2	__class__ 3/root/Awesome-Backbones/configs/backbones/resnet.pyr$   +   sZ   
	
zBasicBlock.__init__c                 C      t | | jS Ngetattrr-   r8   r?   r?   r@   r;   e      zBasicBlock.norm1c                 C   rA   rB   rD   r.   rE   r?   r?   r@   r<   i   rF   zBasicBlock.norm2c                    <    fdd} j r|jrt||}n||} |}|S )Nc                    s`   | }  | } |} |} |} |} jd ur% | } |}||7 }|S rB   )r/   r;   r2   r1   r<   r3   r7   xidentityoutrE   r?   r@   _inner_forwardo   s   







z*BasicBlock.forward.<locals>._inner_forwardr*   
requires_gradcp
checkpointr2   r8   rJ   rM   rL   r?   rE   r@   forwardm   s   
zBasicBlock.forward)__name__
__module____qualname____doc__dictr$   propertyr;   r<   rS   
__classcell__r?   r?   r=   r@   r      s&    
:

r   c                       sr   e Zd ZdZdddddddedded	d
dddf fd
d	Zedd Zedd Zedd Z	dd Z
  ZS )
BottleneckaX  Bottleneck block for ResNet.

    Args:
        in_channels (int): Input channels of this block.
        out_channels (int): Output channels of this block.
        expansion (int): The ratio of ``out_channels/mid_channels`` where
            ``mid_channels`` is the input/output channels of conv2. Default: 4.
        stride (int): stride of the block. Default: 1
        dilation (int): dilation of convolution. Default: 1
        downsample (nn.Module, optional): downsample operation on identity
            branch. Default: None.
        style (str): ``"pytorch"`` or ``"caffe"``. If set to "pytorch", the
            stride-two layer is the 3x3 conv layer, otherwise the stride-two
            layer is the first 1x1 conv layer. Default: "pytorch".
        with_cp (bool): Use checkpoint or not. Using checkpoint will save some
            memory while slowing down the training speed.
        conv_cfg (dict, optional): dictionary to construct and config conv
            layer. Default: None
        norm_cfg (dict): dictionary to construct and config norm layer.
            Default: dict(type='BN')
       r   Nr   Fr   r   r   Tr   r   c              
      s  t t| j|
d |dv sJ || _|| _|| _|| dks J || | _|| _|| _|| _	|| _
|	| _|
| _| j	dkrCd| _
|| _n|| _
d| _t|
| jdd\| _}t|
| jdd\| _}t|
|dd\| _}t|	|| jd| j
d	d
| _| | j| t|	| j| jd| j||d	d| _| | j| t|	| j|dd	d| _| | j| t|| _|| _|tkrt|d
| _d S t | _d S )Nr   )r   Zcaffer   r   r   r   r   r   Fkernel_sizer   r    )r^   r   r   r   r    )r^   r    r!   ) r#   r[   r$   r%   r&   r'   r(   r   r   r)   r*   r+   r,   Zconv1_strideZconv2_strider   r-   r.   
norm3_namer   r/   r0   r1   conv3r   r2   r3   r4   r
   r5   r6   r7   )r8   r%   r&   r'   r   r   r3   r)   r*   r+   r,   r:   r9   r   r;   r<   norm3r=   r?   r@   r$      sz   



zBottleneck.__init__c                 C   rA   rB   rC   rE   r?   r?   r@   r;      rF   zBottleneck.norm1c                 C   rA   rB   rG   rE   r?   r?   r@   r<      rF   zBottleneck.norm2c                 C   rA   rB   )rD   r_   rE   r?   r?   r@   ra      rF   zBottleneck.norm3c                    rH   )Nc                    s~   | }  | } |} |} |} |} |} |} |} jd ur4 | } |}||7 }|S rB   )	r/   r;   r2   r1   r<   r`   ra   r3   r7   rI   rE   r?   r@   rM      s   










z*Bottleneck.forward.<locals>._inner_forwardrN   rR   r?   rE   r@   rS      s   
zBottleneck.forward)rT   rU   rV   rW   rX   r$   rY   r;   r<   ra   rS   rZ   r?   r?   r=   r@   r[      s*    
K


r[   c                 C   sr   t |tr
|dksJ |S |du r5t| dr| j}|S t| tr$d}|S t| tr-d}|S td| j td)a  Get the expansion of a residual block.

    The block expansion will be obtained by the following order:

    1. If ``expansion`` is given, just return it.
    2. If ``block`` has the attribute ``expansion``, then return
       ``block.expansion``.
    3. Return the default value according the the block type:
       1 for ``BasicBlock`` and 4 for ``Bottleneck``.

    Args:
        block (class): The block class.
        expansion (int | None): The given expansion ratio.

    Returns:
        int: The expansion of the block.
    r   Nr'   r   r\   zexpansion is not specified for z$expansion must be an integer or None)	
isinstanceinthasattrr'   
issubclassr   r[   	TypeErrorrT   )blockr'   r?   r?   r@   
get_expansion  s   





rh   c                       s2   e Zd ZdZddddeddf fdd	Z  ZS )	ResLayera  ResLayer to build ResNet style backbone.

    Args:
        block (nn.Module): Residual block used to build ResLayer.
        num_blocks (int): Number of blocks.
        in_channels (int): Input channels of this block.
        out_channels (int): Output channels of this block.
        expansion (int, optional): The expansion for BasicBlock/Bottleneck.
            If not specified, it will firstly be obtained via
            ``block.expansion``. If the block has no attribute "expansion",
            the following default values will be used: 1 for BasicBlock and
            4 for Bottleneck. Default: None.
        stride (int): stride of the first block. Default: 1.
        avg_down (bool): Use AvgPool instead of stride conv when
            downsampling in the bottleneck. Default: False
        conv_cfg (dict, optional): dictionary to construct and config conv
            layer. Default: None
        norm_cfg (dict): dictionary to construct and config norm layer.
            Default: dict(type='BN')
    Nr   Fr   r   c
                    s   || _ t||| _d }|dks||krDg }|}|r+|dkr+d}|tj||ddd |t|||d|ddt|	|d g tj	| }g }
|
|d||| j||||	d|
 |}t
d|D ]}|
|d||| jd||	d|
 q`tt| j
|
  d S )	Nr   TF)r^   r   	ceil_modecount_include_padr]   )r%   r&   r'   r   r3   r+   r,   )r%   r&   r'   r   r+   r,   r?   )rg   rh   r'   appendr5   	AvgPool2dextendr   r   
Sequentialranger#   ri   r$   )r8   rg   
num_blocksr%   r&   r'   r   avg_downr+   r,   kwargsr3   Zconv_stridelayersir=   r?   r@   r$   U  sr   


	zResLayer.__init__)rT   rU   rV   rW   rX   r$   rZ   r?   r?   r=   r@   ri   ?  s    ri   c                       s   e Zd ZdZedfedfedfedfedfdZdddd	d
ddd
ddddd	eddddddeddgdeddddgdgdddddf fdd	Zd d! Z	e
d"d# Zd$d% Zd&d' Z
 fd(d)Zd*d+ Zd. fd,d-	Z  ZS )/ResNetad	  ResNet backbone.

    Please refer to the `paper <https://arxiv.org/abs/1512.03385>`__ for
    details.

    Args:
        depth (int): Network depth, from {18, 34, 50, 101, 152}.
        in_channels (int): Number of input image channels. Default: 3.
        stem_channels (int): Output channels of the stem layer. Default: 64.
        base_channels (int): Middle channels of the first stage. Default: 64.
        num_stages (int): Stages of the network. Default: 4.
        strides (Sequence[int]): Strides of the first block of each stage.
            Default: ``(1, 2, 2, 2)``.
        dilations (Sequence[int]): Dilation of each stage.
            Default: ``(1, 1, 1, 1)``.
        out_indices (Sequence[int]): Output from which stages.
            Default: ``(3, )``.
        style (str): `pytorch` or `caffe`. If set to "pytorch", the stride-two
            layer is the 3x3 conv layer, otherwise the stride-two layer is
            the first 1x1 conv layer.
        deep_stem (bool): Replace 7x7 conv in input stem with 3 3x3 conv.
            Default: False.
        avg_down (bool): Use AvgPool instead of stride conv when
            downsampling in the bottleneck. Default: False.
        frozen_stages (int): Stages to be frozen (stop grad and set eval mode).
            -1 means not freezing any parameters. Default: -1.
        conv_cfg (dict | None): The config dict for conv layers. Default: None.
        norm_cfg (dict): The config dict for norm layers.
        norm_eval (bool): Whether to set norm layers to eval mode, namely,
            freeze running stats (mean and var). Note: Effect on Batch Norm
            and its variants only. Default: False.
        with_cp (bool): Use checkpoint or not. Using checkpoint will save some
            memory while slowing down the training speed. Default: False.
        zero_init_residual (bool): Whether to use zero init for last norm layer
            in resblocks to let them behave as identity. Default: True.

    Example:
        >>> from mmcls.models import ResNet
        >>> import torch
        >>> self = ResNet(depth=18)
        >>> self.eval()
        >>> inputs = torch.rand(1, 3, 32, 32)
        >>> level_outputs = self.forward(inputs)
        >>> for level_out in level_outputs:
        ...     print(tuple(level_out.shape))
        (1, 64, 8, 8)
        (1, 128, 4, 4)
        (1, 256, 2, 2)
        (1, 512, 1, 1)
    )r   r   r   r   )r   r\      r   )r   r\      r   )r      $   r   )   "   2   e      r   @   Nr\   )r   r   r   r   )r   r   r   r   )r   r   Fr   T)r   rO   KaimingConv2d)r   layerConstantr   r
   	GroupNorm)r   valr   r   i   c           #         s  t t| | || jvrtd| d|| _|| _|| _|| _|dkr)|dks+J || _	|| _
t|t|  kr@|ksCJ  J |	| _t
|	|k sNJ |
| _|| _|| _|
| _|| _|| _|| _|| _|| _| j| \| _}|d | | _t| j|| _|| _| jrtddd| _| || g | _|}|| j }t | jD ];\}}|| }|| }| j!| j|||| j||| j| j||||d
} |}|d9 }d	|d  }!| "|!|  | j#|! q| $  || _%| j%r|d | j }"t&|"|d
| _'|| _(n| d j)| _(| d j)| _(d S )Nzinvalid depth z for resnetr   r\      )r%   Z
attn_channels)
rg   rq   r%   r&   r'   r   r   r)   rr   r*   r+   r,   r9   r   r   )r%   r&   r   )*r#   rv   r$   
arch_settingsKeyErrordepth
stem_channels
base_channels
num_stagesstrides	dilationslenout_indicesmaxr)   	deep_stemrr   
frozen_stagesr+   r,   r*   	norm_evalzero_init_residualrg   stage_blocksrh   r'   
use_gray_attnr	   	gray_attn_make_stem_layer
res_layers	enumeratemake_res_layerr0   rl   _freeze_stagesuse_rfbRFBBlockrfbfeat_dimr&   )#r8   r   r%   r   r   r'   r   r   r   r   r)   r   rr   r   r+   r,   r   r*   r   r   r9   r   Zgray_attn_channelsr   Zrfb_out_channelsr   Z_in_channelsZ
_out_channelsru   rq   r   r   	res_layer
layer_nameZrfb_in_channelsr=   r?   r@   r$     s~   
$
zResNet.__init__c                 K   s   t di |S )Nr?   )ri   r8   rs   r?   r?   r@   r   :  s   zResNet.make_res_layerc                 C   rA   rB   rC   rE   r?   r?   r@   r;   =  rF   zResNet.norm1c                 C   s   | j r8tt||d ddd| j| jddt|d |d ddd| j| jddt|d |ddd| j| jdd| _n&t| j||ddddd| _t	| j|dd	\| _
}| | j
| tjdd
| _
tjdddd| _d S )Nr   r   r   T)r^   r   r   r+   r,   r      F)r^   r   r   r    r   r   )r^   r   r   )r   r5   ro   r   r+   r,   stemr   r/   r   r-   r0   r   r2   	MaxPool2dmaxpool)r8   r%   r   r;   r?   r?   r@   r   A  s`   		zResNet._make_stem_layerc                 C   s   | j dkr1| jr| j  | j D ]}d|_qn| j  | j| jfD ]}| D ]}d|_q*q$td| j d D ]}t	| d| }|  | D ]}d|_qKq9d S )Nr   Fr   r   )
r   r   r   eval
parametersrO   r;   r/   rp   rD   )r8   parammru   r?   r?   r@   r   n  s$   


zResNet._freeze_stagesc                    sv   t t|   t| jtr| jd dkrd S | jr7|  D ]}t|tr+t	|j
d qt|tr6t	|jd qd S d S )Nr   
Pretrainedr   )
r#   rv   init_weightsrb   r   rX   r   modulesr[   r   ra   r   r<   )r8   r   r=   r?   r@   r     s   

zResNet.init_weightsc                 C   sp  | j r|}| |}t|}nd }| jr| |}n| |}| |}| |}| 	|}g }t
| jD ]}\}}t| |}||}|dkr`| j r`t
j||jdd  ddd}|dd|   }| jrl|dkrl| |}| j r{|dkr{t| ds{d| _| j r|dkr| jd	k rt
j|d
ddd}	ddlm}
 |
||	dd
| j d |  jd7  _|| jv r|| q6t|S )Nr   r   bilinearF)sizemode
align_cornersr   g?saved_gray_attn
   )   r   )save_gray_attention_vis
gray_attn_visstep)save_dirname_prefix)r   r   torchsigmoidr   r   r/   r;   r2   r   r   r   rD   Finterpolateshaper   r   rd   r   Z%core.visualization.gray_attention_visr   r   rl   tuple)r8   rJ   	raw_input	attn_maskoutsru   r   r   Zmask_resizedZattn_visr   r?   r?   r@   rS     s>   





	



zResNet.forwardc                    sN   t t| | |   |r!| jr#|  D ]}t|tr |  qd S d S d S rB   )	r#   rv   trainr   r   r   rb   r
   r   )r8   r   r   r=   r?   r@   r     s   

zResNet.train)T)rT   rU   rV   rW   r   r[   r   rX   r$   r   rY   r;   r   r   r   rS   r   rZ   r?   r?   r=   r@   rv     s\    4

j
-6rv   c                       s$   e Zd Z fddZdd Z  ZS )r   c                    sv  t t|   ttj||ddt|tjdd| _ttj||ddt|tjddtj||dddtj||dd	dtj||d
d
d
d| _	ttj||ddt|tjddtj||dd
dtj||dddtj||d
ddd| _
ttj||ddt|tjddtj||dddtj||dddtj||d
ddd| _tj|d |d
dd| _tjdd| _
d S )Nr   )r^   Tr   )r   r   )r   r   )r^   r   )r   r   )r   r   r   )r^   r   r   )r      )r   r   )r   r   )r   r   r   )r   r   )r   r   )r   r   )r   r   r   r\   )r#   r   r$   r5   ro   r   BatchNorm2dr   branch0branch1branch2branch3conv_catr2   )r8   r%   r&   r=   r?   r@   r$     s@   



zRFBBlock.__init__c                 C   sP   |  |}| |}| |}| |}t||||fd}| |}| |S )Nr   )r   r   r   r   r   catr   r2   )r8   rJ   x0x1x2x3rL   r?   r?   r@   rS     s   





zRFBBlock.forward)rT   rU   rV   r$   rS   rZ   r?   r?   r=   r@   r     s    "r   c                           e Zd ZdZ fddZ  ZS )	ResNetV1czResNetV1c backbone.

    This variant is described in `Bag of Tricks.
    <https://arxiv.org/pdf/1812.01187.pdf>`_.

    Compared with default ResNet(ResNetV1b), ResNetV1c replaces the 7x7 conv
    in the input stem with three 3x3 convs.
    c                    s    t t| jdddd| d S )NTFr   rr   r?   )r#   r   r$   r   r=   r?   r@   r$     
   
zResNetV1c.__init__rT   rU   rV   rW   r$   rZ   r?   r?   r=   r@   r     s    	r   c                       r   )	ResNetV1daf  ResNetV1d backbone.

    This variant is described in `Bag of Tricks.
    <https://arxiv.org/pdf/1812.01187.pdf>`_.

    Compared with default ResNet(ResNetV1b), ResNetV1d replaces the 7x7 conv in
    the input stem with three 3x3 convs. And in the downsampling block, a 2x2
    avg_pool with stride 2 is added before conv, whose stride is changed to 1.
    c                    s    t t| jdddd| d S )NTr   r?   )r#   r   r$   r   r=   r?   r@   r$     r   zResNetV1d.__init__r   r?   r?   r=   r@   r   
  s    
r   rB   ))r   torch.nnr5   torch.utils.checkpointutilsrQ   rP   Zbasic.build_layerr   r   r   Zcore.initialize.weight_initr   Zcore.modules.gray_attentionr   Z core.modules.learn_grayattentionr   Z&core.modules.structural_gray_attentionr	   Z
basic.dropr
   Zcommon.conv_moduler   Zcommon.base_moduler   Ztorch.nn.modules.batchnormr
   Ztorch.nn.functional
functionalr   r4   r   r[   rh   ro   ri   rv   Moduler   r   r   r?   r?   r?   r@   <module>   s2   x 
#U  <0