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

update hparams, allow OmegaConf #2047

Merged
merged 51 commits into from
Jun 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
f5e5e45
DictConf
Borda Jun 1, 2020
8f9b530
inits
Borda Jun 1, 2020
973502f
Apply suggestions from code review
Borda Jun 3, 2020
50e4e6a
wip
Borda Jun 4, 2020
a2bf308
wip
Borda Jun 4, 2020
89a500a
wip
Borda Jun 4, 2020
ae288e0
wip
Borda Jun 4, 2020
0662707
wip
Borda Jun 4, 2020
c7e0b74
wip
Borda Jun 4, 2020
7f38ca0
wip
Borda Jun 4, 2020
771fd30
wip
Borda Jun 4, 2020
dc83ccf
wip
Borda Jun 5, 2020
8ebcaf7
wip
Borda Jun 5, 2020
3761e98
atrib
Borda Jun 5, 2020
f952aae
wip
Borda Jun 5, 2020
f9e2ffa
wip
Borda Jun 5, 2020
bbd471b
wip
Borda Jun 6, 2020
73ab2ee
added hparams test
williamFalcon Jun 6, 2020
5d4fd39
wip
Borda Jun 6, 2020
607b243
wip
Borda Jun 6, 2020
b21b6e6
wip
Borda Jun 6, 2020
16b29ed
wip
Borda Jun 6, 2020
ac1e6a8
wip
Borda Jun 6, 2020
c5fbc25
wip
Borda Jun 6, 2020
4cceca6
wip
Borda Jun 6, 2020
db4204e
wip
Borda Jun 6, 2020
cfe890d
wip
Borda Jun 6, 2020
3095b11
wip
Borda Jun 6, 2020
f585341
wip
Borda Jun 6, 2020
9626ae1
wip
Borda Jun 7, 2020
8a60394
wip
Borda Jun 7, 2020
74a75be
wip
Borda Jun 7, 2020
a356cb0
wip
Borda Jun 7, 2020
364f13d
wip
Borda Jun 7, 2020
3c55c02
wip
Borda Jun 7, 2020
a5924b9
wip
Borda Jun 7, 2020
c06555b
wip
Borda Jun 7, 2020
688a727
wip
Borda Jun 7, 2020
72a93b7
wip
Borda Jun 7, 2020
99685ea
Update test_hparams.py
williamFalcon Jun 7, 2020
446d5e2
added hparams test
williamFalcon Jun 7, 2020
6f996bb
added hparams test
williamFalcon Jun 7, 2020
8546b8c
pep8
williamFalcon Jun 7, 2020
974bb53
pep8
williamFalcon Jun 7, 2020
4e59c9a
pep8
williamFalcon Jun 7, 2020
367d182
docs
williamFalcon Jun 7, 2020
0a7a164
wip
Borda Jun 7, 2020
bc4da6e
wip
Borda Jun 7, 2020
d97b3c8
clean
Borda Jun 7, 2020
38e9686
review @omry
Borda Jun 7, 2020
e532796
Update docs/source/hyperparameters.rst
Borda Jun 7, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).

