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   )
LpDistance)common_functions)loss_and_miner_utils   )BaseMetricLossFunctionc                       s:   e Zd ZdZd fdd	Zdd Zdd Zd	d
 Z  ZS )AngularLossz
    Implementation of https://arxiv.org/abs/1708.01682
    Args:
        alpha: The angle (as described in the paper), specified in degrees.
    (   c                    s\   t  jd	i | tj| tdddd tt|| _	| j
dgdd | j
dgdd d S )
Nr   r   T)ppowernormalize_embeddingsalphaF)list_of_namesis_stataverage_angle )super__init__c_fassert_distance_typer   torchtensornpradiansr   add_to_recordable_attributes)selfr   kwargs	__class__r   _/home/ubuntu/.local/lib/python3.10/site-packages/pytorch_metric_learning/losses/angular_loss.pyr      s   
zAngularLoss.__init__c                 C   s   t | | |||||\}}}}	}
|d u r|  S t| jd }tj|| ddd}t|| |	d}|
d }d| | dd|  |  }tj||dd}d||	|
fdd	iS )
Nr   r   T)dimkeepdim   )	keep_maskadd_onelosspos_pair)lossesindicesreduction_type)r   labels_required	get_pairszero_lossesr   tanr   summatmul	unsqueezesqueezetlmu	logsumexp)r   
embeddingslabelsindices_tupleref_emb
ref_labelsanchors	positivesr#   
anchor_idxpositive_idxsq_tan_alphaap_dotap_matmul_embeddings
final_formr'   r   r   r   compute_loss   s,   


zAngularLoss.compute_lossc                 C   s   t |||\}}}}	t|dkst|dkrd gd S | j|| }
| j|| }|| d|dk}| |
|||| |
||||fS )Nr      r   )r3   convert_to_pairslendistance	normalizer0   	set_stats)r   r5   r6   r7   r8   r9   a1r
   a2_r:   r;   r#   r   r   r   r+   5   s   
zAngularLoss.get_pairsc                 C   s   | j rVt E || d }| j||}| jj||d dd }t|dd|  }	t	|	| t	| }
t
|
 | _W d    d S 1 sOw   Y  d S d S )Nr   r   )r    )collect_statsr   no_gradrF   pairwise_distanceget_normr0   r2   atanr.   r   degreesitemr   )r   r:   r;   r5   r8   r#   centersap_distnc_distanglesr   r   r   r   rH   ?   s   
"zAngularLoss.set_stats)r	   )	__name__
__module____qualname____doc__r   rB   r+   rH   __classcell__r   r   r   r   r   
   s    	
r   )numpyr   r   	distancesr   utilsr   r   r   r3   base_metric_loss_functionr   r   r   r   r   r   <module>   s    