o
    S"g6                     @  s   d dl mZ d dlmZ d dlmZ d dlmZ d dlm	  m
Z d dlmZm	Z	 d dlmZ G dd	 d	eZG d
d de	jZdS )    )annotations)Iterable)Enum)AnyN)Tensornn)SentenceTransformerc                   @  s(   e Zd ZdZdd Zdd Zdd ZdS )TripletDistanceMetriczThe metric for the triplet lossc                 C  s   dt | | S )N   )Fcosine_similarityxy r   j/mnt/skqttb/ctump_chatbot/chatbot/lib/python3.10/site-packages/sentence_transformers/losses/TripletLoss.py<lambda>       zTripletDistanceMetric.<lambda>c                 C     t j| |ddS )N   pr   pairwise_distancer   r   r   r   r      r   c                 C  r   )Nr
   r   r   r   r   r   r   r      r   N)__name__
__module____qualname____doc__COSINE	EUCLIDEAN	MANHATTANr   r   r   r   r	      s
    r	   c                      sH   e Zd Zejdfd fdd	ZdddZdddZedddZ	  Z
S )TripletLoss   modelr   triplet_marginfloatreturnNonec                   s    t    || _|| _|| _dS )a  
        This class implements triplet loss. Given a triplet of (anchor, positive, negative),
        the loss minimizes the distance between anchor and positive while it maximizes the distance
        between anchor and negative. It compute the following loss function:

        ``loss = max(||anchor - positive|| - ||anchor - negative|| + margin, 0)``.

        Margin is an important hyperparameter and needs to be tuned respectively.

        Args:
            model: SentenceTransformerModel
            distance_metric: Function to compute distance between two
                embeddings. The class TripletDistanceMetric contains
                common distance metrices that can be used.
            triplet_margin: The negative should be at least this much
                further away from the anchor than the positive.

        References:
            - For further details, see: https://en.wikipedia.org/wiki/Triplet_loss

        Requirements:
            1. (anchor, positive, negative) triplets

        Inputs:
            +---------------------------------------+--------+
            | Texts                                 | Labels |
            +=======================================+========+
            | (anchor, positive, negative) triplets | none   |
            +---------------------------------------+--------+

        Example:
            ::

                from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses
                from datasets import Dataset

                model = SentenceTransformer("microsoft/mpnet-base")
                train_dataset = Dataset.from_dict({
                    "anchor": ["It's nice weather outside today.", "He drove to work."],
                    "positive": ["It's so sunny.", "He took the car to the office."],
                    "negative": ["It's quite rainy, sadly.", "She walked to the store."],
                })
                loss = losses.TripletLoss(model=model)

                trainer = SentenceTransformerTrainer(
                    model=model,
                    train_dataset=train_dataset,
                    loss=loss,
                )
                trainer.train()
        N)super__init__r#   distance_metricr$   )selfr#   r*   r$   	__class__r   r   r)      s   
6
zTripletLoss.__init__sentence_featuresIterable[dict[str, Tensor]]labelsr   c           
        sP    fdd|D }|\}}}  ||}  ||}t||  j }	|	 S )Nc                   s   g | ]	}  |d  qS )sentence_embedding)r#   ).0sentence_featurer+   r   r   
<listcomp>R   s    z'TripletLoss.forward.<locals>.<listcomp>)r*   r   relur$   mean)
r+   r.   r0   reps
rep_anchorrep_posrep_negdistance_posdistance_neglossesr   r4   r   forwardQ   s   
zTripletLoss.forwarddict[str, Any]c                 C  sB   | j j}tt D ]\}}|| j krd| } nq
|| jdS )NzTripletDistanceMetric.)r*   r$   )r*   r   varsr	   itemsr$   )r+   distance_metric_namenamevaluer   r   r   get_config_dict[   s   

zTripletLoss.get_config_dictstrc                 C  s   dS )Na  
@misc{hermans2017defense,
    title={In Defense of the Triplet Loss for Person Re-Identification},
    author={Alexander Hermans and Lucas Beyer and Bastian Leibe},
    year={2017},
    eprint={1703.07737},
    archivePrefix={arXiv},
    primaryClass={cs.CV}
}
r   r4   r   r   r   citationd   s   zTripletLoss.citation)r#   r   r$   r%   r&   r'   )r.   r/   r0   r   r&   r   )r&   r@   )r&   rG   )r   r   r   r	   r   r)   r?   rF   propertyrH   __classcell__r   r   r,   r   r!      s    
;

	r!   )
__future__r   collections.abcr   enumr   typingr   torch.nn.functionalr   
functionalr   torchr   )sentence_transformers.SentenceTransformerr   r	   Moduler!   r   r   r   r   <module>   s    