U
    ­Ê¹jw=  ã                   @   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eeeeeeedœdd„Zee ee eeef dœ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                       s`   e Zd ZdZdZdeeddœ‡ fdd„Z‡ fdd	„Zee	 e
ee	 ee	 f d
œ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   N)Úin_channelsÚnum_anchorsÚreturnc              	      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ƒrrtjjj|jdd� |jd k	rrtjj |jd¡ qrd S )	Né   )Úkernel_sizeZ
norm_layerr   )r   Zstrideé   g{®Gáz„?)Zstdr   )ÚsuperÚ__init__ÚrangeÚappendr
   r   Z
SequentialÚconvZConv2dÚ
cls_logitsÚ	bbox_predÚmodulesÚ
isinstanceÚtorchÚinitZnormal_ÚweightÚbiasZ	constant_)Úselfr   r   Z
conv_depthZconvsÚ_Úlayer©Ú	__class__© ú_/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torchvision/models/detection/rpn.pyr      s    

zRPNHead.__init__c              	      st   |  dd ¡}|d ks|dk rXdD ]6}	|› d|	› �}
|› d|	› �}|
|kr | |
¡||< q tƒ  |||||||¡ d S )NÚversionr   )r"   r#   zconv.z	conv.0.0.)ÚgetÚpopr   Ú_load_from_state_dict)r$   Z
state_dictÚprefixZlocal_metadataÚstrictZmissing_keysZunexpected_keysZ
error_msgsr+   ÚtypeÚold_keyZnew_keyr'   r)   r*   r.   *   s     
ùzRPNHead._load_from_state_dict)Úxr   c                 C   sD   g }g }|D ].}|   |¡}| |  |¡¡ | |  |¡¡ q||fS )N)r   r   r   r   )r$   r3   ZlogitsZbbox_regÚfeatureÚtr)   r)   r*   ÚforwardG   s    
zRPNHead.forward)r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú_versionÚintr   r.   r   r   r   r6   Ú__classcell__r)   r)   r'   r*   r      s
   	r   )r&   ÚNÚAÚCÚHÚWr   c                 C   s6   |   |d|||¡} |  ddddd¡} |  |d|¡} | S )Néÿÿÿÿr   r   r   r   r   )ÚviewZpermuteÚreshape)r&   r>   r?   r@   rA   rB   r)   r)   r*   Úpermute_and_flattenQ   s    rF   )Úbox_clsÚbox_regressionr   c                 C   s°   g }g }t | |ƒD ]h\}}|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   éþÿÿÿrC   )ÚzipÚshaperF   r   r    ÚcatÚflattenrE   )rG   rH   Zbox_cls_flattenedZbox_regression_flattenedZbox_cls_per_levelZbox_regression_per_levelr>   ZAxCrA   rB   ZAx4r?   r@   r)   r)   r*   Úconcat_box_prediction_layersX   s    

rP   c                       sb  e Zd ZdZejejejdœZde	e
jeeeeeeef eeef eeddœ‡ fdd„Zedœd	d
„Zedœdd„Zee eeeef  eee ee f dœdd„Zeee edœdd„Zeeeeeef  ee eee ee f dœdd„Zeeee ee eeef dœdd„Zdeeeef eeeeef   eee eeef f dœdd„Z‡  ZS )ÚRegionProposalNetworkah  
    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

    )Ú	box_coderÚproposal_matcherÚfg_bg_samplerç        N)Ú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   c                    sn   t ƒ  ¡  || _|| _tjdd�| _tj| _	tj
||dd�| _t ||¡| _|| _|| _|	| _|
| _d| _d S )N)ç      ð?r`   r`   r`   )ÚweightsT)Zallow_low_quality_matchesgü©ñÒMbP?)r   r   rV   rW   Ú	det_utilsÚBoxCoderrR   Úbox_opsZbox_iouÚbox_similarityÚMatcherrS   ÚBalancedPositiveNegativeSamplerrT   Ú_pre_nms_top_nÚ_post_nms_top_nr^   r_   Úmin_size)r$   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r'   r)   r*   r   ‘   s     
ýzRegionProposalNetwork.__init__)r   c                 C   s   | j r| jd S | jd S ©NÚtrainingZtesting)rl   rh   ©r$   r)   r)   r*   r\   ¶   s    
z#RegionProposalNetwork.pre_nms_top_nc                 C   s   | j r| jd S | jd S rk   )rl   ri   rm   r)   r)   r*   r]   »   s    
z$RegionProposalNetwork.post_nms_top_n)ÚanchorsÚtargetsr   c                 C   sæ   g }g }t ||ƒD ]Ê\}}|d }| ¡ dkrd|j}tj|jtj|d�}	tj|jd ftj|d�}
nd|  ||¡}|  |¡}||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)rq   rU   g      ð¿)rL   Únumelrr   r    ZzerosrM   Zfloat32re   rS   ÚclampÚtoZBELOW_LOW_THRESHOLDZBETWEEN_THRESHOLDSr   )r$   rn   ro   ÚlabelsÚmatched_gt_boxesZanchors_per_imageZtargets_per_imageZgt_boxesrr   Zmatched_gt_boxes_per_imageZlabels_per_imageZmatch_quality_matrixZmatched_idxsZ
bg_indicesZinds_to_discardr)   r)   r*   Úassign_targets_to_anchorsÀ   s(    

z/RegionProposalNetwork.assign_targets_to_anchors)Ú
objectnessÚnum_anchors_per_levelr   c           
      C   sl   g }d}|  |d¡D ]H}|jd }t ||  ¡ d¡}|j|dd�\}}	| |	| ¡ ||7 }qtj|dd�S )Nr   r   rI   )	ÚsplitrM   rb   Z	_topk_minr\   Ztopkr   r    rN   )
