Skip to content

Expectation when cloning a net #521

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

Closed
BenjaminBossan opened this issue Sep 7, 2019 · 3 comments · Fixed by #617
Closed

Expectation when cloning a net #521

BenjaminBossan opened this issue Sep 7, 2019 · 3 comments · Fixed by #617
Labels

Comments

@BenjaminBossan
Copy link
Collaborator

At the moment, when we use sklearn.base.clone on a fitted net, we receive a fitted net. In sklearn, however, we get back an unfitted estimator. The main reason is that out net.get_params() also returns learned attributes (ending on _, like module_).

For sklearn compliance, we might want to change this behavior. However, I wonder if this can have some unintended side-effects are might break backwards-compatibility for too many people (say, making it so that old pickle files no longer work?).

@BenjaminBossan
Copy link
Collaborator Author

One possibility I could imagine: We don't change the behavior of get_params yet, only prepare everything for the eventual change. Then, after the next release, we change get_params to be more in line with what sklearn does.

Unfortunately, it's not really possible to slap a deprecation warning onto get_params. I would be afraid that it would trigger too many false positives. Instead, we have to make clear in the release text that the change will happen and what users need to do to prepare for it, then hope they read it. I believe we should encourage using copy.deepcopy for the purpose instead of clone.

Overall, most people shouldn't be affected by the change, but I can imagine it leads to some surprising bugs, as many are not even aware when get_params is actually used under the hood (e.g. for grid search).

@thomasjpfan
Copy link
Member

I agree with being compatible with the sklearn api of clone.

making it so that old pickle files no longer work?

I do not think pickling will be affected by this change. Pickling serializes all the attribute regardless of how get_params work.

as many are not even aware when get_params is actually used under the hood (e.g. for grid search).

Since grid search calls fit, even with the fitted net it will restarted from the beginning. If a user sets warm_start=True or passes in a module instance, I would say the grid search will give false results, since the training is continuing where the last parameter has left off.

@BenjaminBossan
Copy link
Collaborator Author

Since grid search calls fit, even with the fitted net it will restarted from the beginning. If a user sets warm_start=True or passes in a module instance, I would say the grid search will give false results, since the training is continuing where the last parameter has left off.

That would be my biggest worry with the current situation, especially since it's not easy to notice.

I do not think pickling will be affected by this change. Pickling serializes all the attribute regardless of how get_params work.

Pickling will probably not be a problem but still some code could break because of the change.

BenjaminBossan added a commit that referenced this issue Aug 30, 2020
This release of skorch contains a few minor improvements and some nice additions. As always, we fixed a few bugs and improved the documentation. Our [learning rate scheduler](https://skorch.readthedocs.io/en/latest/callbacks.html#skorch.callbacks.LRScheduler) now optionally logs learning rate changes to the history; moreover, it now allows the user to choose whether an update step should be made after each batch or each epoch.

If you always longed for a metric that would just use whatever is defined by your criterion, look no further than [`loss_scoring`](https://skorch.readthedocs.io/en/latest/scoring.html#skorch.scoring.loss_scoring). Also, skorch now allows you to easily change the kind of nonlinearity to apply to the module's output when `predict` and `predict_proba` are called, by passing the `predict_nonlinearity` argument.

Besides these changes, we improved the customization potential of skorch. First of all, the `criterion` is now set to `train` or `valid`, depending on the phase -- this is useful if the criterion should act differently during training and validation. Next we made it easier to add custom modules, optimizers, and criteria to your neural net; this should facilitate implementing architectures like GANs. Consult the [docs](https://skorch.readthedocs.io/en/latest/user/neuralnet.html#subclassing-neuralnet) for more on this. Conveniently, [`net.save_params`](https://skorch.readthedocs.io/en/latest/net.html#skorch.net.NeuralNet.save_params) can now persist arbitrary attributes, including those custom modules.
As always, these improvements wouldn't have been possible without the community. Please keep asking questions, raising issues, and proposing new features. We are especially grateful to those community members, old and new, who contributed via PRs:

```
Aaron Berk
guybuk
kqf
Michał Słapek
Scott Sievert
Yann Dubois
Zhao Meng
```

Here is the full list of all changes:

### Added

- Added the `event_name` argument for `LRScheduler` for optional recording of LR changes inside `net.history`. NOTE: Supported only in Pytorch>=1.4
- Make it easier to add custom modules or optimizers to a neural net class by automatically registering them where necessary and by making them available to set_params
- Added the `step_every` argument for `LRScheduler` to set whether the scheduler step should be taken on every epoch or on every batch.
- Added the `scoring` module with `loss_scoring` function, which computes the net's loss (using `get_loss`) on provided input data.
- Added a parameter `predict_nonlinearity` to `NeuralNet` which allows users to control the nonlinearity to be applied to the module output when calling `predict` and `predict_proba` (#637, #661)
- Added the possibility to save the criterion with `save_params` and with checkpoint callbacks
- Added the possibility to save custom modules with `save_params` and with checkpoint callbacks

### Changed

- Removed support for schedulers with a `batch_step()` method in `LRScheduler`.
- Raise `FutureWarning` in `CVSplit` when `random_state` is not used. Will raise an exception in a future (#620)
- The behavior of method `net.get_params` changed to make it more consistent with sklearn: it will no longer return "learned" attributes like `module_`; therefore, functions like `sklearn.base.clone`, when called with a fitted net, will no longer return a fitted net but instead an uninitialized net; if you want a copy of a fitted net, use `copy.deepcopy` instead;`net.get_params` is used under the hood by many sklearn functions and classes, such as `GridSearchCV`, whose behavior may thus be affected by the change. (#521, #527)
- Raise `FutureWarning` when using `CyclicLR` scheduler, because the default behavior has changed from taking a step every batch to taking a step every epoch. (#626)
- Set train/validation on criterion if it's a PyTorch module (#621)
- Don't pass `y=None` to `NeuralNet.train_split` to enable the direct use of split functions without positional `y` in their signatures. This is useful when working with unsupervised data (#605).
- `to_numpy` is now able to unpack dicts and lists/tuples (#657, #658)
- When using `CrossEntropyLoss`, softmax is now automatically applied to the output when calling `predict` or `predict_proba`

### Fixed

- Fixed a bug where `CyclicLR` scheduler would update during both training and validation rather than just during training.
- Fixed a bug introduced by moving the `optimizer.zero_grad()` call outside of the train step function, making it incompatible with LBFGS and other optimizers that call the train step several times per batch (#636)
- Fixed pickling of the `ProgressBar` callback (#656)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants