o
    ei<                     @   s   d dl Zd dlZd dlmZ ddlmZmZmZ ddl	m
Z
mZmZmZmZmZmZ e r3d dlmZ e r<d dlmZ e rKd dlmZ d d	lmZ G d
d de
ZG dd dejZ				dddZdS )    N   )is_accelerate_availableis_scipy_availableis_vision_available   )HungarianMatcher_set_aux_lossbox_iou	dice_lossgeneralized_box_iounested_tensor_from_tensor_listsigmoid_focal_loss)center_to_corners_formatlinear_sum_assignment)PartialState)reducec                   @   s   e Zd Ze dd ZdS )LwDetrHungarianMatcherc                    s  |d j dd \}}|d dd }|d dd}tdd |D }td	d |D }	d
}
d}d|
 ||  d| d    }|
d| |  |d    }|dd|f |dd|f  }|j}|tj}|	tj}	tj	||	dd}||}t
t|t|	 }| j| | j|  | j|  }|||d }dd |D }g }|| |jdd}t|D ]' |  }dd t||dD } dkr|}q fddt||D }qdd |D S )z
        Differences:
        - out_prob = outputs["logits"].flatten(0, 1).sigmoid() instead of softmax
        - class_cost uses alpha and gamma
        logitsNr   r   r   
pred_boxesc                 S      g | ]}|d  qS class_labels .0vr   r   \/home/ubuntu/transcripts/venv/lib/python3.10/site-packages/transformers/loss/loss_lw_detr.py
<listcomp>9       z2LwDetrHungarianMatcher.forward.<locals>.<listcomp>c                 S   r   boxesr   r   r   r   r   r   :   r   g      ?g       @g:0yE>)pc                 S      g | ]}t |d  qS r    lenr   r   r   r   r   Q       dimc                 S   s   g | ]
\}}t || qS r   r   )r   icr   r   r   r   W   s    c                    sD   g | ]\}}t |d  |d     gt |d |d gfqS )r   r   )npconcatenate)r   indice1indice2group_idgroup_num_queriesr   r   r   [   s    c                 S   s0   g | ]\}}t j|t jd t j|t jd fqS ))dtype)torch	as_tensorint64)r   r*   jr   r   r   r   b   s   0 )shapeflattensigmoidr4   catlogr3   tofloat32cdistr   r   	bbox_cost
class_cost	giou_costviewcpusplitrange	enumeratezip)selfoutputstargets
group_detr
batch_sizenum_queriesout_probout_bbox
target_idstarget_bboxalphagammaneg_cost_classpos_cost_classrA   r3   r@   rB   cost_matrixsizesindicescost_matrix_listgroup_cost_matrixgroup_indicesr   r0   r   forward+   s>   " 
zLwDetrHungarianMatcher.forwardN)__name__
__module____qualname__r4   no_gradr]   r   r   r   r   r   *   s    r   c                       sd   e Zd Z fddZdd Ze dd Zdd Zd	d
 Z	dd Z
dd Zdd Zdd Z  ZS )LwDetrImageLossc                    s,   t    || _|| _|| _|| _|| _d S N)super__init__matchernum_classesfocal_alphalossesrL   )rI   rf   rg   rh   ri   rL   	__class__r   r   re   f   s   

zLwDetrImageLoss.__init__c                 C   sJ  d|vrt d|d }| |}tdd t||D }| j}d}	|d | }
tjdd t||D dd	}ttt|
	 t|d }|
|j}| 	 }| }t|}||	 }t|}|| || ||d
|  }t|d	 }|||< d
| ||< | |  |d
|    }| | }d|i}|S )Nr   z#No logits were found in the outputsc                 S       g | ]\}\}}|d  | qS r   r   )r   t_Jr   r   r   r   u        z/LwDetrImageLoss.loss_labels.<locals>.<listcomp>r   r   c                 S   rl   r    r   r   rm   rn   r*   r   r   r   r   y   rp   r   r(   r   g{Gz?loss_ce)KeyError_get_source_permutation_idxr4   r;   rH   rh   diagr	   r   detachr=   r3   cloner:   
zeros_likelistappendpowclampr<   sum)rI   rJ   rK   rY   	num_boxessource_logitsidxtarget_classes_orS   rT   	src_boxestarget_boxesiou_targetspos_iousprobpos_weightsneg_weightspos_indrm   rr   ri   r   r   r   loss_labelso   s6   