r$   rz   r{   ÚrÚoffsetÚobr   r\   r%   Ú	top_n_idxr)   r)   r*   Ú_get_top_n_idxæ   s    

z$RegionProposalNetwork._get_top_n_idx)Ú	proposalsrz   Úimage_shapesr{   r   c                    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 |  ¡ … }|| ||  }}| |¡ | |¡ qÆ||fS )Nr   rC   c                    s&   g | ]\}}t j|f|t jˆ d �‘qS )rp   )r    ÚfullZint64)Ú.0ÚidxÚn©rr   r)   r*   Ú
<listcomp>ÿ   s    z:RegionProposalNetwork.filter_proposals.<locals>.<listcomp>r   rˆ   )rM   rr   ÚdetachrE   Ú	enumerater    rN   Z	expand_asr�   ZarangeZsigmoidrL   rd   Zclip_boxes_to_imageZremove_small_boxesrj   Úwherer_   Zbatched_nmsr^   r]   r   )r$   r‚   rz   rƒ   r{   Ú
num_imagesZlevelsr€   Zimage_rangeZ	batch_idxZobjectness_probZfinal_boxesZfinal_scoresr	   ÚscoresZlvlZ	img_shapeZkeepr)   rˆ   r*   Úfilter_proposalsñ   s<    

ÿ

z&RegionProposalNetwork.filter_proposals)rz   Úpred_bbox_deltasrw   Úregression_targetsr   c           
      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   rI   gÇqÇq¼?Úsum)ÚbetaZ	reduction)	rT   r    rŒ   rN   rO   ÚFZsmooth_l1_lossrt   Z binary_cross_entropy_with_logits)
r$   rz   r�   rw   r‘   Zsampled_pos_indsZsampled_neg_indsZsampled_indsZbox_lossZobjectness_lossr)   r)   r*   Úcompute_loss*  s"    üûz"RegionProposalNetwork.compute_loss)ÚimagesÚfeaturesro   r   c                 C   sì   t | ¡ ƒ}|  |¡\}}|  ||¡}t|ƒ}dd„ |D ƒ}dd„ |D ƒ}	t||ƒ\}}| j | ¡ |¡}
|
 	|dd¡}
|  
|
||j|	¡\}}i }| jrä|dkr¨t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   )rM   )r…   Úor)   r)   r*   r‰   l  s     z1RegionProposalNetwork.forward.<locals>.<listcomp>c                 S   s$   g | ]}|d  |d  |d  ‘qS )r   r   r   r)   )r…   Úsr)   r)   r*   r‰   m  s     rC   r   Nztargets should not be None)Úloss_objectnessÚloss_rpn_box_reg)ÚlistÚvaluesrW   rV   ÚlenrP   rR   ÚdecoderŠ   rD   r�   Zimage_sizesrl   Ú
ValueErrorry   Úencoder•   )r$   r–   r—   ro   rz   r�   rn   r�   Z#num_anchors_per_level_shape_tensorsr{   r‚   r	   rŽ   Zlossesrw   rx   r‘   rš   r›   r)   r)   r*   r6   O  s4       ÿþzRegionProposalNetwork.forward)rU   )N)r7   r8   r9   r:   rb   rc   rf   rg   Ú__annotations__r   r   ÚModuleÚfloatr<   r   Ústrr   r\   r]   r   r   r   ry   r�   r�   r•   r   r   r6   r=   r)   r)   r'   r*   rQ   q   sZ   ý ó

ò% þ&ú:   
þ) ü
ûrQ   )Útypingr   r   r   r   r    r   r   Ztorch.nnr   r”   Ztorchvision.opsr	   rd   r
   Ú r   rb   Zanchor_utilsr   Z
image_listr   r£   r   r<   rF   rP   rQ   r)   r)   r)   r*   Ú<module>   s   B"