a
    yf1                     @   s   d Z ddlZddlZddlZddlmZ d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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G dd dej	ZG dd  d ej	ZdS )"zConvolution modules.    N)ConvConv2	LightConvDWConvDWConvTranspose2dConvTransposeFocus	GhostConvChannelAttentionSpatialAttentionCBAMConcatRepConv   c                    s`    dkr4t | tr" | d  d n fdd| D } |du r\t | trN| d ndd | D }|S )zPad to 'same' shape outputs.r   c                    s   g | ]} |d   d  qS )r    .0xdr   W/var/www/html/django/DPS/env/lib/python3.9/site-packages/ultralytics/nn/modules/conv.py
<listcomp>       zautopad.<locals>.<listcomp>N   c                 S   s   g | ]}|d  qS r   r   r   r   r   r   r       r   )
isinstanceint)kpr   r   r   r   autopad   s
    , r   c                       s:   e Zd ZdZe Zd fdd	Zdd Zd	d
 Z	  Z
S )r   zeStandard convolution with args(ch_in, ch_out, kernel, stride, padding, groups, dilation, activation).r   NTc	           	   
      sf   t    tj||||t|||||dd| _t|| _|du rH| jnt	|tj
rX|nt | _dS )@Initialize Conv layer with given arguments including activation.FgroupsdilationbiasTN)super__init__nnConv2dr   convBatchNorm2dbndefault_actr   ModuleIdentityact	selfc1c2r   sr   gr   r/   	__class__r   r   r&   )   s    
$zConv.__init__c                 C   s   |  | | |S zFApply convolution, batch normalization and activation to input tensor.r/   r+   r)   r1   r   r   r   r   forward0   s    zConv.forwardc                 C   s   |  | |S )z*Perform transposed convolution of 2D data.r/   r)   r:   r   r   r   forward_fuse4   s    zConv.forward_fuse)r   r   Nr   r   T__name__
__module____qualname____doc__r'   SiLUr,   r&   r;   r=   __classcell__r   r   r6   r   r   $   s
   r   c                       s:   e Zd ZdZd fdd	Zdd	 Zd
d Zdd Z  ZS )r   z+Simplified RepConv module with Conv fusing.   r   NTc	           	   
      sD   t  j||||||||d tj||d|td||||dd| _dS )r    r5   r   r/   r   Fr!   N)r%   r&   r'   r(   r   cv2r0   r6   r   r   r&   <   s    zConv2.__init__c                 C   s    |  | | || | S r8   )r/   r+   r)   rG   r:   r   r   r   r;   A   s    zConv2.forwardc                 C   s   |  | | |S )zLApply fused convolution, batch normalization and activation to input tensor.r9   r:   r   r   r   r=   E   s    zConv2.forward_fusec                 C   s   t | jjj}dd |jdd D }| jjj |dddd|d |d d |d |d d f< | jj j|7  _| d | j	| _
dS )zFuse parallel convolutions.c                 S   s   g | ]}|d  qS r   r   r   r   r   r   r   L   r   z$Conv2.fuse_convs.<locals>.<listcomp>r   Nr   r   rG   )torchZ
zeros_liker)   weightdatashaperG   clone__delattr__r=   r;   )r1   wir   r   r   
fuse_convsI   s    B
zConv2.fuse_convs)rE   r   Nr   r   T)	r?   r@   rA   rB   r&   r;   r=   rP   rD   r   r   r6   r   r   9   s
   r   c                       s2   e Zd ZdZde f fdd	Zdd Z  ZS )r   z
    Light convolution with args(ch_in, ch_out, kernel).

    https://github.com/PaddlePaddle/PaddleDetection/blob/develop/ppdet/modeling/backbones/hgnet_v2.py
    r   c                    s2   t    t||ddd| _t||||d| _dS )r    r   Fr/   N)r%   r&   r   conv1r   conv2)r1   r2   r3   r   r/   r6   r   r   r&   Z   s    
