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

Migrate to PyTorch #191

Merged
merged 85 commits into from
Apr 13, 2021
Merged

Migrate to PyTorch #191

merged 85 commits into from
Apr 13, 2021

Conversation

kiudee
Copy link
Owner

@kiudee kiudee commented Apr 13, 2021

Description

Replaces Tensorflow v1.x with PyTorch 1.8.
The most important neural network learners have been converted:

  • FATE
  • FETA
  • CmpNet
  • RankNet

In order to fully support scikit-learn interoperability, we also include skorch now as dependency.

The old master branch corresponding to v1.x.y will be continued here to facilitate bug fixes:
https://github.com/kiudee/cs-ranking/tree/v1.x

Motivation and Context

The code base depends heavily on Tensorflow v1, which is no longer updated due to the major update to Tensorflow v2. Since a major rewrite to support Tensorflow v2 would have been necessary, we deliberated whether it is better to switch over to PyTorch instead. Finally, we decided to go for PyTorch, since we also switched to it on other projects and the momentum of the research community is currently behind it.

Special thanks go to @timokau who worked hard on making this migration a reality.

How Has This Been Tested?

The tests of the learners have been adapted to use PyTorch. The tests were run locally and on GitHub Actions to confirm that everything passes.

Does this close/impact existing issues?

Resolves #125, resolves #153, resolves #146, fixes #130, closes #105, closes #43.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.

timokau added 30 commits April 4, 2021 01:09
This is the start of the pytorch migration. Removing all tensorflow
components as a first step simplifies the dependency situation.
They are no longer necessary since all tensorflow components were
removed.
As suggested by pycodestyle E741.
A hotfix is available, but not committed to the repository. See the
comment in `shell.nix` for more details.
They can also be useful for targets other than shell.nix, such as a
nix-based pre-commit check.
Python 3.7 is not officially supported anymore. Python 3.9 is released
already, but let's update to 3.8 first.
In preparation for the pytorch migration.
In preparation of adding new entries to the list.
This is part of the ongoing pytorch migration. We will use skorch as the
basis for our pytorch estimators. That will make it easier to be
compliant with the scikit-learn estimator API.

Ranking and  (general/discrete) choice estimators are often based on
some sort of scoring. The task specific estimators make it easy to
derive concrete estimators from a scoring module.
This adds a scoring module and the derived estimators for the FATE
approach. The architecture is modular, so it should be easy to
experiment with new ways to put the estimators together. This is a big
commit. Multiple smaller ones that add the separate components (some of
which are structural or can be useful outside of FATE and therefore
could be considered features on their own) would probably have been
better. Splitting it up now would take more time and is not worth it in
this case though.
This simplifies interchangeable use of pytorch estimators and other
estimators.
The "linear" implementations have been removed. The existing estimators
do not expect `epochs` or `validation_split` parameters. The `verbose`
parameter is accepted by some estimators, but defaults to `False` and is
not expected by any of the ranking or discrete choice estimators.
The configuration is based on the configuration of the old (tensorflow
based) fate estimators in the tests. The tensorflow tests used a 10%
validation split, but still verified the performance in-sample. The
validation was not actually used. Therefore I haven't kept that
behavior.

The performance isn't the same. Especially the performance on the choice
task seems worse if we trust the test results. We shouldn't read too
much into that yet. The test is mostly for basic functionality and not a
reliable performance indicator. The sample size is small.
The binder logo (badge.svg vs badge_logo.svg) differs between the two
files, but either should be good.
There is now a pytorch implementation of the FATE estimators.
This is similar to the "optimizer_common_args" dictionary that used to
exist. This version contains skorch-specific arguments, which also
includes the train split and the number of epochs. There are only the
FATE based estimators now, but this would get repetitive when the other
approaches are included again.
PyTorch migration: Remove tensorflow components, add FATE estimators
This is mostly an import from the "proof of concept" implementation with
some small changes. It is just a starting point and not polished yet.
The old test of the tensorflow version only exercised the "no zeroth
order model" configuration. This adds basic tests for both
configurations.
These estimators (different tasks, same scoring module) are pretty
repetitive. They are slightly different, so we need different classes.
We could add an additional `FETABasedEstimator` mixin but that would
probably just make it unnecessarily complicated. The current way to
define the estimators also makes it easier to adjust them and play with
different configurations.

The repetitive definition and the additional mixin both have their
advantages. I think we should stick to the repetitive definition for
now.
The old test of the tensorflow version only exercised the estimator with
the zeroth order model enabled. This adds basic tests for both
configurations.
timokau and others added 24 commits April 8, 2021 23:54
This is somewhat contrary to the comment I wrote in the general choice
test. I have since noticed a similar issue with RankNet in the tests. It
seems that SELU just works better, at least for these tiny toy problems.
Its already the default for the other pytorch based estimators. I think
it makes sense to use it as the default for CmpNet as well.
It can be useful to compare the network sizes that are used for the
different estimators at a glance. The CmpNet test specifications already
list the `n_hidden` and `n_unit` arguments even though they match the
default values. This change makes the specifications more consistent.
I have added them in alphabetical order, which is why the order has
changed in `discretechoice.rst`.
PyTorch migration: Finishing touches
For now we will only test Python 3.8 and run the following steps:

* Pre-commit (incl caching)
* Nox
* Coverage
Remove the build status, until GitHub Actions is running on master
@kiudee kiudee added enhancement New feature or request dependencies Pull requests that update a dependency file labels Apr 13, 2021
@codecov
Copy link

codecov bot commented Apr 13, 2021

Codecov Report

Merging #191 (7c1f922) into master (1217c46) will decrease coverage by 4.90%.
The diff coverage is 87.94%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #191      +/-   ##
==========================================
- Coverage   57.04%   52.14%   -4.91%     
==========================================
  Files         113      102      -11     
  Lines        6560     5090    -1470     
==========================================
- Hits         3742     2654    -1088     
+ Misses       2818     2436     -382     
Impacted Files Coverage Δ
csrank/choicefunction/__init__.py 100.00% <ø> (ø)
csrank/choicefunction/baseline.py 37.93% <0.00%> (-1.36%) ⬇️
csrank/constants.py 100.00% <ø> (ø)
csrank/core/__init__.py 100.00% <ø> (ø)
csrank/dataset_reader/dataset_reader.py 68.57% <ø> (+27.39%) ⬆️
csrank/dataset_reader/discretechoice/util.py 22.41% <ø> (+6.89%) ⬆️
...nk/dataset_reader/letor_listwise_dataset_reader.py 14.56% <ø> (ø)
...ank/dataset_reader/letor_ranking_dataset_reader.py 14.52% <ø> (ø)
csrank/dataset_reader/util.py 36.44% <ø> (+18.64%) ⬆️
csrank/discretechoice/__init__.py 100.00% <ø> (ø)
... and 87 more

@kiudee kiudee merged commit 639473b into master Apr 13, 2021
@kiudee kiudee deleted the pytorch-migration branch April 13, 2021 15:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependencies Pull requests that update a dependency file enhancement New feature or request
Projects
None yet
2 participants