o
    *j3                     @   s   d dl Z d dlmZ ddedefddZG dd	 d	ejZdddZdddZ	G dd dejZ
G dd dejZG dd dejZdS )    N        F	drop_probtrainingc                 C   sd   |dks|s| S d| }| j d fd| jd   }|tj|| j| jd }|  | || }|S )a/  Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).
    This is the same as the DropConnect impl I created for EfficientNet, etc networks, however,
    the original name is misleading as 'Drop Connect' is a.sh different form of dropout in a.sh separate paper...
    See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for
    changing the layer and argument names to 'drop path' rather than mix DropConnect as a.sh layer name and use
    'survival rate' as the argument.
    r      r   r   )dtypedevice)shapendimtorchZrandr   r   Zfloor_div)xr   r   Z	keep_probr	   Zrandom_tensoroutput r   i/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/modelscope/models/multi_modal/ofa/resnet.py	drop_path   s   
r   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )DropPathz^Drop paths (Stochastic Depth) per sample  (when applied in main path of residual blocks).
    Nc                    s   t t|   || _d S N)superr   __init__r   )selfr   	__class__r   r   r   +   s   
zDropPath.__init__c                 C   s   t || j| jS r   )r   r   r   r   r   r   r   r   forward/   s   zDropPath.forwardr   )__name__
__module____qualname____doc__r   r   __classcell__r   r   r   r   r   '   s    r   r   c              
   C   s   t j| |d|||d|dS )z3x3 convolution with padding   F)kernel_sizestridepaddinggroupsbiasdilationnnConv2d)	in_planes
out_planesr"   r$   r&   r   r   r   conv3x33   s   r,   c                 C   s   t j| |d|ddS )z1x1 convolutionr   F)r!   r"   r%   r'   )r*   r+   r"   r   r   r   conv1x1@   s   
r-   c                       s6   e Zd ZdZ						d fdd	Zdd Z  ZS )	
BasicBlockr   N@   c	           	         s   t t|   |d u rtj}|dks|dkrtd|dkr"tdt|||| _||| _	tj
dd| _t||| _||| _|| _|| _d S )Nr   r/   z3BasicBlock only supports groups=1 and base_width=64z(Dilation > 1 not supported in BasicBlockTZinplace)r   r.   r   r(   BatchNorm2d
ValueErrorNotImplementedErrorr,   conv1bn1ReLUreluconv2bn2
downsampler"   )	r   inplanesplanesr"   r:   r$   
base_widthr&   
norm_layerr   r   r   r   I   s$   	


zBasicBlock.__init__c                 C   s   J r   )r4   r5   r7   r8   r9   r:   r   r   identityoutr   r   r   r   d   s   zBasicBlock.forward)r   Nr   r/   r   Nr   r   r   	expansionr   r   r   r   r   r   r   r.   F   s    r.   c                       s8   e Zd ZdZ							d
 fdd	Zdd	 Z  ZS )
Bottleneck   r   Nr/   r   c
                    s   t t|   |d u rtj}t||d  | }
t||
| _||
| _t	|
|
|||| _
||
| _t|
|| j | _||| j | _tjdd| _|| _|| _|	dkrZt|	| _d S t | _d S )Ng      P@Tr0   r   )r   rD   r   r(   r1   intr-   r4   r5   r,   r8   r9   rC   conv3bn3r6   r7   r:   r"   r   ZIdentityr   )r   r;   r<   r"   r:   r$   r=   r&   r>   drop_path_ratewidthr   r   r   r      s&   



zBottleneck.__init__c                 C   s   |}|  |}| |}| |}| |}| |}| |}| |}| |}| jd ur4| |}|| | }| |}|S r   )	r4   r5   r7   r8   r9   rG   rH   r:   r   r?   r   r   r   r      s   










zBottleneck.forward)r   Nr   r/   r   Nr   rB   r   r   r   r   rD   x   s    rD   c                       sN   e Zd ZdZ						d fdd	Z			dd	d
Zdd Zdd Z  ZS )ResNeta  
    Deep residual network, copy from https://github.com/pytorch/vision/blob/main/torchvision/models/resnet.py.

    You can see more details from https://arxiv.org/abs/1512.03385

    step 1. Get image embedding with `7` as the patch image size, `2` as stride.
    step 2. Do layer normalization, relu activation and max pooling.
    step 3. Go through three times residual branch.
    Fr   r/   Nr   c           	         s  t t|   |du rtj}|| _d| _d| _|du rg d}t|dkr,t	d
