
    h                    b    S SK Jr  S SKJrJr  S SKJr  S SKJr   " S S\R                  5      r
g)    )annotations)Tensornn)CrossEncoder)fullnamec                  p   ^  \ rS rSr\R
                  " 5       S4       SU 4S jjjrSS jrS rSr	U =r
$ )	BinaryCrossEntropyLoss	   Nc                  > [         TU ]  5         Xl        X l        X0l        [
        R                  " SSU0UD6U l        [        U R                  [        5      (       d8  [        U R                  R                   S[        U R                  5       S35      eU R                  R                  S:w  a9  [        U R                  R                   SU R                  R                   S35      eg)	a  
Computes the Binary Cross Entropy Loss for a CrossEncoder model. This loss is used to train a model to predict
a high logit for positive pairs and a low logit for negative pairs. The model should be initialized with
``num_labels = 1`` (a.k.a. the default) to predict one class.

It has been used to train many of the strong `CrossEncoder MS MARCO Reranker models <https://huggingface.co/models?author=cross-encoder&search=marco>`_.

Args:
    model (:class:`~sentence_transformers.cross_encoder.CrossEncoder`): A CrossEncoder model to be trained.
    activation_fn (:class:`~torch.nn.Module`): Activation function applied to the logits before computing the loss. Defaults to :class:`~torch.nn.Identity`.
    pos_weight (Tensor, optional): A weight of positive examples. Must be a :class:`torch.Tensor` like ``torch.tensor(4)`` for a weight of 4. Defaults to None.
    **kwargs: Additional keyword arguments passed to the underlying :class:`torch.nn.BCEWithLogitsLoss`.

References:
    - :class:`torch.nn.BCEWithLogitsLoss`
    - `Cross Encoder > Training Examples > Semantic Textual Similarity <../../../examples/cross_encoder/training/sts/README.html>`_
    - `Cross Encoder > Training Examples > Quora Duplicate Questions <../../../examples/cross_encoder/training/quora_duplicate_questions/README.html>`_
    - `Cross Encoder > Training Examples > MS MARCO <../../../examples/cross_encoder/training/ms_marco/README.html>`_
    - `Cross Encoder > Training Examples > Rerankers <../../../examples/cross_encoder/training/rerankers/README.html>`_

Requirements:
    1. Your model must be initialized with `num_labels = 1` (a.k.a. the default) to predict one class.

Inputs:
    +-------------------------------------------------+----------------------------------------+-------------------------------+
    | Texts                                           | Labels                                 | Number of Model Output Labels |
    +=================================================+========================================+===============================+
    | (anchor, positive/negative) pairs               | 1 if positive, 0 if negative           | 1                             |
    +-------------------------------------------------+----------------------------------------+-------------------------------+
    | (sentence_A, sentence_B) pairs                  | float similarity score between 0 and 1 | 1                             |
    +-------------------------------------------------+----------------------------------------+-------------------------------+

Recommendations:
    - Use :class:`~sentence_transformers.util.mine_hard_negatives` with ``output_format="labeled-pair"``
      to convert question-answer pairs to the ``(anchor, positive/negative) pairs`` format with labels as 1 or 0,
      using hard negatives.

Example:
    ::

        from sentence_transformers.cross_encoder import CrossEncoder, CrossEncoderTrainer, losses
        from datasets import Dataset

        model = CrossEncoder("microsoft/mpnet-base")
        train_dataset = Dataset.from_dict({
            "query": ["What are pandas?", "What are pandas?"],
            "response": ["Pandas are a kind of bear.", "Pandas are a kind of fish."],
            "label": [1, 0],
        })
        loss = losses.BinaryCrossEntropyLoss(model)

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

pos_weightz? expects a model of type CrossEncoder, but got a model of type .   z; expects a model with 1 output label, but got a model with z output labels.N )super__init__modelactivation_fnr   r   BCEWithLogitsLossbce_with_logits_loss
isinstancer   
ValueError	__class____name__type
num_labels)selfr   r   r   kwargsr   s        {/home/james-whalen/.local/lib/python3.13/site-packages/sentence_transformers/cross_encoder/losses/BinaryCrossEntropyLoss.pyr   BinaryCrossEntropyLoss.__init__
   s    B 	
*$$&$8$8$YJ$YRX$Y!$**l33>>**+ ,++/

+;*<A? 
 ::  A%>>**+ ,((,

(=(='>oO  &    c                   [        U5      S:w  a  [        S[        U5       S35      e[        [        US   US   5      5      nU R                  R                  USSSS9nUR                  U R                  R                  5        U R                  " S
0 UD6S   R                  S	5      nU R                  U5      nU R                  XRR                  5       5      nU$ )N   z\BinaryCrossEntropyLoss expects a dataset with two non-label columns, but got a dataset with z	 columns.r   r   Tpt)padding
truncationreturn_tensorsr   )lenr   listzipr   	tokenizertodeviceviewr   r   float)r   inputslabelspairstokenslogitslosss          r   forwardBinaryCrossEntropyLoss.forward]   s    v;!norsyozn{  |E  F  SF1I./%%	 & 
 			$**##$%f%a(--b1##F+((@r    c                    [        U R                  5      U R                  c  U R                  S.$ U R                  R                  5       S.$ )N)r   r   )r   r   r   item)r   s    r   get_config_dict&BinaryCrossEntropyLoss.get_config_dictp   sD    %d&8&89-1__-D$//
 	
JN//J^J^J`
 	
r    )r   r   r   r   )r   r   r   z	nn.Moduler   zTensor | NonereturnNone)r0   zlist[list[str]]r1   r   r<   r   )r   
__module____qualname____firstlineno__r   Identityr   r6   r:   __static_attributes____classcell__)r   s   @r   r	   r	   	   sW     $&;;=$(	QQ !Q "	Q 
Q Qf&
 
r    r	   N)
__future__r   torchr   r   0sentence_transformers.cross_encoder.CrossEncoderr   sentence_transformers.utilr   Moduler	   r   r    r   <module>rI      s#    "  I /k
RYY k
r    