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 generalized pointwise loss #540

Merged
merged 19 commits into from
Oct 13, 2021
Merged

Conversation

cthoyt
Copy link
Member

@cthoyt cthoyt commented Jul 20, 2021

Closes #46, closes #47

This PR generalizes the implementation of pykeen.losses.SoftplusLoss so the Pointwise Hinge Loss could be implemented.

It also suggests a new pointwise loss function half way between the pointwise hinge loss and pointwise logistic loss where the softplus activation is used with a nonzero margin. This needs a name, or perhaps someone has already done this and it needs a reference.

@cthoyt cthoyt added 💧 Loss Related to loss functions 💎 New Component labels Jul 20, 2021
@cthoyt cthoyt requested a review from mberr July 20, 2021 12:41
src/pykeen/losses.py Outdated Show resolved Hide resolved
src/pykeen/losses.py Outdated Show resolved Hide resolved
choices=margin_activation_resolver.options,
),
)
class GeneralMarginRankingLoss(PairwiseLoss):
Copy link
Member Author

Choose a reason for hiding this comment

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

@mberr what's a better name for this

Copy link
Member

Choose a reason for hiding this comment

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

Sounds ok. I would go for MarginRankingLoss and rename MRL to HardMarginRankingLoss, but I think this will lead to confusion, since papers do use the term MRL to refer to the hard version.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes I also agree we can't mix with pre-existing nomenclature

Copy link
Member Author

@cthoyt cthoyt Oct 13, 2021

Choose a reason for hiding this comment

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

I settled on MarginPairwiseLoss since there are a few that inherit from it in different ways. This also makes it more explicit this only works in pairwise loss world

src/pykeen/losses.py Outdated Show resolved Hide resolved
synonyms = {"Pairwise Hinge Loss"}

hpo_default: ClassVar[Mapping[str, Any]] = dict(
margin=dict(type=int, low=0, high=3, q=1),
Copy link
Member

Choose a reason for hiding this comment

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

Use a constant for this? the range is chosen somewhat random. btw, why use an integer range for a floating point value.

Copy link
Member Author

Choose a reason for hiding this comment

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

🤷 that's what we had before. Would be happy to change if you want to make it something else

Copy link
Member Author

Choose a reason for hiding this comment

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

updated in c2a8fc5

Pointwise Loss Activation Margin Formulation Implementation
=================== ========== ====================== ======================================================== =========================================
Hinge ReLU $\lambda \neq 0$ $g(s, l) = \max(0, \lambda -\hat{l}*s)$ :class:`pykeen.losses.PointwiseHingeLoss`
??? softplus $\lambda \neq 0$ $g(s, l) = \log(1+\exp(\lambda -\hat{l}*s))$
Copy link
Member

Choose a reason for hiding this comment

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

Soft Hinge?

Copy link
Member

@mberr mberr left a comment

Choose a reason for hiding this comment

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

generally lgtm

class GeneralMarginRankingLoss(PairwiseLoss):
r"""Generalized margin ranking loss.

TODO check order -> is it f(k) - f(\bar{k}) or f(\bar{k}) - f(k)?
Copy link
Member Author

Choose a reason for hiding this comment

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

@mberr please advise :)

Copy link
Member

Choose a reason for hiding this comment

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

Okay, let's check:

Larger score means higher plausibility.

So the loss should be large, if the score of the negative one is larger than the score of the positive, i.e., L = f(\bar{k}) - f(k).

If there is a margin, then the positive score should be at least lambda larger than the negative score. If this is not the case, there should be a positive loss. Thus, L = f(\bar{k}) - f(k) + lambda.

src/pykeen/losses.py Outdated Show resolved Hide resolved
# Utils
'loss_resolver',
]

logger = logging.getLogger(__name__)

DEFAULT_MARGIN_HPO_STRATEGY = dict(type=float, low=0, high=3)
Copy link
Member Author

Choose a reason for hiding this comment

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

@mberr here's a reusable constant for the HPO strategy used everywhere except NSSAL

@mberr can you give an example of a distance-based one?
Trigger CI
@cthoyt cthoyt merged commit 47b9499 into master Oct 13, 2021
@cthoyt cthoyt deleted the generalized-pointwise-loss branch October 13, 2021 22:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💧 Loss Related to loss functions 💎 New Component
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement Pairwise Logistic Loss Implement Pointwise Hinge Loss
2 participants