o

    hu                     @   sJ   d dl mZ d dlm  mZ d dlmZ ddlmZ G dd deZ	dS )    N)
trunc_normal_   )ClsHeadc                       sd   e Zd ZdZeddddf fdd	Zdd	 Z fd
dZdd
 ZdddZ	dd Z
dd Z  ZS )
ConformerHeadab  Linear classifier head.

    Args:
        num_classes (int): Number of categories excluding the background
            category.
        in_channels (int): Number of channels in the input feature map.
        init_cfg (dict | optional): The extra init config of layers.
            Defaults to use ``dict(type='Normal', layer='Linear', std=0.01)``.
    NormalLinearg{Gz?)typelayerstdc                    sr   t t| j|dd i| || _|| _|| _| jdkr#td| dt| jd || _	t| jd || _
d S )Ninit_cfgr   znum_classes=z must be a positive integerr   )superr   __init__in_channelsnum_classesr   
ValueErrornnr   
conv_cls_headtrans_cls_head)selfr   r   r   argskwargs	__class__ 7/root/Awesome-Backbones/configs/heads/conformer_head.pyr
      s   

zConformerHead.__init__c                 C   sP   t |tjr"t|jdd t |tjr$|jd ur&tj|jd d S d S d S d S )Ng{Gz?)r
   r   )
isinstancer   r   r   weightbiasinit	constant_)r   mr   r   r   
_init_weights(   s   zConformerHead._init_weightsc                    s<   t t|   t| jtr| jd dkrd S | | j d S )Nr   
Pretrained)r   r   init_weightsr   r   dictapplyr!   )r   r   r   r   r#   .   s
   zConformerHead.init_weightsc                 C   s   t |tr	|d }|S )N)r   tuple)r   xr   r   r   
pre_logits8   s   
zConformerHead.pre_logitsTFc                 C   s   |  |}t|dks
J | |d }| |d }|r7|| }|dur,tj|ddnd}|r5| |}|S ||g}|rEtt| j|}|S )a  Inference without augmentation.

        Args:
            x (tuple[tuple[tensor, tensor]]): The input features.
                Multi-stage inputs are acceptable but only the last stage will
                be used to classify. Every item should be a tuple which
                includes convluation features and transformer features. The
                shape of them should be ``(num_samples, in_channels[0])`` and
                ``(num_samples, in_channels[1])``.
            softmax (bool): Whether to softmax the classification score.
            post_process (bool): Whether to do post processing the
                inference results. It will convert the output to a list.

        Returns:
            Tensor | list: The inference results.

                - If no post processing, the output is a tensor with shape
                  ``(num_samples, num_classes)``.
                - If post processing, the output is a multi-dimentional list of
                  float and the dimensions are ``(num_samples, num_classes)``.
           r   r   N)dim)	r)   lenr   r   Fsoftmaxpost_processlistmap)r   r(   r.   r/   conv_cls_scoretran_cls_score	cls_scorepredr   r   r   simple_test=   s   

zConformerHead.simple_testc                 C   sX   |  |}t|trt|dksJ d| |d }| |d }| ||g|}|S )Nr*   z2There should be two outputs in the Conformer modelr   r   )r)   r   r0   r,   r   r   loss)r   r(   gt_labelr2   r3   lossesr   r   r   
forward_trainf   s   
zConformerHead.forward_trainc                    s   t  d t }t fdd D }jr> d  d  }t |t jks1J dd tj|D |d< ||d< |S )	Nr   c                    s$   g | ]}j |d t  qS ))
avg_factor)compute_lossr,   ).0scorer4   r8   num_samplesr   r   r   
<listcomp>u   s    z&ConformerHead.loss.<locals>.<listcomp>r   c                 S   s   i | ]
\}}d | |qS )ztop-r   )r=   kar   r   r   
<dictcomp>}   s    
z&ConformerHead.loss.<locals>.<dictcomp>accuracyr7   )r,   r$   sumcal_acccompute_accuracytopkzip)r   r4   r8   r9   r7   accr   r?   r   r7   q   s   

zConformerHead.loss)TF)
__name__
__module____qualname____doc__r$   r
   r!   r#   r)   r6   r:   r7   
__classcell__r   r   r   r   r   	   s    

)r   )
torch.nnr   Ztorch.nn.functional
functionalr-   Zcore.initialize.weight_initr   cls_headr   r   r   r   r   r   <module>   s
   