ó
    — óh|  ã                  ór   • S SK Jr  S SKJr  S SKJrJr  S SKJr  SSK	J	r	J
r
   " S S\R                  5      rg	)
é    )Úannotations)ÚIterable)ÚTensorÚnn)ÚSentenceTransformeré   )ÚBatchHardTripletLossÚ$BatchHardTripletLossDistanceFunctionc                  óz   ^ • \ rS rSr\R
                  S4     SU 4S jjjrS	S jrS
S jr\	SS j5       r
SrU =r$ )ÚBatchAllTripletLossé   é   c                óF   >• [         TU ]  5         Xl        X0l        X l        g)aæ
  
BatchAllTripletLoss takes a batch with (sentence, label) pairs and computes the loss for all possible, valid
triplets, i.e., anchor and positive must have the same label, anchor and negative a different label. The labels
must be integers, with same label indicating sentences from the same class. Your train dataset
must contain at least 2 examples per label class.

Args:
    model: SentenceTransformer model
    distance_metric: Function that returns a distance between
        two embeddings. The class SiameseDistanceMetric contains
        pre-defined metrics that can be used.
    margin: Negative samples should be at least margin further
        apart from the anchor than the positive.

References:
    * Source: https://github.com/NegatioN/OnlineMiningTripletLoss/blob/master/online_triplet_loss/losses.py
    * Paper: In Defense of the Triplet Loss for Person Re-Identification, https://arxiv.org/abs/1703.07737
    * Blog post: https://omoindrot.github.io/triplet-loss

Requirements:
    1. Each sentence must be labeled with a class.
    2. Your dataset must contain at least 2 examples per labels class.

Inputs:
    +------------------+--------+
    | Texts            | Labels |
    +==================+========+
    | single sentences | class  |
    +------------------+--------+

Recommendations:
    - Use ``BatchSamplers.GROUP_BY_LABEL`` (:class:`docs <sentence_transformers.training_args.BatchSamplers>`) to
      ensure that each batch contains 2+ examples per label class.

Relations:
    * :class:`BatchHardTripletLoss` uses only the hardest positive and negative samples, rather than all possible, valid triplets.
    * :class:`BatchHardSoftMarginTripletLoss` uses only the hardest positive and negative samples, rather than all possible, valid triplets.
      Also, it does not require setting a margin.
    * :class:`BatchSemiHardTripletLoss` uses only semi-hard triplets, valid triplets, rather than all possible, valid triplets.

Example:
    ::

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

        model = SentenceTransformer("microsoft/mpnet-base")
        # E.g. 0: sports, 1: economy, 2: politics
        train_dataset = Dataset.from_dict({
            "sentence": [
                "He played a great game.",
                "The stock is up 20%",
                "They won 2-1.",
                "The last goal was amazing.",
                "They all voted against the bill.",
            ],
            "label": [0, 1, 0, 0, 2],
        })
        loss = losses.BatchAllTripletLoss(model)

        trainer = SentenceTransformerTrainer(
            model=model,
            train_dataset=train_dataset,
            loss=loss,
        )
        trainer.train()

N)ÚsuperÚ__init__Úsentence_embedderÚtriplet_marginÚdistance_metric)ÚselfÚmodelr   ÚmarginÚ	__class__s       €Új/home/james-whalen/.local/lib/python3.13/site-packages/sentence_transformers/losses/BatchAllTripletLoss.pyr   ÚBatchAllTripletLoss.__init__   s#   ø€ ôT 	‰ÑÔØ!&ÔØ$ÔØ.Õó    c                óR   • U R                  US   5      S   nU R                  X#5      $ )Nr   Úsentence_embedding)r   Úbatch_all_triplet_loss)r   Úsentence_featuresÚlabelsÚreps       r   ÚforwardÚBatchAllTripletLoss.forward\   s/   € Ø×$Ñ$Ð%6°qÑ%9Ó:Ð;OÑPˆØ×*Ñ*¨6Ó7Ð7r   c                óJ  • U R                  U5      nUR                  S5      nUR                  S5      nXE-
  U R                  -   n[        R                  " U5      nUR                  5       U-  nSXfS:  '   XfS:„     nUR                  S5      n	UR                  5       U	S-   -  nU$ )a  Build the triplet loss over a batch of embeddings.
We generate all the valid triplets and average the loss over the positive ones.
Args:
    labels: labels of the batch, of size (batch_size,)
    embeddings: tensor of shape (batch_size, embed_dim)
    margin: margin for triplet loss
    squared: Boolean. If true, output is the pairwise squared euclidean distance matrix.
             If false, output is the pairwise euclidean distance matrix.
Returns:
    Label_Sentence_Triplet: scalar tensor containing the triplet loss
é   r   r   g¼‰Ø—²Òœ<)r   Ú	unsqueezer   r	   Úget_triplet_maskÚfloatÚsizeÚsum)
r   r    Ú
embeddingsÚpairwise_distÚanchor_positive_distÚanchor_negative_distÚtriplet_lossÚmaskÚvalid_tripletsÚnum_positive_tripletss
             r   r   Ú*BatchAllTripletLoss.batch_all_triplet_loss`   s½   € ð ×,Ñ,¨ZÓ8ˆà,×6Ñ6°qÓ9ÐØ,×6Ñ6°qÓ9Ðð ,ÑBÀT×EXÑEXÑXˆô $×4Ò4°VÓ<ˆØ—z‘z“| lÑ2ˆð *+ˆ AÑ%Ñ&ð &°UÑ&:Ñ;ˆØ .× 3Ñ 3°AÓ 6Ðð
 $×'Ñ'Ó)Ð-BÀUÑ-JÑKˆàÐr   c                ó   • g)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   s    r   ÚcitationÚBatchAllTripletLoss.citation‹   s   € ð	r   )r   r   r   )r   r   r   r(   ÚreturnÚNone)r   zIterable[dict[str, Tensor]]r    r   r8   r   )r    r   r+   r   r8   r   )r8   Ústr)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r
   Úeucledian_distancer   r"   r   Úpropertyr6   Ú__static_attributes__Ú__classcell__)r   s   @r   r   r      s\   ø† ð =×OÑOØð	M/à"ðM/ð ð	M/ð
 
÷M/ð M/ô^8ô)ðV ó
ó ö
r   r   N)Ú
__future__r   Úcollections.abcr   Útorchr   r   Ú)sentence_transformers.SentenceTransformerr   r	   r
   ÚModuler   r5   r   r   Ú<module>rH      s&   ðÝ "å $ç å Iç \ôJ˜"Ÿ)™)õ Jr   