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 multiclass support #29

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open

Conversation

MichalBrzozowski91
Copy link
Collaborator

No description provided.

@mwachnicki mwachnicki self-assigned this Mar 6, 2024
@@ -1,5 +1,11 @@
# Version History

## 1.1.0 Feb 26, 2024
Copy link
Collaborator

Choose a reason for hiding this comment

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

This date should be consistent with the release date, so I mark it with a comment as a reminder :)

notebooks/requirements.txt Outdated Show resolved Hide resolved
tests/test_bert_truncated.py Outdated Show resolved Hide resolved
@mwachnicki
Copy link
Collaborator

mwachnicki commented Mar 8, 2024

Summary of issues we have discussed today on the call:

  • Divide classes into Classifier and Regressor
  • Current BertClassifier class as a base for both
  • Interface:
    • Classification: predict method returning classes and predict_scores method returning probabilities
    • Regression: predict method
  • _predict_logits as a protected method that is used by predict/predict_scores to get meaningful results
  • Refactor names of classes
  • Make sure that the cross entropy loss uses softmax and is the best choice in terms of numerical stability, etc.
    • Actually, the best option would be to have the loss function as a parameter with the default value
  • Similarly, there can be a possibility to choose the optimizer and its parameters

@MichalBrzozowski91
Copy link
Collaborator Author

Thanks for the review :)
I added the main changes concerning division classes into Classifier and Regressor
I did not implement the custom loss and optimizer:

  • For me, it does violate the YAGNI principle - I am not sure this is needed now.
  • If necessary, I would rather add it in another PR. This issue is separate from adding the multiclass support.

Copy link
Collaborator

@mwachnicki mwachnicki left a comment

Choose a reason for hiding this comment

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

Thank you, I really like how it looks now! 🙂

I agree that the loss and optimizer feature is not part of the multiclass support. I have just created the related issue - #43.

tests/test_bert_truncated.py Outdated Show resolved Hide resolved
belt_nlp/bert.py Show resolved Hide resolved
@@ -75,7 +78,7 @@ def __init__(
self._params.update(additional_params)

self.device = device
self.collate_fn = BertClassifierWithPooling.collate_fn_pooled_tokens
self.collate_fn = BertBaseWithPooling.collate_fn_pooled_tokens
Copy link
Collaborator

Choose a reason for hiding this comment

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

self.collate_fn_pooled_tokens would also work and use the method overwritten in a derived class (if done so).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

But this is is a static method, it seems natural to me to use with the class and not an instance.

Copy link
Collaborator

Choose a reason for hiding this comment

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

You may be right in general, but this is a specific case, where the collate_fn_pooled_tokens method is called in an instance method of the same class.

If you create a new class that derives from the BertBaseWithPooling class and overwrite the collate_fn_pooled_tokens method, you would probably expect the overwritten method to be used in the __init__ method and that's why I think it would be safer to call it as self.collate_fn_pooled_tokens.

However, in this very specific case, this scenario may be unlikely, so I just want to present you my point of view, but I leave the decision to you.

belt_nlp/bert_regressor_truncated.py Show resolved Hide resolved
notebooks/requirements.txt Outdated Show resolved Hide resolved
notebooks/binary_classification/base.ipynb Show resolved Hide resolved
notebooks/multiclass/base.ipynb Outdated Show resolved Hide resolved
@mwachnicki
Copy link
Collaborator

I would also love to see the same basic tests for the Regressor classes.

from pathlib import Path
from shutil import rmtree

import numpy as np
Copy link
Collaborator

Choose a reason for hiding this comment

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

numpy is not used

Comment on lines +6 to +7
from belt_nlp.bert_regressor_truncated import BertRegressorTruncated
MODEL_PARAMS = {"batch_size": 1, "learning_rate": 5e-5, "epochs": 1, "device": "cpu"}
Copy link
Collaborator

Choose a reason for hiding this comment

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

There should be a blank line in between.


x_test = ["nice"] * 99 + ["bad"] * 1

model.fit(x_train, y_train)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Right now, y_train expects list[bool], so the type hint should be updated.

assert scores.shape == torch.Size([2, 1])


def test_regression_order():
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think that for both classifiers and regressors prediction_order is the appropriate name.

predictions is used in the docstring anyway ;)

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.

None yet

2 participants