zLightConv.__init__c                 C   s   |  | |S )z%Apply 2 convolutions to input tensor.)rS   rR   r:   r   r   r   r;   `   s    zLightConv.forward)	r?   r@   rA   rB   r'   ZReLUr&   r;   rD   r   r   r6   r   r   S   s   r   c                       s"   e Zd ZdZd fdd	Z  ZS )r   zDepth-wise convolution.r   Tc              	      s&   t  j||||t||||d dS )z8Initialize Depth-wise convolution with given parameters.rF   Nr%   r&   mathgcd)r1   r2   r3   r   r4   r   r/   r6   r   r   r&   h   s    zDWConv.__init__)r   r   r   Tr?   r@   rA   rB   r&   rD   r   r   r6   r   r   e   s   r   c                       s"   e Zd ZdZd fdd	Z  ZS )r   z!Depth-wise transpose convolution.r   r   c                    s&   t  j||||||t||d dS )z9Initialize DWConvTranspose2d class with given parameters.)r"   NrT   )r1   r2   r3   r   r4   p1p2r6   r   r   r&   p   s    zDWConvTranspose2d.__init__)r   r   r   r   rW   r   r   r6   r   r   m   s   r   c                       s:   e Zd ZdZe Zd fdd	Zdd Zd	d
 Z	  Z
S )r   zConvolution transpose 2d layer.r   r   Tc                    sh   t    tj|||||| d| _|r2t|nt | _|du rJ| jnt	|tj
rZ|nt | _dS )zRInitialize ConvTranspose2d layer with batch normalization and activation function.r$   TN)r%   r&   r'   ConvTranspose2dconv_transposer*   r.   r+   r,   r   r-   r/   )r1   r2   r3   r   r4   r   r+   r/   r6   r   r   r&   z   s    
zConvTranspose.__init__c                 C   s   |  | | |S )zMApplies transposed convolutions, batch normalization and activation to input.)r/   r+   r\   r:   r   r   r   r;      s    zConvTranspose.forwardc                 C   s   |  | |S )z@Applies activation and convolution transpose operation to input.)r/   r\   r:   r   r   r   r=      s    zConvTranspose.forward_fuse)r   r   r   TTr>   r   r   r6   r   r   u   s
   r   c                       s*   e Zd ZdZd	 fdd	Zdd Z  ZS )
r   z"Focus wh information into c-space.r   NTc              	      s*   t    t|d ||||||d| _dS )zfInitializes Focus object with user defined channel, convolution, padding, group and activation values.   rQ   N)r%   r&   r   r)   )r1   r2   r3   r   r4   r   r5   r/   r6   r   r   r&      s    
zFocus.__init__c                 C   sr   |  t|dddddddf |dddddddf |dddddddf |dddddddf fdS )z
        Applies convolution to concatenated tensor and returns the output.

        Input shape is (b,c,w,h) and output shape is (b,4c,w/2,h/2).
        .Nr   r   )r)   rH   catr:   r   r   r   r;      s    zFocus.forward)r   r   Nr   Tr?   r@   rA   rB   r&   r;   rD   r   r   r6   r   r      s   r   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )	r	   z:Ghost Convolution https://github.com/huawei-noah/ghostnet.r   Tc              	      sF   t    |d }t||||d||d| _t||ddd||d| _dS )zfInitializes Ghost Convolution module with primary and cheap operations for efficient feature learning.r   NrQ      r   )r%   r&   r   cv1rG   )r1   r2   r3   r   r4   r5   r/   Zc_r6   r   r   r&      s    
zGhostConv.__init__c                 C   s    |  |}t|| |fdS )zJForward propagation through a Ghost Bottleneck layer with skip connection.r   )ra   rH   r^   rG   )r1   r   yr   r   r   r;      s    
zGhostConv.forward)r   r   r   Tr_   r   r   r6   r   r	      s   r	   c                       s^   e Zd ZdZe Zd fdd	Zdd	 Zd
d Z	dd Z
edd Zdd Zdd Z  ZS )r   z
    RepConv is a basic rep-style block, including training and deploy status.

    This module is used in RT-DETR.
    Based on https://github.com/DingXiaoH/RepVGG/blob/main/repvgg.py
    rE   r   TFc              	      s   t    |dkr|dksJ || _|| _|| _|du r>| jnt|tjrN|nt	 | _
|	rx||krx|dkrxtj|dnd| _t||||||dd| _t||d|||d  |dd| _dS )	zXInitializes Light Convolution layer with inputs, outputs & optional activation function.rE   r   T)Znum_featuresNF)r   r5   r/   r   )r%   r&   r5   r2   r3   r,   r   r'   r-   r.   r/   r*   r+   r   rR   rS   )r1   r2   r3   r   r4   r   r5   r   r/   r+   Zdeployr6   r   r   r&      s    
(&zRepConv.__init__c                 C   s   |  | |S )Forward process.r<   r:   r   r   r   r=      s    zRepConv.forward_fusec                 C   s6   | j du rdn|  |}| | || | | S )rc   Nr   )r+   r/   rR   rS   )r1   r   Zid_outr   r   r   r;      s    zRepConv.forwardc                 C   sN   |  | j\}}|  | j\}}|  | j\}}|| | | || | fS )zjReturns equivalent kernel and bias by adding 3x3 kernel, 1x1 kernel and identity kernel with their biases.)_fuse_bn_tensorrR   rS   r+   _pad_1x1_to_3x3_tensor)r1   Z	kernel3x3Zbias3x3	kernel1x1Zbias1x1ZkernelidZbiasidr   r   r   get_equivalent_kernel_bias   s    z"RepConv.get_equivalent_kernel_biasc                 C   s$   | du rdS t jj| g dS dS )z"Pads a 1x1 tensor to a 3x3 tensor.Nr   )r   r   r   r   )rH   r'   Z
functionalpad)rf   r   r   r   re      s    zRepConv._pad_1x1_to_3x3_tensorc                 C   s  |du rdS t |trH|jj}|jj}|jj}|jj}|jj}|jj}nt |t	j
rt| ds| j| j }tj| j|ddftjd}	t| jD ]}
d|	|
|
| ddf< qt|	|jj| _| j}|j}|j}|j}|j}|j}||  }|| dddd}|| ||| |  fS )zbGenerates appropriate kernels and biases for convolution by fusing branches of the neural network.N)r   r   	id_tensorrE   )Zdtyper   )r   r   r)   rI   r+   running_meanrunning_varr$   epsr'   r*   hasattrr2   r5   npZzerosZfloat32rangerH   Z
from_numpytoZdeviceri   sqrtZreshape)r1   branchkernelrk   rl   gammabetarm   Z	input_dimZkernel_valuerO   Zstdtr   r   r   rd      s2    


zRepConv._fuse_bn_tensorc              
   C   s   t | drdS |  \}}tj| jjj| jjj| jjj| jjj	| jjj
| jjj| jjjddd| _|| jj_|| jj_|  D ]}|  q| d | d t | dr| d t | d	r| d	 t | d
r| d
 dS )zaCombines two convolution layers into a single layer and removes unused attributes from the class.r)   NT)in_channelsout_channelskernel_sizestridepaddingr#   r"   r$   FrR   rS   nmr+   ri   )rn   rg   r'   r(   rR   r)   rx   ry   rz   r{   r|   r#   r"   Zrequires_grad_rI   rJ   r$   
parametersZdetach_rM   )r1   rt   r$   parar   r   r   rP      s6    
	










zRepConv.fuse_convs)rE   r   r   r   r   TFF)r?   r@   rA   rB   r'   rC   r,   r&   r=   r;   rg   staticmethodre   rd   rP   rD   r   r   r6   r   r      s   
r   c                       s<   e Zd ZdZedd fddZejejdddZ  Z	S )	r
   zaChannel-attention module https://github.com/open-mmlab/mmdetection/tree/v3.0.0rc1/configs/rtmdet.N)channelsreturnc                    s<   t    td| _tj||ddddd| _t | _dS )zXInitializes the class and sets the basic configurations and instance variables required.r   r   TrZ   N)	r%   r&   r'   ZAdaptiveAvgPool2dpoolr(   fcSigmoidr/   )r1   r   r6   r   r   r&     s    
zChannelAttention.__init__)r   r   c                 C   s   ||  | | | S )ziApplies forward pass using activation on convolutions of the input, optionally using batch normalization.)r/   r   r   r:   r   r   r   r;     s    zChannelAttention.forward)
r?   r@   rA   rB   r   r&   rH   ZTensorr;   rD   r   r   r6   r   r
     s   r
   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )r   zSpatial-attention module.   c                    sN   t    |dv sJ d|dkr&dnd}tjdd||dd| _t | _d	S )
z>Initialize Spatial-attention module with kernel size argument.>   rE   r   zkernel size must be 3 or 7r   rE   r   r   F)r|   r$   N)r%   r&   r'   r(   ra   r   r/   )r1   rz   r|   r6   r   r   r&   '  s
    
zSpatialAttention.__init__c                 C   s<   ||  | ttj|dddtj|dddd gd S )zGApply channel and spatial attention on input for feature recalibration.r   T)Zkeepdimr   )r/   ra   rH   r^   meanmaxr:   r   r   r   r;   /  s    zSpatialAttention.forward)r   r_   r   r   r6   r   r   $  s   r   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )r   z%Convolutional Block Attention Module.r   c                    s"   t    t|| _t|| _dS )z>Initialize CBAM with given input channel (c1) and kernel size.N)r%   r&   r
   channel_attentionr   spatial_attention)r1   r2   rz   r6   r   r   r&   7  s    

zCBAM.__init__c                 C   s   |  | |S )z+Applies the forward pass through C1 module.)r   r   r:   r   r   r   r;   =  s    zCBAM.forward)r   r_   r   r   r6   r   r   4  s   r   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )r   z.Concatenate a list of tensors along dimension.r   c                    s   t    || _dS )z;Concatenates a list of tensors along a specified dimension.N)r%   r&   r   )r1   	dimensionr6   r   r   r&   E  s    
zConcat.__init__c                 C   s   t || jS )z.Forward pass for the YOLOv8 mask Proto module.)rH   r^   r   r:   r   r   r   r;   J  s    zConcat.forward)r   r_   r   r   r6   r   r   B  s   r   )Nr   )rB   rU   numpyro   rH   Ztorch.nnr'   __all__r   r-   r   r   r   r   r[   r   r   r   r	   r   r
   r   r   r   r   r   r   r   <module>   s&   
	h