o
    pi                     @   sT   d dl Z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)nn   CosineSimilarity)common_functions   )BaseMetricLossFunctionc                       sP   e Zd ZdZ				ddededed	ed
ef
 fddZdd Zdd Z  Z	S )ManifoldLossa  
    The parameters are defined as in the paper https://openaccess.thecvf.com/content_CVPR_2019/papers/Aziere_Ensemble_Deep_Manifold_Similarity_Learning_Using_Hard_Proxies_CVPR_2019_paper.pdf
    - l: embedding size.

    - K: number of proxies. Optional

    - lambdaC: regularization weight. Used in the formula
                :math:`loss = loss^{int} + \lambda_C*loss^{ctx}`.
        For :math:`\lambda_C=0` use only intrinsic loss, for :math:`\lambda_C=\infty` use only context loss.
        Optional

    - alpha: parameter of the Random Walk. It is contained in :math:`(0,1)` and specifies the amount of similarity from
           each node is passed to neighbor nodes. Optional

    - margin: margin used in the calculation of the loss. Optional
    2         ?皙?Mb@?lKlambdaCalphamarginc                    sr   t  jdi | |dk rtd| d|| _|| _tt||| _	|| _
|| _|| _| jg ddd d S )Nr   z4Incorrect value for lambdaC argument. Given lambdaC=z& but accepted only non-negative values)r   r   r   r   r   F)list_of_namesis_stat )super__init__
ValueErrorr   r   r   	Parametertorchrandnproxiesr   r   r   add_to_recordable_attributes)selfr   r   r   r   r   kwargs	__class__r   `/home/ubuntu/.local/lib/python3.10/site-packages/pytorch_metric_learning/losses/manifold_loss.pyr      s    	
zManifoldLoss.__init__c                 C   s  t |||| t || |jd | jksJ t|}|d ur#|}ntd| j|| j f}t	t
| j|f}|t| }tjd|j|jd}tj	|| jgdd}	| |	|	dtj}
t|
d }
tj|| j |
j|
jd}|
|
|  }
ttj|
ddd }||
}||}|j}t| | j|   }||}d| j | }||d d d f  }|d |d d f  }| jtjkr|d ||d f }||t
||f  dd | j! }tj |t
||f< tj ||dk < t|}t"dtj|dd }|# }tj$j%j&||'ddd( }||t
||f  dd | j! 7 }tj |t
||f< tj ||dk < t|}t"dtj|dd }|# }|| j|  }d|d d	d
iS )Nr   r   )devicedtype)dimg      ?g      lossalready_reduced)lossesindicesreduction_type))c_fref_not_supportedlabels_not_supportedshaper   lenr   randintr   catarangerandpermzerosr#   r$   r   distanceclampnpinfexpeyepowsumdiagmminversefloatr   tocloner   viewr   logmeanr   
functionalcosine_similarity	unsqueezet)r   
embeddingslabelsindices_tupleref_emb
ref_labelsNmeta_classesloss_intembs_and_proxiesSY
D_inv_halfS_bardtLFF_pF_eloss_ctxr'   r   r   r"   compute_loss6   sn   


$

&
zManifoldLoss.compute_lossc                 C   s   t  S )Nr   )r   r   r   r"   get_default_distance   s   z!ManifoldLoss.get_default_distance)r
   r   r   r   )
__name__
__module____qualname____doc__intrA   r   r^   r_   __classcell__r   r   r    r"   r	   
   s&    Kr	   )numpyr8   r   r   	distancesr   utilsr   r,   base_metric_loss_functionr   r	   r   r   r   r"   <module>   s    