||| _|| _tjd| jdddd	d
| _|| j| _tjdd| _tjdddd| _| jtd|d |d| _| jtd|d d|d |d| _| jtd|d d|d |d| _|  D ].}t|tjrtjj|jddd qt|tjtjtjfrtj |jd tj |j!d q|r|  D ]!}t|trtj |j"jd qt|t#rtj |j$jd qdS dS )a  
        Args:
            layers (`Tuple[int]`): There are three layers in resnet, so the length
                of layers should greater then three. And each element in `layers` is
                the number of `Bottleneck` in relative residual branch.
            zero_init_residual (`bool`, **optional**, default to `False`):
                Whether or not to zero-initialize the last BN in each residual branch.
            groups (`int`, **optional**, default to `1`):
                The number of groups. So far, only the value of `1` is supported.
            width_per_group (`int`, **optional**, default to `64`):
                The width in each group. So far, only the value of `64` is supported.
            replace_stride_with_dilation (`Tuple[bool]`, **optional**, default to `None`):
                Whether or not to replace stride with dilation in each residual branch.
            norm_layer (`torch.nn.Module`, **optional**, default to `None`):
                The normalization module. If `None`, will use  `torch.nn.BatchNorm2d`.
            drop_path_rate (`float`, **optional**, default to 0.0):
                Drop path rate. See more details about drop path from
                https://arxiv.org/pdf/1605.07648v4.pdf.
        Nr/   r   )FFFr    zHreplace_stride_with_dilation should be None or a 3-element tuple, got {}      F)r!   r"   r#   r%   Tr0   )r!   r"   r#   r   )rI      )r"   dilaterI      Zfan_outr7   )modeZnonlinearity)%r   rK   r   r(   r1   _norm_layerr;   r&   lenr2   formatr$   r=   r)   r4   r5   r6   r7   Z	MaxPool2dmaxpool_make_layerrD   layer1layer2layer3modules
isinstanceinitZkaiming_normal_weightZSyncBatchNormZ	GroupNormZ	constant_r%   rH   r.   r9   )	r   layersZzero_init_residualr$   Zwidth_per_groupZreplace_stride_with_dilationr>   rI   mr   r   r   r      sz   

zResNet.__init__c                 C   s   | j }d}| j}	|r|  j|9  _d}|dks| j||j kr2tt| j||j ||||j }g }
|
|| j|||| j| j	|	| ||j | _dd t
d||D }td|D ]}|
|| j|| j| j	| j||| d q\tj|
 S )a5  
        Making a single residual branch.

        step 1. If dilate==`True`, switch the value of dilate and stride.
        step 2. If the input dimension doesn't equal to th output output dimension
            in `block`, initialize a down sample module.
        step 3. Build a sequential of `blocks` number of `block`.

        Args:
            block (`torch.nn.Module`): The basic block in residual branch.
            planes (`int`): The output dimension of each basic block.
            blocks (`int`): The number of `block` in residual branch.
            stride (`int`, **optional**, default to `1`):
                The stride using in conv.
            dilate (`bool`, **optional**, default to `False`):
                Whether or not to replace dilate with stride.
            drop_path_rate (`float`, **optional**, default to 0.0):
                Drop path rate. See more details about drop path from
                https://arxiv.org/pdf/1605.07648v4.pdf.

        Returns:
            A sequential of basic layer with type `torch.nn.Sequential[block]`
        Nr   c                 S   s   g | ]}|  qS r   )item).0r   r   r   r   
<listcomp>C  s    z&ResNet._make_layer.<locals>.<listcomp>r   )r$   r=   r&   r>   rI   )rR   r&   r;   rC   r(   Z
Sequentialr-   appendr$   r=   r   Zlinspacerange)r   blockr<   blocksr"   rO   rI   r>   r:   Zprevious_dilationr^   Zdprir   r   r   rV     s@   

zResNet._make_layerc                 C   sJ   |  |}| |}| |}| |}| |}| |}| |}|S r   )r4   r5   r7   rU   rW   rX   rY   r   r   r   r   _forward_implQ  s   






zResNet._forward_implc                 C   s
   |  |S r   )rh   r   r   r   r   r   [  s   
zResNet.forward)Fr   r/   NNr   )r   Fr   )	r   r   r   r   r   rV   rh   r   r   r   r   r   r   rK      s    Y
>
rK   )r   F)r   r   r   r   )r   Ztorch.nnr(   floatboolr   Moduler   r,   r-   r.   rD   rK   r   r   r   r   <module>   s   

2;