Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pairwise losses (MSE, Hinge, Logistic, SoftZeroOne) #32

Merged
merged 14 commits into from
Mar 8, 2025

Conversation

abheesht17
Copy link
Collaborator

@abheesht17 abheesht17 commented Feb 24, 2025

To be discussed offline:

  • Currently, we are passing the mask explicitly with y_true. Can use sample_weight, but have a few questions about that [keep it for now].
  • Do we need to do the up-ranking for rank-1 tensors? Or can we ignore? [keep dim=0 expansion, but check TFR]
  • Doc-strings: should we remove args such as reduction, name? [keep them]
  • Should we set doc-strings by setting cls.__doc__ to avoid repetition? [yes]

TODO:

  • Add ops.stop_gradient().
  • Add temperature, etc. as args (can be done in another PR).

@abheesht17 abheesht17 marked this pull request as ready for review February 27, 2025 11:48
@abheesht17 abheesht17 requested a review from hertschuh February 27, 2025 14:01
@abheesht17 abheesht17 changed the title Add pairwise losses Add pairwise losses (MSE, Hinge, Logistic, SoftZeroOne Feb 27, 2025
@abheesht17 abheesht17 changed the title Add pairwise losses (MSE, Hinge, Logistic, SoftZeroOne Add pairwise losses (MSE, Hinge, Logistic, SoftZeroOne) Feb 27, 2025
Copy link
Collaborator

@hertschuh hertschuh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass at the super class and utils.

@abheesht17 abheesht17 requested a review from hertschuh March 1, 2025 10:35
Copy link
Collaborator

@hertschuh hertschuh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates!

The comments for pairwise hinge loss apply to the other ones too.

)
.replace(
"{{explanation}}",
"""\033[A
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does that actually work? Is it just because the dash - has to come right after the """?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, it works!

Computes pairwise hinge loss between true labels and predicted scores.

    This loss function is designed for ranking tasks, where the goal is to
    correctly order items within each list. It computes the loss by comparing
    pairs of items within each list, penalizing cases where an item with a
    higher true label has a lower predicted score than an item with a lower
    true label.

    For each list of predicted scores `s` in `y_pred` and the corresponding list
    of true labels `y` in `y_true`, the loss is computed as follows:

    ```
    loss = sum_{i} sum_{j} I(y_i > y_j) * (s_i - s_j)^2
    ```

    where:
      - `y_i` and `y_j` are the true labels of items `i` and `j`, respectively.
      - `s_i` and `s_j` are the predicted scores of items `i` and `j`,
        respectively.
      - `I(y_i > y_j)` is an indicator function that equals 1 if `y_i > y_j`,
        and 0 otherwise.
      - `(s_i - s_j)^2` is the squared difference between the predicted scores
        of items `i` and `j`, which penalizes discrepancies between the
        predicted order of items relative to their true order.
        
    Args:
        reduction: Type of reduction to apply to the loss. In almost all cases
            this should be `"sum_over_batch_size"`. Supported options are
            `"sum"`, `"sum_over_batch_size"`, `"mean"`,
            `"mean_with_sample_weight"` or `None`. `"sum"` sums the loss,
            `"sum_over_batch_size"` and `"mean"` sum the loss and divide by the
            sample size, and `"mean_with_sample_weight"` sums the loss and
            divides by the sum of the sample weights. `"none"` and `None`
            perform no aggregation. Defaults to `"sum_over_batch_size"`.
        name: Optional name for the loss instance.
        dtype: The dtype of the loss's computations. Defaults to `None`, which
            means using `keras.backend.floatx()`. `keras.backend.floatx()` is a
            `"float32"` unless set to different value
            (via `keras.backend.set_floatx()`). If a `keras.DTypePolicy` is
            provided, then the `compute_dtype` will be utilized.

Copy link
Collaborator

@hertschuh hertschuh Mar 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the thing you pasted here?

Does it work with IDEs (e.g. VSCode for code completion and when you mouse over a symbol)

Does it work on Keras.io (the thing that generates the documentation)?

Those special codes are a terminal concept. So it works when you print it. But outside of a terminal, it's unlikely to work, there is no equivalent concept in markdown, html...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the thing you pasted here?

print(PairwiseMeanSquaredError.__doc__)

Those special codes are a terminal concept. So it works when you print it. But outside of a terminal, it's unlikely to work, there is no equivalent concept in markdown, html...

Ah, I see



pairwise_loss_subclass_doc_string = (
" Computes pairwise hinge loss between true labels and predicted scores."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this simply be in the triple quotes?

Copy link
Collaborator Author

@abheesht17 abheesht17 Mar 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the reason I put it separately is because black formats it to be on the same line as =, which in turn makes it go beyond the 80 line limit.

)
.replace(
"{{extra_args}}",
"\033[A",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does that work for removing the empty line?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah

@abheesht17 abheesht17 requested a review from hertschuh March 3, 2025 16:37
{explanation}

Args:
{extra_args}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like {extra_args} is never actually used (always empty).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, keeping it in case we need to add other losses which might have extra args



formula = "loss = sum_{i} sum_{j} I(y_i > y_j) * (s_i - s_j)^2"
explanation = """\033[A
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the two \033[A and just use " instead """.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did it slightly differently, please take a look



formula = "loss = sum_{i} sum_{j} I(y_i > y_j) * (1 - sigmoid(s_i - s_j))"
explanation = """\033[A
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the two \033[A and just use " instead """.



formula = "loss = sum_{i} sum_{j} I(y_i > y_j) * max(0, 1 - (s_i - s_j))"
explanation = """\033[A
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the two \033[A and just use " instead """.



formula = "loss = sum_{i} sum_{j} I(y_i > y_j) * log(1 + exp(-(s_i - s_j)))"
explanation = """\033[A
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the two \033[A and just use " instead """.

@hertschuh hertschuh merged commit 7553d19 into keras-team:main Mar 8, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants