@@ -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