Skip to content

Fix predict in cropped mode, changed behavior of predict_proba #171

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

Merged
merged 6 commits into from
Nov 6, 2020

Conversation

sliwy
Copy link
Collaborator

@sliwy sliwy commented Sep 25, 2020

Resolves #157

As reported in #135 we had a bug in cropped decoding mode, so we did not return values that corresponded to prediction output of our models. Averaging over crops was missing before returning predictions so predict returned argmax over wrong axis.

I've found two possible options to fix that:

  1. Keep predict_proba return raw predictions (n_examples x n_classes x n_crops) and give users possibility to aggregate crops by themselves. Do averaging over crops in predict method.
  2. Make predict_proba return average of all crops (n_examples x n_classes). This has at least correct size when interpreting as probabilities (we don't assure that those are valid probabilities, just output of torch Module and may need some nonlinearity at the end). If a user would like to use predictions per crop than he/she needs to use skorch forward method. I assume that this is for more advanced users.

I decided to use second option as it sounds to me more user-friendly.

I added tests for EEGClassifier and EEGRegressor checking if predicted values are correct (there are some parts repeated in both tests (like MockModule, MockDataset), are you ok with that in tests or do you prefer to create a separated module for that?).

@robintibor
Copy link
Contributor

Looks good to me! I think the duplication for mockstuff is maybe still acceptable, definitely if we need again should move to separate file.
@gemeinl can you maybe briefly check if what @sliwy wrote is fine for you as well? Then I would merge already.

@robintibor
Copy link
Contributor

Ah one thing why did you name it "test_unit_eeg_classifier.py" should be "test_eeg_classifier.py"

@robintibor
Copy link
Contributor

In case it was because of pytest issue, fix in that way: pytest-dev/pytest#3151 (comment)

@sliwy
Copy link
Collaborator Author

sliwy commented Sep 28, 2020

@robintibor yes, it was because of that pytest issue; I added init.py to all folders with tests and changed tests' names

@@ -185,3 +185,42 @@ def _default_callbacks(self):
),
("print_log", PrintLog()),
]

def predict_proba(self, X):
Copy link
Collaborator

Choose a reason for hiding this comment

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

to me it does not make sense to have a predict_proba for a regressor

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

predict_proba is already implemented in skorch, so this changes the behavior in cropped mode to return averaged predictions per trial not raw predictions per crop. After the change it would be consistent with EEGClassifier predict_proba and predict behavior.

@agramfort
Copy link
Collaborator

agramfort commented Sep 30, 2020 via email

@sliwy
Copy link
Collaborator Author

sliwy commented Sep 30, 2020

@agramfort I don't think that it has any connection with sklearn decision_function. It's rather a skorch thing. Our EEGRegressor inherits from skorch NeuralNetRegressor class which has predict_proba method implemented. It returns the output of the module's forward method as a numpy array, we can call it raw predictions.
As we modified EEGClassifier behavior to return aggregated values per trial in cropped mode (instead of raw) I think that it is good to have consistent behavior of predict_proba method for EEGClassifier and EEGRegressor. Then instead of returning predictions per crop for regressor and predictions per trial for classifier it is better to return predictions per trial for both classifier and regressor.

At this moment, EEGRegressor in cropped mode returns raw predictions per crop for both predict_proba and predict. In skorch regressor predict returns the same output as predict_proba, so for me, it is better to modify predict_proba to affect both methods.

@agramfort
Copy link
Collaborator

predict_proba for a regressor is for me evil. Maybe @thomasjpfan can shed some light on this decision in skorch?

@sliwy
Copy link
Collaborator Author

sliwy commented Sep 30, 2020

@agramfort just to clear it a little bit more, predict_proba is implemented in skorch NeuralNet which is a parent class for NeuralNetRegressor. It does not change much, predict_proba can be used in NeuralNetRegressor which is'evil' but it may explain somehow why it looks like that. Let's wait for comment of @thomasjpfan

@sliwy sliwy closed this Sep 30, 2020
@sliwy sliwy reopened this Sep 30, 2020
@thomasjpfan
Copy link

predict_proba in the regressor does look strange to me and it would make sense to remove from NeuralNetRegressor. Currently NeuralNetRegressor, predict will do the same thing as predict_proba.

Maybe @BenjaminBossan would have insight into why NeuralNetRegressor defines predict_proba.

@BenjaminBossan
Copy link

There is no particular reason, really. It is present on NeuralNet and it would allow you to easily add another "predict mode" to your regressor if you choose to customize it.

In case you'd rather not have the method, you could declare it a property and raise an AttributeError. If we want to remove it in skorch, it would probably require deprecation cycle.

@agramfort
Copy link
Collaborator

agramfort commented Oct 2, 2020 via email

@robintibor
Copy link
Contributor

So I see two options:

  1. Create EEGNeuralNet superclass to solve it
  2. Leave it as in this PR, live with predict_proba in regressor

I think 2. is simply more practical now what do you think @sliwy ?

@sliwy
Copy link
Collaborator Author

sliwy commented Nov 3, 2020

@robintibor I agree with you, it's simpler. If we merge it we will have the same API as skorch. Both predict and predict_proba will work properly for cropped and trialwise decoding. On the other hand, raising AttributeError is not a big problem, I can do this, but I am not really convinced if we should do that.

@agramfort
Copy link
Collaborator

agramfort commented Nov 3, 2020 via email

@robintibor
Copy link
Contributor

yeah can you add such a comment @sliwy ? that would be great, then I would merge.

@sliwy
Copy link
Collaborator Author

sliwy commented Nov 5, 2020

done @robintibor, I added a comment with an explanation why we implement predict_proba for regressor and warning in the docstring to warn users that regressor does not return probabilities and it's better to use predict

@robintibor
Copy link
Contributor

amazing. Since previous commits were fine on travis and now only acceptance tests fail again, have to assume it is another library change (skorch?), therefore merging..

thanks for your work!! :)

@robintibor robintibor mentioned this pull request Jun 11, 2021
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.

Fix predict in cropped mode
5 participants