o
    pi                     @   s^   d dl Z d dlm  mZ ddlmZ ddlmZ	 ddlm
Z ddlmZ G dd	 d	eZdS )
    N   CosineSimilarity)common_functions)loss_and_miner_utils   )BaseMetricLossFunctionc                       s2   e Zd ZdZd	 fdd	Zdd Zdd Z  ZS )
SmoothAPLosszO
    Implementation of the SmoothAP loss: https://arxiv.org/abs/2007.12163
    {Gz?c                    s(   t  jdi | t| t || _d S )N )super__init__c_fassert_distance_typer   temperature)selfr   kwargs	__class__r   \/home/ubuntu/.local/lib/python3.10/site-packages/pytorch_metric_learning/losses/smooth_ap.pyr      s   
zSmoothAPLoss.__init__c                 C   s   t  S )Nr   )r   r   r   r   get_default_distance   s   z!SmoothAPLoss.get_default_distancec           !      C   s  t | t |||| t|}tj|ddd }|| }| ddkr3td	|
  |d}	|	t|d }
dt|	 }|jdd|	dd}| |}|jddd|	d}||ddd }t|| j ||j }tj|d	dd }||
|	|
 |d	}dt|	|
  }|jddjdd|
|	|
 dd}| jj|d	d}| j||}|jdddd|	|
 d}||ddd
d }t|| j ||j }tj|d	dd }|	|
 }t|	|j}t|
D ]1}t|D ]*}|||f }||| | || |d | f }t|| | ||| | < q qtj|||jd}d| | } d| t | ddiS )NT)as_tupler   r   zAll classes must have the same number of elements in the labels.
The given labels have the following number of elements: {}.
You can achieve this using the samplers.MPerClassSampler class and setting the batch_size and m.g      ?)dimr      )dtypeap_losselement)lossesindicesreduction_type) r   labels_requiredref_not_supportedtorchbincountnonzerouniquesize
ValueErrorformatcputolisteye	unsqueezerepeatdistancepermuteFsigmoidr   todevicesumviewmaybe_normalizecompute_matzerosrangelmuconvert_to_weightsr   torch_arange_from_size)!r   
embeddingslabelsindices_tupleref_emb
ref_labelscountsnonzero_indicesnonzero_counts
batch_sizenum_classes_batchmasksimssims_repeat	sims_diff	sims_sigm
sims_ranksxspos_maskxs_normsims_possims_pos_repeatsims_pos_diffsims_pos_sigmsims_pos_ranksgapijpos_rankall_rankminer_weightslossr   r   r   compute_loss   sp   
	




$"zSmoothAPLoss.compute_loss)r
   )__name__
__module____qualname____doc__r   r   r^   __classcell__r   r   r   r   r	   
   s
    r	   )r#   torch.nn.functionalnn
functionalr1   	distancesr   utilsr   r   r   r;   base_metric_loss_functionr   r	   r   r   r   r   <module>   s    