zLwDetrImageLoss.loss_labelsc                 C   sb   |d }|j }tjdd |D |d}| djdkd}tj	|
 |
 }	d|	i}
|
S )	z
        Compute the cardinality error, i.e. the absolute error in the number of predicted non-empty boxes.

        This is not really a loss, it is intended for logging purposes only. It doesn't propagate gradients.
        r   c                 S   r$   r   r%   r   r   r   r   r      r'   z4LwDetrImageLoss.loss_cardinality.<locals>.<listcomp>)devicer#   g      ?r   cardinality_error)r   r4   r5   r:   maxvaluesr}   nn
functionall1_lossfloat)rI   rJ   rK   rY   r~   r   r   target_lengths	card_predcard_errri   r   r   r   loss_cardinality   s   z LwDetrImageLoss.loss_cardinalityc                 C   s   d|vrt d| |}|d | }tjdd t||D dd}tjj||dd}i }	| | |	d	< d
t	t
t|t| }
|
 | |	d< |	S )a<  
        Compute the losses related to the bounding boxes, the L1 regression loss and the GIoU loss.

        Targets dicts must contain the key "boxes" containing a tensor of dim [nb_target_boxes, 4]. The target boxes
        are expected in format (center_x, center_y, w, h), normalized by the image size.
        r   z#No predicted boxes found in outputsc                 S   rl   r    r   rq   r   r   r   r      rp   z.LwDetrImageLoss.loss_boxes.<locals>.<listcomp>r   r(   none)	reduction	loss_bboxr   	loss_giou)rs   rt   r4   r;   rH   r   r   r   r}   ru   r   r   )rI   rJ   rK   rY   r~   r   source_boxesr   r   ri   r   r   r   r   
loss_boxes   s   
zLwDetrImageLoss.loss_boxesc                 C   s   d|vrt d| |}| |}|d }|| }dd |D }t| \}	}
|	|}	|	| }	tjj|dddf |	j	dd ddd	}|ddd
f 
d}|	
d}	|	|j	}	t||	|t||	|d}|S )z
        Compute the losses related to the masks: the focal loss and the dice loss.

        Targets dicts must contain the key "masks" containing a tensor of dim [nb_target_boxes, h, w].
        
pred_masksz#No predicted masks found in outputsc                 S   r   )masksr   r   rm   r   r   r   r      r   z.LwDetrImageLoss.loss_masks.<locals>.<listcomp>NbilinearF)sizemodealign_cornersr   r   )	loss_mask	loss_dice)rs   rt   _get_target_permutation_idxr   	decomposer=   r   r   interpolater8   r9   rC   r   r
   )rI   rJ   rK   rY   r~   
source_idx
target_idxsource_masksr   target_masksvalidri   r   r   r   
loss_masks   s(   





zLwDetrImageLoss.loss_masksc                 C   4   t dd t|D }t dd |D }||fS )Nc                 S   s    g | ]\}\}}t ||qS r   r4   	full_like)r   r*   sourcern   r   r   r   r      rp   z?LwDetrImageLoss._get_source_permutation_idx.<locals>.<listcomp>c                 S   s   g | ]\}}|qS r   r   )r   r   rn   r   r   r   r      r   r4   r;   rG   )rI   rY   	batch_idxr   r   r   r   rt         z+LwDetrImageLoss._get_source_permutation_idxc                 C   r   )Nc                 S   s    g | ]\}\}}t ||qS r   r   )r   r*   rn   targetr   r   r   r      rp   z?LwDetrImageLoss._get_target_permutation_idx.<locals>.<listcomp>c                 S   s   g | ]\}}|qS r   r   )r   rn   r   r   r   r   r      r   r   )rI   rY   r   r   r   r   r   r      r   z+LwDetrImageLoss._get_target_permutation_idxc                 C   s@   | j | j| j| jd}||vrtd| d|| ||||S )N)labelscardinalityr!   r   zLoss z not supported)r   r   r   r   
ValueError)rI   lossrJ   rK   rY   r~   loss_mapr   r   r   get_loss   s   zLwDetrImageLoss.get_lossc              
      s  | j r| jnd}dd | D }| |||}tdd |D }|| }tj|gtjtt	|
 jd}d}t rHtji krHt|}t j}tj|| dd }i }| jD ]}	|| |	|||| qXd|v rt|d D ]/\ }
