o
    Vh=                     @   s   d dl mZmZmZmZ d dlZd dlmZmZ d dlm	Z
 d dlmZmZ ddlmZ ddlmZ dd	lmZ G d
d dejZdededededededefddZdee dee deeef fddZG dd dejjZdS )    )DictListOptionalTupleN)nnTensor)
functional)boxesConv2dNormActivation   )_utils)AnchorGenerator)	ImageListc                       sf   e Zd ZdZdZddededdf fdd	Z fd
dZdee	 de
ee	 ee	 f fddZ  ZS )RPNHeada  
    Adds a simple RPN Head with classification and regression heads

    Args:
        in_channels (int): number of channels of the input feature
        num_anchors (int): number of anchors to be predicted
        conv_depth (int, optional): number of convolutions
       r   in_channelsnum_anchorsreturnNc              	      s   t    g }t|D ]}|t||dd d qtj| | _tj||ddd| _	tj||d ddd| _
|  D ] }t|tjrYtjjj|jdd |jd urYtjj|jd q9d S )	N   )kernel_size
norm_layerr   )r   stride   g{Gz?)stdr   )super__init__rangeappendr
   r   
SequentialconvConv2d
cls_logits	bbox_predmodules
isinstancetorchinitnormal_weightbias	constant_)selfr   r   
conv_depthconvs_layer	__class__ T/var/www/vscode/kcb/lib/python3.10/site-packages/torchvision/models/detection/rpn.pyr      s   

zRPNHead.__init__c              	      st   | dd }|d u s|dk r,dD ]}	| d|	 }
| d|	 }|
|v r+||
||< qt ||||||| d S )Nversionr   )r(   r)   zconv.z	conv.0.0.)getpopr   _load_from_state_dict)r+   
state_dictprefixlocal_metadatastrictmissing_keysunexpected_keys
error_msgsr4   typeold_keynew_keyr0   r2   r3   r7   *   s"   
zRPNHead._load_from_state_dictxc                 C   sD   g }g }|D ]}|  |}|| | || | q||fS N)r   r   r!   r"   )r+   rB   logitsbbox_regfeaturetr2   r2   r3   forwardG   s   
zRPNHead.forward)r   )__name__
__module____qualname____doc___versionintr   r7   r   r   r   rH   __classcell__r2   r2   r0   r3   r      s    	.r   r/   NACHWr   c                 C   s6   |  |d|||} | ddddd} | |d|} | S )Nr   r   r   r   r   )viewpermutereshape)r/   rP   rQ   rR   rS   rT   r2   r2   r3   permute_and_flattenQ   s   rY   box_clsbox_regressionc                 C   s   g }g }t | |D ]4\}}|j\}}}}	|jd }
|
d }|| }t||||||	}|| t|||d||	}|| q	tj|dddd} tj|dddd}| |fS )Nr   r   dimr   rU   )zipshaperY   r   r%   catflattenrX   )rZ   r[   box_cls_flattenedbox_regression_flattenedbox_cls_per_levelbox_regression_per_levelrP   AxCrS   rT   Ax4rQ   rR   r2   r2   r3   concat_box_prediction_layersX   s   

ri   c                       s  e Zd ZdZejejejdZ	d+de	de
jdededed	ed
eeef deeef dededdf fddZdefddZdefddZdee deeeef  deee ee f fddZdedee defddZdededeeeef  dee deee ee f f
d d!Zded"ed#ee d$ee deeef f
d%d&Z	d,d'ed(eeef deeeeef   deee eeef f fd)d*Z  ZS )-RegionProposalNetworka  
    Implements Region Proposal Network (RPN).

    Args:
        anchor_generator (AnchorGenerator): module that generates the anchors for a set of feature
            maps.
        head (nn.Module): module that computes the objectness and regression deltas
        fg_iou_thresh (float): minimum IoU between the anchor and the GT box so that they can be
            considered as positive during training of the RPN.
        bg_iou_thresh (float): maximum IoU between the anchor and the GT box so that they can be
            considered as negative during training of the RPN.
        batch_size_per_image (int): number of anchors that are sampled during training of the RPN
            for computing the loss
        positive_fraction (float): proportion of positive anchors in a mini-batch during training
            of the RPN
        pre_nms_top_n (Dict[str, int]): number of proposals to keep before applying NMS. It should
            contain two fields: training and testing, to allow for different values depending
            on training or evaluation
        post_nms_top_n (Dict[str, int]): number of proposals to keep after applying NMS. It should
            contain two fields: training and testing, to allow for different values depending
            on training or evaluation
        nms_thresh (float): NMS threshold used for postprocessing the RPN proposals
        score_thresh (float): only return proposals with an objectness score greater than score_thresh

    )	box_coderproposal_matcherfg_bg_sampler        anchor_generatorheadfg_iou_threshbg_iou_threshbatch_size_per_imagepositive_fractionpre_nms_top_npost_nms_top_n
nms_threshscore_threshr   Nc                    sn   t    || _|| _tjdd| _tj| _	tj
||dd| _t||| _|| _|| _|	| _|
| _d| _d S )N)      ?ry   ry   ry   )weightsT)allow_low_quality_matchesgMbP?)r   r   ro   rp   	det_utilsBoxCoderrk   box_opsbox_ioubox_similarityMatcherrl   BalancedPositiveNegativeSamplerrm   _pre_nms_top_n_post_nms_top_nrw   rx   min_size)r+   ro   rp   rq   rr   rs   rt   ru   rv   rw   rx   r0   r2   r3   r      s    

zRegionProposalNetwork.__init__c                 C      | j r| jd S | jd S Ntrainingtesting)r   r   r+   r2   r2   r3   ru         

