o
    Vh!                     @   s   d dl mZ d dlmZmZmZmZ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 G dd	 d	e	jZG d
d de	jZG dd deZG dd deZdS )    )OrderedDict)CallableDictListOptionalTupleN)nnTensor   )Conv2dNormActivation)_log_api_usage_oncec                   @   F   e Zd ZdZdee dee dee deee ee f fddZdS )	ExtraFPNBlocka  
    Base class for the extra block in the FPN.

    Args:
        results (List[Tensor]): the result of the FPN
        x (List[Tensor]): the original feature maps
        names (List[str]): the names for each one of the
            original feature maps

    Returns:
        results (List[Tensor]): the extended set of results
            of the FPN
        names (List[str]): the extended set of names for the results
    resultsxnamesreturnc                 C   s   d S )N )selfr   r   r   r   r   [/var/www/vscode/kcb/lib/python3.10/site-packages/torchvision/ops/feature_pyramid_network.pyforward   s   zExtraFPNBlock.forwardN	__name__
__module____qualname____doc__r   r	   strr   r   r   r   r   r   r      s    r   c                       s   e Zd ZdZdZ		ddee dedee dee	de
jf  f fd	d
Z fddZdededefddZdededefddZdeeef deeef fddZ  ZS )FeaturePyramidNetworkac  
    Module that adds a FPN from on top of a set of feature maps. This is based on
    `"Feature Pyramid Network for Object Detection" <https://arxiv.org/abs/1612.03144>`_.

    The feature maps are currently supposed to be in increasing depth
    order.

    The input to the model is expected to be an OrderedDict[Tensor], containing
    the feature maps on top of which the FPN will be added.

    Args:
        in_channels_list (list[int]): number of channels for each feature map that
            is passed to the module
        out_channels (int): number of channels of the FPN representation
        extra_blocks (ExtraFPNBlock or None): if provided, extra operations will
            be performed. It is expected to take the fpn features, the original
            features and the names of the original features as input, and returns
            a new list of feature maps and their corresponding names
        norm_layer (callable, optional): Module specifying the normalization layer to use. Default: None

    Examples::

        >>> m = torchvision.ops.FeaturePyramidNetwork([10, 20, 30], 5)
        >>> # get some dummy data
        >>> x = OrderedDict()
        >>> x['feat0'] = torch.rand(1, 10, 64, 64)
        >>> x['feat2'] = torch.rand(1, 20, 16, 16)
        >>> x['feat3'] = torch.rand(1, 30, 8, 8)
        >>> # compute the FPN on top of x
        >>> output = m(x)
        >>> print([(k, v.shape) for k, v in output.items()])
        >>> # returns
        >>>   [('feat0', torch.Size([1, 5, 64, 64])),
        >>>    ('feat2', torch.Size([1, 5, 16, 16])),
        >>>    ('feat3', torch.Size([1, 5, 8, 8]))]

    r
   Nin_channels_listout_channelsextra_blocks
norm_layer.c           	   	      s   t    t|  t | _t | _|D ])}|dkrtdt||dd|d d}t||d|d d}| j	| | j	| q| 
 D ]}t|tjratjj|jdd |jd uratj|jd qC|d urtt|tsttdt| || _d S )	Nr   z(in_channels=0 is currently not supported   )kernel_sizepaddingr!   activation_layer   )r#   r!   r%   az1extra_blocks should be of type ExtraFPNBlock not )super__init__r   r   
ModuleListinner_blockslayer_blocks
ValueErrorr   appendmodules
isinstanceConv2dinitkaiming_uniform_weightbias	constant_r   	TypeErrortyper    )	r   r   r   r    r!   in_channelsinner_block_modulelayer_block_modulem	__class__r   r   r*   M   s2   






zFeaturePyramidNetwork.__init__c              	      s   | dd }|d u s|dk rGt| j}	dD ]1}
t|	D ]*}dD ]%}| |
 d| d| }| |
 d| d| }||v rD||||< qqqt ||||||| d S )Nversionr
   )r,   r-   )r5   r6   .z.0.)getlenr,   rangepopr)   _load_from_state_dict)r   
