o
    pi                     @   sL   d dl 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   
LpDistance)common_functions)loss_and_miner_utils   )BaseMetricLossFunctionc                       s6   e Zd Zd
 fdd	Zdd Zdd Zdd	 Z  ZS )NCALossr   c                    s,   t  jdi | || _| jdgdd d S )Nsoftmax_scaleF)list_of_namesis_stat )super__init__r
   add_to_recordable_attributes)selfr
   kwargs	__class__r   [/home/ubuntu/.local/lib/python3.10/site-packages/pytorch_metric_learning/losses/nca_loss.pyr   
   s
   
zNCALoss.__init__c                 C   s0   t |dkr
|  S t| | |||||S )Nr   )lenzero_lossesc_flabels_requirednca_computation)r   
embeddingslabelsindices_tupleref_emb
ref_labelsr   r   r   compute_loss   s   

zNCALoss.compute_lossc                 C   s   |j }tj|||||ud}| ||}| jjs| }||u r'|t| tj|	d|	dk|d}	t
jjj| j| dd}
t
j|
|	 dd}
|
dk}t
|
|  ||  }d|t|| ddiS )	N)dtype	using_refr   r   )r!   )dimlosselement)lossesindicesreduction_type)r!   lmuconvert_to_weightsdistanceis_invertedfill_diagonal_r   neg_infto_dtype	unsqueezetorchnn
functionalsoftmaxr
   sumlogtorch_arange_from_size)r   query	referencequery_labelsreference_labelsr   r!   miner_weightsmatsame_labelsexpnon_zeror$   r   r   r   r      s,   zNCALoss.nca_computationc                 C   s
   t ddS )Nr   )powerr   )r   r   r   r   get_default_distance5   s   
zNCALoss.get_default_distance)r   )__name__
__module____qualname__r   r    r   rB   __classcell__r   r   r   r   r	   	   s
    r	   )r1   	distancesr   utilsr   r   r   r)   base_metric_loss_functionr   r	   r   r   r   r   <module>   s    