z#RegionProposalNetwork.pre_nms_top_nc                 C   r   r   )r   r   r   r2   r2   r3   rv      r   z$RegionProposalNetwork.post_nms_top_nanchorstargetsc                 C   s   g }g }t ||D ]e\}}|d }| dkr2|j}tj|jtj|d}	tj|jd ftj|d}
n2| ||}| |}||j	dd }	|dk}
|
j
tjd}
|| jjk}d|
|< || jjk}d|
|< ||
 ||	 q	||fS )Nr	   r   dtypedevice)min)r   rn   g      )r_   numelr   r%   zerosr`   float32r   rl   clamptoBELOW_LOW_THRESHOLDBETWEEN_THRESHOLDSr   )r+   r   r   labelsmatched_gt_boxesanchors_per_imagetargets_per_imagegt_boxesr   matched_gt_boxes_per_imagelabels_per_imagematch_quality_matrixmatched_idxs
bg_indicesinds_to_discardr2   r2   r3   assign_targets_to_anchors   s(   

z/RegionProposalNetwork.assign_targets_to_anchors
objectnessnum_anchors_per_levelc           
      C   sl   g }d}| |dD ]$}|jd }t||  d}|j|dd\}}	||	|  ||7 }q
tj|ddS )Nr   r   r\   )	splitr`   r|   	_topk_minru   topkr   r%   ra   )
r+   r   r   roffsetobr   ru   r.   	top_n_idxr2   r2   r3   _get_top_n_idx   s   

z$RegionProposalNetwork._get_top_n_idx	proposalsimage_shapesc                    s  |j d }|j | }||d} fddt|D }t|d}|dd|}| ||}tj	| d}|d d d f }	||	|f }||	|f }||	|f }t
|}
g }g }t||
||D ]]\}}}}t||}t|| j}|| || || }}}t|| jkd }|| || || }}}t|||| j}|d |   }|| || }}|| || qc||fS )Nr   rU   c                    s&   g | ]\}}t j|f|t j d qS )r   )r%   fullint64).0idxnr   r2   r3   
<listcomp>   s    z:RegionProposalNetwork.filter_proposals.<locals>.<listcomp>r   r   )r`   r   detachrX   	enumerater%   ra   	expand_asr   arangesigmoidr_   r~   clip_boxes_to_imageremove_small_boxesr   whererx   batched_nmsrw   rv   r   )r+   r   r   r   r   
num_imageslevelsr   image_range	batch_idxobjectness_probfinal_boxesfinal_scoresr	   scoreslvl	img_shapekeepr2   r   r3   filter_proposals   s<   



z&RegionProposalNetwork.filter_proposalspred_bbox_deltasr   regression_targetsc           
      C   s   |  |\}}ttj|ddd }ttj|ddd }tj||gdd}| }tj|dd}tj|dd}tj|| || ddd|  }t|| || }	|	|fS )a  
        Args:
            objectness (Tensor)
            pred_bbox_deltas (Tensor)
            labels (List[Tensor])
            regression_targets (List[Tensor])

        Returns:
            objectness_loss (Tensor)
            box_loss (Tensor)
        r   r\   gqq?sum)beta	reduction)	rm   r%   r   ra   rb   Fsmooth_l1_lossr    binary_cross_entropy_with_logits)
r+   r   r   r   r   sampled_pos_indssampled_neg_indssampled_indsbox_lossobjectness_lossr2   r2   r3   compute_loss+  s"   z"RegionProposalNetwork.compute_lossimagesfeaturesc                 C   s   t | }| |\}}| ||}t|}dd |D }dd |D }	t||\}}| j| |}
|
	|dd}
| 
|
||j|	\}}i }| jrr|du rTtd| ||\}}| j||}| ||||\}}||d}||fS )	a=  
        Args:
            images (ImageList): images for which we want to compute the predictions
            features (Dict[str, Tensor]): features computed from the images that are
                used for computing the predictions. Each tensor in the list
                correspond to different feature levels
            targets (List[Dict[str, Tensor]]): ground-truth boxes present in the image (optional).
                If provided, each element in the dict should contain a field `boxes`,
                with the locations of the ground-truth boxes.

        Returns:
            boxes (List[Tensor]): the predicted boxes from the RPN, one Tensor per
                image.
            losses (Dict[str, Tensor]): the losses for the model during training. During
                testing, it is an empty dict.
        c                 S   s   g | ]}|d  j qS )r   )r`   )r   or2   r2   r3   r   m  s    z1RegionProposalNetwork.forward.<locals>.<listcomp>c                 S   s$   g | ]}|d  |d  |d  qS )r   r   r   r2   )r   sr2   r2   r3   r   n  s   $ rU   r   Nztargets should not be None)loss_objectnessloss_rpn_box_reg)listvaluesrp   ro   lenri   rk   decoder   rV   r   image_sizesr   
ValueErrorr   encoder   )r+   r   r   r   r   r   r   r   #num_anchors_per_level_shape_tensorsr   r   r	   r   lossesr   r   r   r   r   r2   r2   r3   rH   P  s.   zRegionProposalNetwork.forward)rn   rC   )rI   rJ   rK   rL   r|   r}   r   r   __annotations__r   r   ModulefloatrN   r   strr   ru   rv   r   r   r   r   r   r   r   r   r   rH   rO   r2   r2   r0   r3   rj   q   s    


%
&
9

)
rj   )typingr   r   r   r   r%   r   r   torch.nnr   r   torchvision.opsr	   r~   r
    r   r|   anchor_utilsr   
image_listr   r   r   rN   rY   ri   rj   r2   r2   r2   r3   <module>   s    &B&