o
    Wh                  
   @   s   d dl Z 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 dZdd ZdddZd	d
 ZdddZdejdejdejdejdejf
ddZdS )    N)uniform_)#multi_scale_deformable_attn_pytorchinverse_sigmoidc                    s   t  fddt|D S )a  
    Create a list of cloned modules from the given module.

    Args:
        module (nn.Module): The module to be cloned.
        n (int): Number of clones to create.

    Returns:
        (nn.ModuleList): A ModuleList containing n clones of the input module.

    Examples:
        >>> import torch.nn as nn
        >>> layer = nn.Linear(10, 10)
        >>> clones = _get_clones(layer, 3)
        >>> len(clones)
        3
    c                    s   g | ]}t  qS  )copydeepcopy).0_moduler   P/var/www/vscode/kcb/lib/python3.10/site-packages/ultralytics/nn/modules/utils.py
<listcomp>!   s    z_get_clones.<locals>.<listcomp>)nn
ModuleListrange)r   nr   r
   r   _get_clones   s   r   {Gz?c                 C   s   t td|  |   S )a  
    Initialize conv/fc bias value according to a given probability value.

    This function calculates the bias initialization value based on a prior probability using the inverse error function.
    It's commonly used in object detection models to initialize classification layers with a specific positive prediction
    probability.

    Args:
        prior_prob (float, optional): Prior probability for bias initialization.

    Returns:
        (float): Bias initialization value calculated from the prior probability.

    Examples:
        >>> bias = bias_init_with_prob(0.01)
        >>> print(f"Bias initialization value: {bias:.4f}")
        Bias initialization value: -4.5951
       )floatnplog)
prior_probr   r   r   bias_init_with_prob$   s   r   c                 C   sV   dt | jjd  }t| j| | t| dr'| jdur)t| j| | dS dS dS )a  
    Initialize the weights and biases of a linear module.

    This function initializes the weights of a linear module using a uniform distribution within bounds calculated
    from the input dimension. If the module has a bias, it is also initialized.

    Args:
        module (nn.Module): Linear module to initialize.

    Returns:
        (nn.Module): The initialized module.

    Examples:
        >>> import torch.nn as nn
        >>> linear = nn.Linear(10, 5)
        >>> initialized_linear = linear_init(linear)
    r   r   biasN)mathsqrtweightshaper   hasattrr   )r   boundr   r   r   linear_init:   s
   r!   h㈵>c                 C   s8   | j ddd} | j |d}d|  j |d}t|| S )a  
    Calculate the inverse sigmoid function for a tensor.

    This function applies the inverse of the sigmoid function to a tensor, which is useful in various neural network
    operations, particularly in attention mechanisms and coordinate transformations.

    Args:
        x (torch.Tensor): Input tensor with values in range [0, 1].
        eps (float, optional): Small epsilon value to prevent numerical instability.

    Returns:
        (torch.Tensor): Tensor after applying the inverse sigmoid function.

    Examples:
        >>> x = torch.tensor([0.2, 0.5, 0.8])
        >>> inverse_sigmoid(x)
        tensor([-1.3863,  0.0000,  1.3863])
    r   r   )minmax)r#   )clamptorchr   )xepsx1x2r   r   r   r   R   s   r   valuevalue_spatial_shapessampling_locationsattention_weightsreturnc                 C   s*  | j \}}}}|j \}}}}	}
}| jdd |D dd}d| d }g }t|D ]>\}\}}|| ddd|| |||}|dddddd|f dddd}tj||dd	d
d}|| q(|dd|| d||	|
 }t	j
|ddd| d||| |}|dd S )a  
    Implement multi-scale deformable attention in PyTorch.

    This function performs deformable attention across multiple feature map scales, allowing the model to attend to
    different spatial locations with learned offsets.

    Args:
        value (torch.Tensor): The value tensor with shape (bs, num_keys, num_heads, embed_dims).
        value_spatial_shapes (torch.Tensor): Spatial shapes of the value tensor with shape (num_levels, 2).
        sampling_locations (torch.Tensor): The sampling locations with shape
            (bs, num_queries, num_heads, num_levels, num_points, 2).
        attention_weights (torch.Tensor): The attention weights with shape
            (bs, num_queries, num_heads, num_levels, num_points).

    Returns:
        (torch.Tensor): The output tensor with shape (bs, num_queries, embed_dims).

    References:
        https://github.com/IDEA-Research/detrex/blob/main/detrex/layers/multi_scale_deform_attn.py
    c                 S   s   g | ]\}}|| qS r   r   )r   H_W_r   r   r   r      s    z7multi_scale_deformable_attn_pytorch.<locals>.<listcomp>r   )dim   Nr   bilinearzerosF)modepadding_modealign_corners)r   split	enumerateflatten	transposereshapeFgrid_sampleappendr&   stacksumview
contiguous)r+   r,   r-   r.   bsr	   	num_heads
embed_dimsnum_queries
num_levels
num_points
value_listsampling_gridssampling_value_listlevelr0   r1   value_l_sampling_grid_l_sampling_value_l_outputr   r   r   r   k   s(   &,
r   )r   )r"   )r   r   numpyr   r&   torch.nnr   torch.nn.functional
functionalr@   torch.nn.initr   __all__r   r   r!   r   Tensorr   r   r   r   r   <module>   s.   

