o
    sh                     @   st   d dl mZ d dlmZmZ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 )
    )Enum)AnyDictIterableN)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   f/var/www/html/alpaca_bot/venv/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                       s|   e Zd Zejdfdededdf fddZdee	e
ef  d	edefd
dZde	e
ef fddZede
fddZ  ZS )TripletLoss   modeltriplet_marginreturnNc                    s$   t 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)superr!   __init__r#   distance_metricr$   )selfr#   r(   r$   	__class__r   r   r'      s   6
zTripletLoss.__init__sentence_featureslabelsc           
         sP    fdd|D }|\}}}  ||}  ||}t||  j }	|	 S )Nc                    s   g | ]	}  |d  qS )sentence_embedding)r#   ).0sentence_featurer)   r   r   
<listcomp>O   s    z'TripletLoss.forward.<locals>.<listcomp>)r(   r   relur$   mean)
r)   r,   r-   reps
rep_anchorrep_posrep_negdistance_posdistance_neglossesr   r1   r   forwardN   s   
zTripletLoss.forwardc                 C   sB   | j j}tt D ]\}}|| j krd|} nq
|| jdS )NzTripletDistanceMetric.{})r(   r$   )r(   r   varsr	   itemsformatr$   )r)   distance_metric_namenamevaluer   r   r   get_config_dictX   s   

zTripletLoss.get_config_dictc                 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   r1   r   r   r   citationa   s   zTripletLoss.citation)r   r   r   r	   r   r   floatr'   r   r   strr   r<   r   rC   propertyrD   __classcell__r   r   r*   r   r!      s    ";
	r!   )enumr   typingr   r   r   torch.nn.functionalr   
functionalr   torchr   )sentence_transformers.SentenceTransformerr   r	   Moduler!   r   r   r   r   <module>   s    