
    si                         d dl mZ d dlmZmZmZ d dlmc mZ	 d dl
mZmZ d dlmZ  G d de          Z G d d	ej                  ZdS )
    )Enum)AnyDictIterableN)Tensornn)SentenceTransformerc                   $    e Zd ZdZd Zd Zd ZdS )TripletDistanceMetriczThe metric for the triplet lossc                 2    dt          j        | |          z
  S )N   )Fcosine_similarityxys     [/var/www/icac/venv/lib/python3.11/site-packages/sentence_transformers/losses/TripletLoss.py<lambda>zTripletDistanceMetric.<lambda>   s    !a1!Q777     c                 0    t          j        | |d          S )N   pr   pairwise_distancer   s     r   r   zTripletDistanceMetric.<lambda>       Q0A;;; r   c                 0    t          j        | |d          S )Nr   r   r   r   s     r   r   zTripletDistanceMetric.<lambda>   r   r   N)__name__
__module____qualname____doc__COSINE	EUCLIDEAN	MANHATTAN r   r   r   r   
   s,        ))77F;;I;;IIIr   r   c                        e Zd Zej        dfdededdf fdZdee	e
ef                  dedefd	Zde	e
ef         fd
Zede
fd            Z xZS )TripletLoss   modeltriplet_marginreturnNc                     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__s       r   r.   zTripletLoss.__init__   s?    l 	k4  ))+++
.,r   sentence_featureslabelsc                       fd|D             }|\  }}}                      ||          }                      ||          }t          j        ||z
   j        z             }	|	                                S )Nc                 F    g | ]}                     |          d          S )sentence_embedding)r)   ).0sentence_featurer0   s     r   
<listcomp>z'TripletLoss.forward.<locals>.<listcomp>O   s-    mmmGW

+,,-ABmmmr   )r/   r   relur*   mean)
r0   r2   r3   reps
rep_anchorrep_posrep_negdistance_posdistance_neglossess
   `         r   forwardzTripletLoss.forwardN   s}    mmmm[lmmm'+$
GW++J@@++J@@|3d6IIJJ{{}}r   c                     | j         j        }t          t                                                    D ]'\  }}|| j         k    rd                    |          } n(|| j        dS )NzTripletDistanceMetric.{})r/   r*   )r/   r   varsr   itemsformatr*   )r0   distance_metric_namenamevalues       r   get_config_dictzTripletLoss.get_config_dictX   su    #3< 566<<>> 	 	KD%,,,'A'H'H'N'N$ - $84K^___r   c                     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%   )r0   s    r   citationzTripletLoss.citationa   s    	 	r   )r   r   r    r   r#   r	   floatr.   r   r   strr   rC   r   rK   propertyrM   __classcell__)r1   s   @r   r'   r'      s        :O:Yst9- 9-(9-kp9-	9- 9- 9- 9- 9- 9-v$sF{2C)D f Y_    `c3h ` ` ` ` 
# 
 
 
 X
 
 
 
 
r   r'   )enumr   typingr   r   r   torch.nn.functionalr   
functionalr   torchr   )sentence_transformers.SentenceTransformerr	   r   Moduler'   r%   r   r   <module>rY      s          & & & & & & & & & &                  I I I I I I< < < < <D < < <Z Z Z Z Z") Z Z Z Z Zr   