| |
||}| jD ] }	|	d	krq| |	|
|||} fd
d| D }|| qqqd|v r|d }| j|||d}| jD ]}	| |	||||}dd | D }|| q|S )a  
        This performs the loss computation.

        Args:
             outputs (`dict`, *optional*):
                Dictionary of tensors, see the output specification of the model for the format.
             targets (`list[dict]`, *optional*):
                List of dicts, such that `len(targets) == batch_size`. The expected keys in each dict depends on the
                losses applied, see each loss' doc.
        r   c                 S   s&   i | ]\}}|d kr|dkr||qS )enc_outputsauxiliary_outputsr   r   kr   r   r   r   
<dictcomp>  s     z+LwDetrImageLoss.forward.<locals>.<dictcomp>c                 s   s    | ]	}t |d  V  qdS )r   Nr%   r   r   r   r   	<genexpr>  s    z*LwDetrImageLoss.forward.<locals>.<genexpr>)r3   r   )minr   r   c                        i | ]\}}|d    |qS rn   r   r   r*   r   r   r   #  rp   r   )rL   c                 S      i | ]	\}}|d  |qS _encr   r   r   r   r   r   +      )trainingrL   itemsrf   r}   r4   r5   r   nextiterr   r   r   r   _shared_stater   num_processesr|   itemri   updater   rG   )rI   rJ   rK   rL   outputs_without_aux_and_encrY   r~   
world_sizeri   r   r   l_dictr   r   r   r   r]      sF   "



zLwDetrImageLoss.forward)r^   r_   r`   re   r   r4   ra   r   r   r   rt   r   r   r]   __classcell__r   r   rj   r   rb   e   s    	$
"rb   c	                    s  t |j|j|jd}
g d}t|
|j|j||jd}|| i }d }| |d< ||d< ||d|d< |j	r>t
||}||d< |||d	|jd
|jd< |j	rpi }t|jd	 D ] | fdd D  qZ| dd  D }| tfddD }||fS )N)rA   r@   rB   )r   r!   r   )rf   rg   rh   ri   rL   r   r   )r   r   r   r   r   )rr   r   r   c                    r   r   r   r   r   r   r   r   ^  rp   z0LwDetrForObjectDetectionLoss.<locals>.<dictcomp>c                 S   r   r   r   r   r   r   r   r   `  r   c                 3   s(    | ]}|v r | |  V  qd S rc   r   )r   r   )	loss_dictweight_dictr   r   r   b  s   & z/LwDetrForObjectDetectionLoss.<locals>.<genexpr>)r   rA   r@   rB   rb   
num_labelsrh   rL   r=   auxiliary_lossr   bbox_loss_coefficientgiou_loss_coefficientrF   decoder_layersr   r   r}   )r   r   r   r   configoutputs_classoutputs_coordenc_outputs_classenc_outputs_coordkwargsrf   ri   	criterionoutputs_lossr   aux_weight_dictenc_weight_dictr   r   )r*   r   r   r   LwDetrForObjectDetectionLoss1  sD   







r   )NNNN)numpyr,   r4   torch.nnr   utilsr   r   r   loss_for_object_detectionr   r   r	   r
   r   r   r   transformers.image_transformsr   scipy.optimizer   
accelerater   accelerate.utilsr   r   Modulerb   r   r   r   r   r   <module>   s(   $; S