Skip to content

Commit d2967d9

Browse files
BordaomrywilliamFalcon
authored
update hparams, allow OmegaConf (Lightning-AI#2047)
* DictConf * inits * Apply suggestions from code review Co-authored-by: Omry Yadan <omry@fb.com> * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * atrib * wip * wip * wip * added hparams test * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Update test_hparams.py * added hparams test * added hparams test * pep8 * pep8 * pep8 * docs * wip * wip * clean * review @omry * Update docs/source/hyperparameters.rst Co-authored-by: Omry Yadan <omry@fb.com> Co-authored-by: Omry Yadan <omry@fb.com> Co-authored-by: William Falcon <waf2107@columbia.edu>
1 parent c09317e commit d2967d9

File tree

15 files changed

+765
-396
lines changed

15 files changed

+765
-396
lines changed

CHANGELOG.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
7676

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

79-
- Fixed an issue where local variables were being collected into module_arguments ([#2048](https://github.com/PyTorchLightning/pytorch-lightning/pull/2048))
80-
81-
- 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))
79+
- 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))
8280

8381
## [0.7.6] - 2020-05-16
8482

docs/source/hyperparameters.rst

Lines changed: 45 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -102,47 +102,51 @@ Finally, make sure to start the training like so:
102102
103103
LightningModule hyperparameters
104104
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
105+
Often times we train many versions of a model. You might share that model or come back to it a few months later
106+
at which point it is very useful to know how that model was trained (ie: what learning_rate, neural network, etc...).
105107

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

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

111-
1. It's more readable to specify all the arguments that go into a module (with default values).
112-
This helps users of your module know everything that is required to run this.
114+
.. code-block:: python
115+
116+
class LitMNIST(LightningModule):
117+
118+
def __init__(self, layer_1_dim=128, learning_rate=1e-2, **kwargs):
119+
super().__init__()
120+
# call this to save (layer_1_dim=128, learning_rate=1e-4) to the checkpoint
121+
self.save_hyperparameters()
122+
123+
# equivalent
124+
self.save_hyperparameters(['layer_1_dim', 'learning_rate'])
125+
126+
# this now works
127+
self.hparams.layer_1_dim
113128
114-
.. testcode::
129+
130+
2. Sometimes your init might have objects or other parameters you might not want to save.
131+
In that case, choose only a few
132+
133+
.. code-block:: python
115134
116135
class LitMNIST(LightningModule):
117136
118-
def __init__(self, layer_1_dim=128, layer_2_dim=256, learning_rate=1e-4, batch_size=32, **kwargs):
137+
def __init__(self, loss_fx, generator_network, layer_1_dim=128 **kwargs):
119138
super().__init__()
120139
self.layer_1_dim = layer_1_dim
121-
self.layer_2_dim = layer_2_dim
122-
self.learning_rate = learning_rate
123-
self.batch_size = batch_size
140+
self.loss_fx = loss_fx
124141
125-
self.layer_1 = torch.nn.Linear(28 * 28, self.layer_1_dim)
126-
self.layer_2 = torch.nn.Linear(self.layer_1_dim, self.layer_2_dim)
127-
self.layer_3 = torch.nn.Linear(self.layer_2_dim, 10)
142+
# call this to save (layer_1_dim=128) to the checkpoint
143+
self.save_hyperparameters(['layer_1_dim'])
128144
129-
def train_dataloader(self):
130-
return DataLoader(mnist_train, batch_size=self.batch_size)
145+
# to load specify the other args
146+
model = LitMNIST.load_from_checkpoint(PATH, loss_fx=torch.nn.SomeOtherLoss, generator_network=MyGenerator())
131147
132-
def configure_optimizers(self):
133-
return Adam(self.parameters(), lr=self.learning_rate)
134148
135-
@staticmethod
136-
def add_model_specific_args(parent_parser):
137-
parser = ArgumentParser(parents=[parent_parser], add_help=False)
138-
parser.add_argument('--layer_1_dim', type=int, default=128)
139-
parser.add_argument('--layer_2_dim', type=int, default=256)
140-
parser.add_argument('--batch_size', type=int, default=64)
141-
parser.add_argument('--learning_rate', type=float, default=0.002)
142-
return parser
143-
144-
2. You can also pass in a dict or Namespace, but this obscures the parameters your module is looking
145-
for. The user would have to search the file to find what is parametrized.
149+
3. Assign to `self.hparams`. Anything assigned to `self.hparams` will also be saved automatically
146150

147151
.. code-block:: python
148152
@@ -160,39 +164,29 @@ for. The user would have to search the file to find what is parametrized.
160164
def train_dataloader(self):
161165
return DataLoader(mnist_train, batch_size=self.hparams.batch_size)
162166
163-
One way to get around this is to convert a Namespace or dict into key-value pairs using `**`
164-
165-
.. code-block:: python
166-
167-
parser = ArgumentParser()
168-
parser = LitMNIST.add_model_specific_args(parser)
169-
args = parser.parse_args()
170-
dict_args = vars(args)
171-
model = LitMNIST(**dict_args)
172-
173-
Within any LightningModule all the arguments you pass into your `__init__` will be stored in
174-
the checkpoint so that you know all the values that went into creating this model.
175-
176-
We will also add all of those values to the TensorBoard hparams tab (unless it's an object which
177-
we won't). We also will store those values into checkpoints for you which you can use to init your
178-
models.
167+
4. You can also save full objects such as `dict` or `Namespace` to the checkpoint.
179168

180169
.. code-block:: python
181170
171+
# using a argparse.Namespace
182172
class LitMNIST(LightningModule):
183173
184-
def __init__(self, layer_1_dim, some_other_param):
174+
def __init__(self, conf, *args, **kwargs):
185175
super().__init__()
186-
self.layer_1_dim = layer_1_dim
187-
self.some_other_param = some_other_param
176+
self.hparams = conf
188177
189-
self.layer_1 = torch.nn.Linear(28 * 28, self.layer_1_dim)
178+
# equivalent
179+
self.save_hyperparameters(conf)
190180
191-
self.layer_2 = torch.nn.Linear(self.layer_1_dim, self.some_other_param)
192-
self.layer_3 = torch.nn.Linear(self.some_other_param, 10)
181+
self.layer_1 = torch.nn.Linear(28 * 28, self.hparams.layer_1_dim)
182+
self.layer_2 = torch.nn.Linear(self.hparams.layer_1_dim, self.hparams.layer_2_dim)
183+
self.layer_3 = torch.nn.Linear(self.hparams.layer_2_dim, 10)
193184
185+
conf = OmegaConf.create(...)
186+
model = LitMNIST(conf)
194187
195-
model = LitMNIST(10, 20)
188+
# this works
189+
model.hparams.anything
196190
197191
198192
Trainer args

0 commit comments

Comments
 (0)