state_dictprefixlocal_metadatastrictmissing_keysunexpected_keys
error_msgsr@   
num_blocksblockir9   old_keynew_keyr>   r   r   rF   p   s,   

z+FeaturePyramidNetwork._load_from_state_dictr   idxr   c                 C   F   t | j}|dk r||7 }|}t| jD ]\}}||kr ||}q|S )zs
        This is equivalent to self.inner_blocks[idx](x),
        but torchscript doesn't support this yet
        r   )rC   r,   	enumerater   r   rS   rN   outrP   moduler   r   r   get_result_from_inner_blocks      
z2FeaturePyramidNetwork.get_result_from_inner_blocksc                 C   rT   )zs
        This is equivalent to self.layer_blocks[idx](x),
        but torchscript doesn't support this yet
        r   )rC   r-   rU   rV   r   r   r   get_result_from_layer_blocks   rZ   z2FeaturePyramidNetwork.get_result_from_layer_blocksc           
      C   s   t | }t | }| |d d}g }|| |d tt|d ddD ]'}| || |}|jdd }t	j
||dd}|| }|d| || q)| jdur_| |||\}}tdd	 t||D }	|	S )
a6  
        Computes the FPN for a set of feature maps.

        Args:
            x (OrderedDict[Tensor]): feature maps for each feature level.

        Returns:
            results (OrderedDict[Tensor]): feature maps after FPN layers.
                They are ordered from the highest resolution first.
        r
   Nnearest)sizemoder   c                 S   s   g | ]\}}||fqS r   r   ).0kvr   r   r   
<listcomp>   s    z1FeaturePyramidNetwork.forward.<locals>.<listcomp>)listkeysvaluesrY   r/   r[   rD   rC   shapeFinterpolateinsertr    r   zip)
r   r   r   
last_innerr   rS   inner_lateral
feat_shapeinner_top_downrW   r   r   r   r      s   
zFeaturePyramidNetwork.forward)NN)r   r   r   r   _versionr   intr   r   r   r   Moduler*   rF   r	   rY   r[   r   r   r   __classcell__r   r   r>   r   r   $   s$    &# *r   c                   @   r   )	LastLevelMaxPoolzh
    Applies a max_pool2d (not actual max_pool2d, we just subsample) on top of the last feature map
    r   yr   r   c                 C   s.   | d | tj|d dddd ||fS )Npoolr\   r"   r
   r   )r#   strider$   )r/   ri   
max_pool2d)r   r   rv   r   r   r   r   r      s   
zLastLevelMaxPool.forwardNr   r   r   r   r   ru      s    ru   c                       s`   e Zd ZdZdedef fddZdee dee dee d	e	ee ee f fd
dZ
  ZS )LastLevelP6P7zO
    This module is used in RetinaNet to generate extra layers, P6 and P7.
    r:   r   c                    st   t    t||ddd| _t||ddd| _| j| jfD ]}tjj|jdd tj	|j
d q||k| _d S )Nr&   r
   r"   r'   r   )r)   r*   r   r2   p6p7r3   r4   r5   r7   r6   use_P5)r   r:   r   rX   r>   r   r   r*      s   
zLastLevelP6P7.__init__pcr   r   c           	      C   s^   |d |d }}| j r|n|}| |}| t|}|||g |ddg ||fS )Nr\   r{   r|   )r}   r{   r|   ri   reluextend)	r   r~   r   r   p5c5r   r{   r|   r   r   r   r      s   
zLastLevelP6P7.forward)r   r   r   r   rr   r*   r   r	   r   r   r   rt   r   r   r>   r   rz      s    	rz   )collectionsr   typingr   r   r   r   r   torch.nn.functionalr   
functionalri   torchr	   ops.miscr   utilsr   rs   r   r   ru   rz   r   r   r   r   <module>   s     ,