
    bi                        d dl mZ d dlmZ d dlmZ d dlmZ d dlm	c m
Z d dlmZm	Z	 d dlmZ d dlmZmZmZ  G d	 d
e          Z G d de	j                  ZdS )    )annotations)Iterable)Enum)AnyN)Tensornn)SentenceTransformer)pairwise_cos_simpairwise_euclidean_simpairwise_manhattan_simc                  $    e Zd ZdZd Zd Zd ZdS )TripletDistanceMetriczThe metric for the triplet lossc                (    dt          | |          z
  S )N   )r
   xys     c/root/projects/butler/venv/lib/python3.11/site-packages/sentence_transformers/losses/TripletLoss.py<lambda>zTripletDistanceMetric.<lambda>   s    !.q!444     c                "    t          | |          S N)r   r   s     r   r   zTripletDistanceMetric.<lambda>       3Aq99 r   c                "    t          | |          S r   )r   r   s     r   r   zTripletDistanceMetric.<lambda>   r   r   N)__name__
__module____qualname____doc__COSINE	EUCLIDEAN	MANHATTAN r   r   r   r      s,        ))44F99I99IIIr   r   c                  `     e Zd Zej        dfd fdZddZddZddZe	dd            Z
 xZS )TripletLoss   modelr	   triplet_marginfloatreturnNonec                r    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__s       r   r-   zTripletLoss.__init__   s9    l 	
.,r   sentence_featuresIterable[dict[str, Tensor]]labelsr   c                L      fd|D             }                      ||          S )Nc                F    g | ]}                     |          d          S )sentence_embedding)r&   ).0sentence_featurer/   s     r   
<listcomp>z'TripletLoss.forward.<locals>.<listcomp>S   s-    sssM]djj!1223GHsssr   )compute_loss_from_embeddings)r/   r1   r3   
embeddingss   `   r   forwardzTripletLoss.forwardR   s3    ssssarsss
00VDDDr   r;   list[Tensor]c                    |\  }}}|                      ||          }|                      ||          }t          j        ||z
  | j        z             }|                                S )z
        Compute the CoSENT loss from embeddings.

        Args:
            embeddings: List of embeddings

        Returns:
            Loss value
        )r.   Frelur'   mean)	r/   r;   r3   
rep_anchorrep_posrep_negdistance_posdistance_neglossess	            r   r:   z(TripletLoss.compute_loss_from_embeddingsW   sd     (2$
GW++J@@++J@@|3d6IIJJ{{}}r   dict[str, Any]c                    | j         j        }t          t                                                    D ]\  }}|| j         k    rd| } n|| j        dS )NzTripletDistanceMetric.)r.   r'   )r.   r   varsr   itemsr'   )r/   distance_metric_namenamevalues       r   get_config_dictzTripletLoss.get_config_dicth   so    #3< 566<<>> 	 	KD%,,,'F'F'F$ - $84K^___r   strc                    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"   )r/   s    r   citationzTripletLoss.citationq   s    	 	r   )r&   r	   r'   r(   r)   r*   )r1   r2   r3   r   r)   r   )r;   r=   r3   r   r)   r   )r)   rH   )r)   rP   )r   r   r   r   r    r-   r<   r:   rO   propertyrR   __classcell__)r0   s   @r   r$   r$      s        :O:Yst9- 9- 9- 9- 9- 9- 9-vE E E E
   "` ` ` ` 
 
 
 X
 
 
 
 
r   r$   )
__future__r   collections.abcr   enumr   typingr   torch.nn.functionalr   
functionalr?   torchr   )sentence_transformers.SentenceTransformerr	   sentence_transformers.utilr
   r   r   r   Moduler$   r"   r   r   <module>r_      s   " " " " " " $ $ $ $ $ $                              I I I I I I g g g g g g g g g g: : : : :D : : :f f f f f") f f f f fr   