- Allow use of same `WandbLogger` instance for multiple training loops ([#2055](https://github.com/PyTorchLightning/pytorch-lightning/pull/2055))

- Fixed an issue where local variables were being collected into module_arguments ([#2048](https://github.com/PyTorchLightning/pytorch-lightning/pull/2048))

- Fixed an issue with `auto_collect_arguments` collecting local variables that are not constructor arguments and not working for signatures that have the instance not named `self` ([#2048](https://github.com/PyTorchLightning/pytorch-lightning/pull/2048))
- Fixed an issue with `_auto_collect_arguments` collecting local variables that are not constructor arguments and not working for signatures that have the instance not named `self` ([#2048](https://github.com/PyTorchLightning/pytorch-lightning/pull/2048))
Borda marked this conversation as resolved.
Show resolved Hide resolved

## [0.7.6] - 2020-05-16

Expand Down
96 changes: 45 additions & 51 deletions docs/source/hyperparameters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,47 +102,51 @@ Finally, make sure to start the training like so:

LightningModule hyperparameters
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Often times we train many versions of a model. You might share that model or come back to it a few months later
at which point it is very useful to know how that model was trained (ie: what learning_rate, neural network, etc...).

.. warning:: The use of `hparams` is no longer recommended (but still supported)
Lightning has a few ways of saving that information for you in checkpoints and yaml files. The goal here is to
improve readability and reproducibility

LightningModule is just an nn.Module, you can use it as you normally would. However, there are
some best practices to improve readability and reproducibility.
1. The first way is to ask lightning to save the values anything in the __init__ for you to the checkpoint. This also
makes those values available via `self.hparams`.

1. It's more readable to specify all the arguments that go into a module (with default values).
This helps users of your module know everything that is required to run this.
.. code-block:: python

class LitMNIST(LightningModule):

def __init__(self, layer_1_dim=128, learning_rate=1e-2, **kwargs):
super().__init__()
# call this to save (layer_1_dim=128, learning_rate=1e-4) to the checkpoint
self.save_hyperparameters()

# equivalent
self.save_hyperparameters(['layer_1_dim', 'learning_rate'])

# this now works
self.hparams.layer_1_dim

.. testcode::

2. Sometimes your init might have objects or other parameters you might not want to save.
In that case, choose only a few

.. code-block:: python

class LitMNIST(LightningModule):

def __init__(self, layer_1_dim=128, layer_2_dim=256, learning_rate=1e-4, batch_size=32, **kwargs):
def __init__(self, loss_fx, generator_network, layer_1_dim=128 **kwargs):
super().__init__()
self.layer_1_dim = layer_1_dim
self.layer_2_dim = layer_2_dim
self.learning_rate = learning_rate
self.batch_size = batch_size
self.loss_fx = loss_fx

self.layer_1 = torch.nn.Linear(28 * 28, self.layer_1_dim)
self.layer_2 = torch.nn.Linear(self.layer_1_dim, self.layer_2_dim)
self.layer_3 = torch.nn.Linear(self.layer_2_dim, 10)
# call this to save (layer_1_dim=128) to the checkpoint
self.save_hyperparameters(['layer_1_dim'])

def train_dataloader(self):
return DataLoader(mnist_train, batch_size=self.batch_size)
# to load specify the other args
model = LitMNIST.load_from_checkpoint(PATH, loss_fx=torch.nn.SomeOtherLoss, generator_network=MyGenerator())

def configure_optimizers(self):
return Adam(self.parameters(), lr=self.learning_rate)

@staticmethod
def add_model_specific_args(parent_parser):
parser = ArgumentParser(parents=[parent_parser], add_help=False)
parser.add_argument('--layer_1_dim', type=int, default=128)
parser.add_argument('--layer_2_dim', type=int, default=256)
parser.add_argument('--batch_size', type=int, default=64)
parser.add_argument('--learning_rate', type=float, default=0.002)
return parser

2. You can also pass in a dict or Namespace, but this obscures the parameters your module is looking
for. The user would have to search the file to find what is parametrized.
3. Assign to `self.hparams`. Anything assigned to `self.hparams` will also be saved automatically

.. code-block:: python

Expand All @@ -160,39 +164,29 @@ for. The user would have to search the file to find what is parametrized.
def train_dataloader(self):
return DataLoader(mnist_train, batch_size=self.hparams.batch_size)

One way to get around this is to convert a Namespace or dict into key-value pairs using `**`

.. code-block:: python

parser = ArgumentParser()
parser = LitMNIST.add_model_specific_args(parser)
args = parser.parse_args()
dict_args = vars(args)
model = LitMNIST(**dict_args)

Within any LightningModule all the arguments you pass into your `__init__` will be stored in
the checkpoint so that you know all the values that went into creating this model.

We will also add all of those values to the TensorBoard hparams tab (unless it's an object which
we won't). We also will store those values into checkpoints for you which you can use to init your
models.
4. You can also save full objects such as `dict` or `Namespace` to the checkpoint.
Borda marked this conversation as resolved.
Show resolved Hide resolved

.. code-block:: python

# using a argparse.Namespace
class LitMNIST(LightningModule):

def __init__(self, layer_1_dim, some_other_param):
def __init__(self, conf, *args, **kwargs):
super().__init__()
self.layer_1_dim = layer_1_dim
self.some_other_param = some_other_param
self.hparams = conf

self.layer_1 = torch.nn.Linear(28 * 28, self.layer_1_dim)
# equivalent
self.save_hyperparameters(conf)

self.layer_2 = torch.nn.Linear(self.layer_1_dim, self.some_other_param)
self.layer_3 = torch.nn.Linear(self.some_other_param, 10)
self.layer_1 = torch.nn.Linear(28 * 28, self.hparams.layer_1_dim)
self.layer_2 = torch.nn.Linear(self.hparams.layer_1_dim, self.hparams.layer_2_dim)
self.layer_3 = torch.nn.Linear(self.hparams.layer_2_dim, 10)

conf = OmegaConf.create(...)
model = LitMNIST(conf)

model = LitMNIST(10, 20)
# this works
model.hparams.anything


Trainer args
Expand Down
Loading