From 6fa7ec876acb9a2e2588d4eefebafa4ed334c414 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 11:35:15 -0500 Subject: [PATCH 01/21] Update README.md --- README.md | 281 +++++++++++++++++++++--------------------------------- 1 file changed, 111 insertions(+), 170 deletions(-) diff --git a/README.md b/README.md index 2fd8cff0da46f..026483c7ac20c 100644 --- a/README.md +++ b/README.md @@ -54,14 +54,27 @@ pip install pytorch-lightning ## What is it? Lightning is a way to organize your PyTorch code to decouple the science code from the engineering. It's more of a style-guide than a framework. -By refactoring your code, we can automate most of the non-research code. Lightning guarantees tested, correct, modern best practices for the automated parts. +Refactor your research code into a LightningModule +![PT to PL](docs/source/_images/lightning_module/pt_to_pl.png) -Here's an example of how to organize PyTorch code into the LightningModule. +And Lightning automates the rest! +![PT to PL](docs/source/_images/lightning_module/pt_trainer.png) -![PT to PL](docs/source/_images/mnist_imgs/pt_to_pl.jpg) +Lightning guarantees riguously tested, correct, modern best practices for the automated parts. -- If you are a researcher, Lightning is infinitely flexible, you can modify everything down to the way .backward is called or distributed is set up. -- If you are a scientist or production team, lightning is very simple to use with best practice defaults. +## How flexible is it? +As you see, you're just organizing your PyTorch code - there's no abstraction. + +And for the stuff that the Trainer abstracts out you can [override any part](https://pytorch-lightning.readthedocs.io/en/latest/introduction_guide.html#extensibility) you want to do things like implement your own distributed training, 16-bit precision, or even a custom backwards pass. + +For anything else you might need, we have an extensive [callback system](https://pytorch-lightning.readthedocs.io/en/latest/introduction_guide.html#callbacks) you can use to add arbitrary functionality not implemented by our team in the Trainer. + +## Who is Lightning for? +- Professional researchers +- PhD students +- Corporate production teams + +If you're just getting into deep learning, we recommend you learn PyTorch first! Once you've implemented a few models, come back and use all the advanced features of Lightning :) ## What does lightning control for me? @@ -71,18 +84,17 @@ This is how lightning separates the science (red) from the engineering (blue). ![Overview](docs/source/_static/images/pl_overview.gif) ## How much effort is it to convert? -You're probably tired of switching frameworks at this point. But it is a very quick process to refactor into the Lightning format (ie: hours). [Check out this tutorial](https://towardsdatascience.com/from-pytorch-to-pytorch-lightning-a-gentle-introduction-b371b7caaf09). +If your code is not a huge mess you should be able to organize it into a LightningModule in less than 1 hour. +If your code IS a mess, then you needed to clean up anyhow ;) + +[Check out this step-by-step guide](https://towardsdatascience.com/from-pytorch-to-pytorch-lightning-a-gentle-introduction-b371b7caaf09). -## What are the differences with PyTorch? -If you're wondering what you gain out of refactoring your PyTorch code, [read this comparison!](https://towardsdatascience.com/from-pytorch-to-pytorch-lightning-a-gentle-introduction-b371b7caaf09) ## Starting a new project? [Use our seed-project aimed at reproducibility!](https://github.com/PytorchLightning/pytorch-lightning-conference-seed) ## Why do I want to use lightning? -Every research project starts the same, a model, a training loop, validation loop, etc. As your research advances, you're likely to need distributed training, 16-bit precision, checkpointing, gradient accumulation, etc. - -Lightning sets up all the boilerplate state-of-the-art training for you so you can focus on the research. +Although your research/production project might start simple, once you add things like GPU AND TPU training, 16-bit precision, etc, you end up spending more time engineering than researching. Lightning automates AND rigorously tests those parts for you. --- @@ -102,25 +114,18 @@ Lightning sets up all the boilerplate state-of-the-art training for you so you c --- -## How do I do use it? -Think about Lightning as refactoring your research code instead of using a new framework. The research code goes into a [LightningModule](https://pytorch-lightning.rtfd.io/en/latest/lightning-module.html) which you fit using a Trainer. +## Realistic example +Here's how you would organize a realistic PyTorch project into Lightning. -The LightningModule defines a *system* such as seq-2-seq, GAN, etc... It can ALSO define a simple classifier such as the example below. +![PT to PL](docs/source/_images/mnist_imgs/pt_to_pl.jpg) -To use lightning do 2 things: -1. [Define a LightningModule](https://pytorch-lightning.rtfd.io/en/latest/lightning-module.html) - ```python - import os - - import torch - from torch.nn import functional as F - from torch.utils.data import DataLoader - from torchvision.datasets import MNIST - from torchvision import transforms - - import pytorch_lightning as pl - - class CoolSystem(pl.LightningModule): +The LightningModule defines a *system* such as seq-2-seq, GAN, etc... It can ALSO define a simple classifier such as the example below. + +In summary, you: + +1. Define a [LightningModule](https://pytorch-lightning.rtfd.io/en/latest/lightning-module.html) +```python + class LitSystem(pl.LightningModule): def __init__(self): super(CoolSystem, self).__init__() @@ -129,102 +134,29 @@ To use lightning do 2 things: def forward(self, x): return torch.relu(self.l1(x.view(x.size(0), -1))) - - def training_step(self, batch, batch_idx): - # REQUIRED - x, y = batch - y_hat = self.forward(x) - loss = F.cross_entropy(y_hat, y) - tensorboard_logs = {'train_loss': loss} - return {'loss': loss, 'log': tensorboard_logs} - - def validation_step(self, batch, batch_idx): - # OPTIONAL - x, y = batch - y_hat = self.forward(x) - return {'val_loss': F.cross_entropy(y_hat, y)} - - def validation_end(self, outputs): - # OPTIONAL - avg_loss = torch.stack([x['val_loss'] for x in outputs]).mean() - tensorboard_logs = {'val_loss': avg_loss} - return {'avg_val_loss': avg_loss, 'log': tensorboard_logs} - def test_step(self, batch, batch_idx): - # OPTIONAL - x, y = batch - y_hat = self.forward(x) - return {'test_loss': F.cross_entropy(y_hat, y)} - - def test_end(self, outputs): - # OPTIONAL - avg_loss = torch.stack([x['test_loss'] for x in outputs]).mean() - tensorboard_logs = {'test_loss': avg_loss} - return {'avg_test_loss': avg_loss, 'log': tensorboard_logs} - - def configure_optimizers(self): - # REQUIRED - # can return multiple optimizers and learning_rate schedulers - # (LBFGS it is automatically supported, no need for closure function) - return torch.optim.Adam(self.parameters(), lr=0.02) - - @pl.data_loader - def train_dataloader(self): - # REQUIRED - return DataLoader(MNIST(os.getcwd(), train=True, download=True, transform=transforms.ToTensor()), batch_size=32) - - @pl.data_loader - def val_dataloader(self): - # OPTIONAL - return DataLoader(MNIST(os.getcwd(), train=True, download=True, transform=transforms.ToTensor()), batch_size=32) - - @pl.data_loader - def test_dataloader(self): - # OPTIONAL - return DataLoader(MNIST(os.getcwd(), train=False, download=True, transform=transforms.ToTensor()), batch_size=32) - ``` -2. Fit with a [trainer](https://pytorch-lightning.rtfd.io/en/latest/pytorch_lightning.trainer.html) - ```python - from pytorch_lightning import Trainer - - model = CoolSystem() - - # most basic trainer, uses good defaults - trainer = Trainer() - trainer.fit(model) - ``` - -Trainer sets up a tensorboard logger, early stopping and checkpointing by default (you can modify all of them or -use something other than tensorboard). - -Here are more advanced examples -```python -# train on cpu using only 10% of the data (for demo purposes) -trainer = Trainer(max_epochs=1, train_percent_check=0.1) - -# train on 4 gpus (lightning chooses GPUs for you) -# trainer = Trainer(max_epochs=1, gpus=4, distributed_backend='ddp') - -# train on 4 gpus (you choose GPUs) -# trainer = Trainer(max_epochs=1, gpus=[0, 1, 3, 7], distributed_backend='ddp') - -# train on 32 gpus across 4 nodes (make sure to submit appropriate SLURM job) -# trainer = Trainer(max_epochs=1, gpus=8, num_gpu_nodes=4, distributed_backend='ddp') + def training_step(self, batch, batch_idx): + ... +``` -# train (1 epoch only here for demo) -trainer.fit(model) +2. Fit it with a [Trainer](https://pytorch-lightning.rtfd.io/en/latest/pytorch_lightning.trainer.html) + ```python + from pytorch_lightning import Trainer -# view tensorboard logs -logging.info(f'View tensorboard logs by running\ntensorboard --logdir {os.getcwd()}') -logging.info('and going to http://localhost:6006 on your browser') -``` + model = CoolSystem() -When you're all done you can even run the test set separately. -```python -trainer.test() -``` + # most basic trainer, uses good defaults + trainer = Trainer() + trainer.fit(model) + ``` + +[Check out the COLAB demo here](https://colab.research.google.com/drive/1F_RNcHzTfFuQf-LeKvSlud6x7jXYkG31#scrollTo=HOk9c4_35FKg) + +## What types of research works? +Anything! Remember, that this is just organized PyTorch code. +The Training step defines the core complexity found in the training loop. -**Could be as complex as seq-2-seq + attention** +#### Could be as complex as a seq2seq ```python # define what happens for training here @@ -251,7 +183,7 @@ def training_step(self, batch, batch_idx): return {'loss': loss} ``` -**Or as basic as CNN image classification** +#### Or as basic as CNN image classification ```python # define what happens for validation here @@ -264,62 +196,73 @@ def validation_step(self, batch, batch_idx): return {'loss': loss} ``` -**And you also decide how to collate the output of all validation steps** +And without changing a single line of code, you could run on CPUs +```python +trainer = Trainer(max_epochs=1) +``` -```python -def validation_epoch_end(self, outputs): - """ - Called at the end of validation to aggregate outputs - :param outputs: list of individual outputs of each validation step - :return: - """ - val_loss_mean = 0 - val_acc_mean = 0 - for output in outputs: - val_loss_mean += output['val_loss'] - val_acc_mean += output['val_acc'] - - val_loss_mean /= len(outputs) - val_acc_mean /= len(outputs) - logs = {'val_loss': val_loss_mean.item(), 'val_acc': val_acc_mean.item()} - result = {'log': logs} - return result + +Or GPUs +```python +# 8 GPUs +trainer = Trainer(max_epochs=1, gpus=8) + +# 256 GPUs +trainer = Trainer(max_epochs=1, gpus=8, num_nodes=32) ``` - -## Tensorboard -Lightning is fully integrated with tensorboard, MLFlow and supports any logging module. -![tensorboard-support](docs/source/_static/images/tf_loss.png) +Or TPUs +```python +trainer = Trainer(num_tpu_cores=8) +``` -Lightning also adds a text column with all the hyperparameters for this experiment. +When you're done training, run the test accuracy +```python +trainer.test() +``` + +## Visualization +Lightning has out-of-the-box integration with the popular logging/visualizing frameworks -![tensorboard-support](docs/source/_static/images/tf_tags.png) +- Tensorboard +- MLFlow +- Neptune.ai +- Comet.ml +- ... -## Lightning automates all of the following ([each is also configurable](https://pytorch-lightning.rtfd.io/en/latest/pytorch_lightning.trainer.html)): +![tensorboard-support](docs/source/_static/images/tf_loss.png) -- [Running grid search on a cluster](https://pytorch-lightning.rtfd.io/en/latest/pytorch_lightning.trainer.distrib_data_parallel.html) -- [Fast dev run](https://pytorch-lightning.rtfd.io/en/latest/pytorch_lightning.utilities.debugging.html) -- [Logging](https://pytorch-lightning.rtfd.io/en/latest/pytorch_lightning.loggers.html) -- [Implement Your Own Distributed (DDP) training](https://pytorch-lightning.rtfd.io/en/latest/pytorch_lightning.core.lightning.html#pytorch_lightning.core.lightning.LightningModule.configure_ddp) -- [Multi-GPU & Multi-node](https://pytorch-lightning.rtfd.io/en/latest/pytorch_lightning.trainer.distrib_parts.html) -- [Training loop](https://pytorch-lightning.rtfd.io/en/latest/pytorch_lightning.trainer.training_loop.html) -- [Hooks](https://pytorch-lightning.rtfd.io/en/latest/pytorch_lightning.core.hooks.html) -- [Configure optimizers](https://pytorch-lightning.rtfd.io/en/latest/pytorch_lightning.core.lightning.html#pytorch_lightning.core.lightning.LightningModule.configure_optimizers) -- [Validations](https://pytorch-lightning.rtfd.io/en/latest/pytorch_lightning.trainer.evaluation_loop.html) -- [Model saving & Restoring training session](https://pytorch-lightning.rtfd.io/en/latest/pytorch_lightning.trainer.training_io.html) +## Lightning automates 40+ parts of DL/ML research +- GPU training +- Distributed GPU (cluster) training +- TPU training +- EarlyStopping +- Logging/Visualizing +- Checkpointing +- Experiment management ## Examples -- [GAN](https://github.com/PytorchLightning/pytorch-lightning/tree/master/pl_examples/domain_templates/gan.py) -- [MNIST](https://github.com/PytorchLightning/pytorch-lightning/tree/master/pl_examples/basic_examples) -- [Other projects using Lightning](https://github.com/PytorchLightning/pytorch-lightning/network/dependents?package_id=UGFja2FnZS0zNzE3NDU4OTM%3D) -- [Multi-node](https://github.com/PytorchLightning/pytorch-lightning/tree/master/pl_examples/multi_node_examples) +Check out this awesome list of research papers and implementations done with Lightning. + +- [Contextual Emotion Detection (DoubleDistilBert)](https://github.com/PyTorchLightning/emotion_transformer) +- [Generative Adversarial Network](https://colab.research.google.com/drive/1F_RNcHzTfFuQf-LeKvSlud6x7jXYkG31#scrollTo=TyYOdg8g77P0) +- [Hyperparameter optimization with Optuna](https://github.com/optuna/optuna/blob/master/examples/pytorch_lightning_simple.py) +- [Image Inpainting using Partial Convolutions](https://github.com/ryanwongsa/Image-Inpainting) +- [MNIST on TPU](https://colab.research.google.com/drive/1-_LKx4HwAxl5M6xPJmqAAu444LTDQoa3#scrollTo=BHBz1_AnamN_) +- [NER (transformers, TPU, huggingface)](https://colab.research.google.com/drive/1dBN-wwYUngLYVt985wGs_OKPlK_ANB9D) +- [NeuralTexture (CVPR)](https://github.com/PyTorchLightning/neuraltexture) +- [Recurrent Attentive Neural Process](https://github.com/PyTorchLightning/attentive-neural-processes) +- [Siamese Nets for One-shot Image Recognition](https://github.com/PyTorchLightning/Siamese-Neural-Networks) +- [Speech Transformers](https://github.com/PyTorchLightning/speech-transformer-pytorch_lightning) +- [Transformers transfer learning (Huggingface)](https://colab.research.google.com/drive/1F_RNcHzTfFuQf-LeKvSlud6x7jXYkG31#scrollTo=yr7eaxkF-djf) +- [Transformers text classification](https://github.com/ricardorei/lightning-text-classification) +- [VAE Library of over 18+ VAE flavors](https://github.com/AntixK/PyTorch-VAE) ## Tutorials -- [Basic Lightning use](https://towardsdatascience.com/supercharge-your-ai-research-with-pytorch-lightning-337948a99eec) -- [9 key speed features in Pytorch-Lightning](https://towardsdatascience.com/9-tips-for-training-lightning-fast-neural-networks-in-pytorch-8e63a502f565) -- [SLURM, multi-node training with Lightning](https://towardsdatascience.com/trivial-multi-node-training-with-pytorch-lightning-ff75dfb809bd) +Check out our [introduction guide](https://pytorch-lightning.readthedocs.io/en/latest/introduction_guide.html) to get started. +Or jump straight into [our tutorials](https://pytorch-lightning.readthedocs.io/en/latest/#tutorials). --- @@ -328,26 +271,24 @@ Welcome to the Lightning community! If you have any questions, feel free to: 1. [read the docs](https://pytorch-lightning.rtfd.io/en/latest/). -2. [Search through the issues](https://github.com/PytorchLightning/pytorch-lightning/issues?utf8=%E2%9C%93&q=my++question). +2. [Search through the issues](https://github.com/PytorchLightning/pytorch-lightning/issues?utf8=%E2%9C%93&q=my++question). 3. [Ask on stackoverflow](https://stackoverflow.com/questions/ask?guided=false) with the tag pytorch-lightning. - -If no one replies to you quickly enough, feel free to post the stackoverflow link to our Gitter chat! - -To chat with the rest of us visit our [gitter channel](https://gitter.im/PyTorch-Lightning/community)! +4. [Join our slack](https://join.slack.com/t/pytorch-lightning/shared_invite/enQtODU5ODIyNTUzODQwLTFkMDg5Mzc1MDBmNjEzMDgxOTVmYTdhYjA1MDdmODUyOTg2OGQ1ZWZkYTQzODhhNzdhZDA3YmNhMDhlMDY4YzQ). --- ## FAQ **How do I use Lightning for rapid research?** -[Here's a walk-through](https://pytorch-lightning.rtfd.io/en/latest/) +[Here's a walk-through](https://pytorch-lightning.readthedocs.io/en/latest/introduction_guide.html) **Why was Lightning created?** Lightning has 3 goals in mind: + 1. Maximal flexibility while abstracting out the common boilerplate across research projects. 2. Reproducibility. If all projects use the LightningModule template, it will be much much easier to understand what's going on and where to look! It will also mean every implementation follows a standard format. 3. Democratizing PyTorch power user features. Distributed training? 16-bit? know you need them but don't want to take the time to implement? All good... these come built into Lightning. **How does Lightning compare with Ignite and fast.ai?** -[Here's a thorough comparison](https://medium.com/@_willfalcon/pytorch-lightning-vs-pytorch-ignite-vs-fast-ai-61dc7480ad8a). +[Here's a thorough comparison](https://medium.com/@_willfalcon/pytorch-lightning-vs-pytorch-ignite-vs-fast-ai-61dc7480ad8a). **Is this another library I have to learn?** Nope! We use pure Pytorch everywhere and don't add unecessary abstractions! From 0b92d6ffecd8611712acc4182233bc94dd7dde7b Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 11:36:51 -0500 Subject: [PATCH 02/21] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 026483c7ac20c..e752b6ef8a670 100644 --- a/README.md +++ b/README.md @@ -54,8 +54,8 @@ pip install pytorch-lightning ## What is it? Lightning is a way to organize your PyTorch code to decouple the science code from the engineering. It's more of a style-guide than a framework. -Refactor your research code into a LightningModule -![PT to PL](docs/source/_images/lightning_module/pt_to_pl.png) +To use Lightning, first refactor your research code into a LightningModule +![PT to PL](docs/source/_images/lightning_module/pt_to_pl.png | width=50) And Lightning automates the rest! ![PT to PL](docs/source/_images/lightning_module/pt_trainer.png) From c8a4a35663039184c6fa10159c8a0c8ad2418215 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 11:38:19 -0500 Subject: [PATCH 03/21] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e752b6ef8a670..d7474c0aba9b4 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ pip install pytorch-lightning Lightning is a way to organize your PyTorch code to decouple the science code from the engineering. It's more of a style-guide than a framework. To use Lightning, first refactor your research code into a LightningModule -![PT to PL](docs/source/_images/lightning_module/pt_to_pl.png | width=50) +![PT to PL](docs/source/_images/lightning_module/pt_to_pl.png) And Lightning automates the rest! ![PT to PL](docs/source/_images/lightning_module/pt_trainer.png) From 04ab78383e597798f5e7dec522850600093a1950 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 11:41:43 -0500 Subject: [PATCH 04/21] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d7474c0aba9b4..392c8e8638835 100644 --- a/README.md +++ b/README.md @@ -54,10 +54,11 @@ pip install pytorch-lightning ## What is it? Lightning is a way to organize your PyTorch code to decouple the science code from the engineering. It's more of a style-guide than a framework. -To use Lightning, first refactor your research code into a LightningModule +To use Lightning, first refactor your research code into a [LightningModule](https://pytorch-lightning.readthedocs.io/en/latest/lightning-module.html). + ![PT to PL](docs/source/_images/lightning_module/pt_to_pl.png) -And Lightning automates the rest! +And Lightning automates the rest using the [Trainer](https://pytorch-lightning.readthedocs.io/en/latest/trainer.html)! ![PT to PL](docs/source/_images/lightning_module/pt_trainer.png) Lightning guarantees riguously tested, correct, modern best practices for the automated parts. From 2e67763c5749d76303f8825a97f4f51ba5091348 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 11:43:57 -0500 Subject: [PATCH 05/21] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 392c8e8638835..d26b185ec9518 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,8 @@ Here's how you would organize a realistic PyTorch project into Lightning. ![PT to PL](docs/source/_images/mnist_imgs/pt_to_pl.jpg) -The LightningModule defines a *system* such as seq-2-seq, GAN, etc... It can ALSO define a simple classifier such as the example below. +The LightningModule defines a *system* such as seq-2-seq, GAN, etc... +It can ALSO define a simple classifier. In summary, you: From b3d68b8fbbe524e6b17f9e379cad92cd8d73aa40 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 11:45:28 -0500 Subject: [PATCH 06/21] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d26b185ec9518..76c1178bf34bd 100644 --- a/README.md +++ b/README.md @@ -243,6 +243,7 @@ Lightning has out-of-the-box integration with the popular logging/visualizing fr - Logging/Visualizing - Checkpointing - Experiment management +- [Full list here](https://pytorch-lightning.readthedocs.io/en/latest/#common-use-cases) ## Examples From a60e5dce27bfebfcfa936ee8dcda84137136137f Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 11:57:36 -0500 Subject: [PATCH 07/21] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 76c1178bf34bd..94926ffb6b91c 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,12 @@ If your code IS a mess, then you needed to clean up anyhow ;) ## Why do I want to use lightning? Although your research/production project might start simple, once you add things like GPU AND TPU training, 16-bit precision, etc, you end up spending more time engineering than researching. Lightning automates AND rigorously tests those parts for you. +## Support +- [7 core contributors](https://pytorch-lightning.readthedocs.io/en/latest/governance.html) who are all a mix of professional engineers, Research Scientists, PhD students from top AI labs. +- 100+ community contributors. + +Lightning is also part of the [PyTorch ecosystem](https://pytorch.org/ecosystem/) which requires projects to have solid testing, documentation and support. + --- ## README Table of Contents From a22461ca705ad4781bc6309dc93d1ddef5c2227f Mon Sep 17 00:00:00 2001 From: Jirka Borovec Date: Fri, 6 Mar 2020 18:00:05 +0100 Subject: [PATCH 08/21] Test deprecated API for 0.8.0 and 0.9.0 (#1071) * till 0.8 * refactor * fix tests * fix tests * deprx till 0.9 * Update trainer.py * Apply suggestions from code review Co-authored-by: William Falcon --- .../gradient_accumulation_scheduler.py | 6 +- pytorch_lightning/core/model_saving.py | 2 +- pytorch_lightning/core/root_module.py | 2 + pytorch_lightning/loggers/comet.py | 9 +- pytorch_lightning/loggers/mlflow.py | 8 +- pytorch_lightning/loggers/neptune.py | 6 +- pytorch_lightning/logging/comet.py | 2 +- .../{loggers => logging}/comet_logger.py | 0 pytorch_lightning/logging/mlflow.py | 2 +- .../{loggers => logging}/mlflow_logger.py | 0 pytorch_lightning/logging/neptune.py | 2 +- pytorch_lightning/logging/test_tube.py | 2 +- .../{loggers => logging}/test_tube_logger.py | 0 pytorch_lightning/logging/wandb.py | 2 +- pytorch_lightning/pt_overrides/__init__.py | 2 - .../pt_overrides/override_data_parallel.py | 12 +++ pytorch_lightning/root_module/decorators.py | 11 +++ pytorch_lightning/root_module/grads.py | 11 +++ pytorch_lightning/root_module/hooks.py | 11 +++ pytorch_lightning/root_module/memory.py | 11 +++ pytorch_lightning/root_module/model_saving.py | 11 +++ pytorch_lightning/root_module/root_module.py | 11 +++ pytorch_lightning/trainer/__init__.py | 2 +- pytorch_lightning/trainer/deprecated_api.py | 87 +++++++++++++++++++ pytorch_lightning/trainer/trainer.py | 86 +++++++++--------- pytorch_lightning/trainer/training_loop.py | 18 ---- tests/test_deprecated.py | 55 ++++++++++++ 27 files changed, 282 insertions(+), 89 deletions(-) rename pytorch_lightning/{loggers => logging}/comet_logger.py (100%) rename pytorch_lightning/{loggers => logging}/mlflow_logger.py (100%) rename pytorch_lightning/{loggers => logging}/test_tube_logger.py (100%) create mode 100644 pytorch_lightning/pt_overrides/override_data_parallel.py create mode 100644 pytorch_lightning/root_module/decorators.py create mode 100644 pytorch_lightning/root_module/grads.py create mode 100644 pytorch_lightning/root_module/hooks.py create mode 100644 pytorch_lightning/root_module/memory.py create mode 100644 pytorch_lightning/root_module/model_saving.py create mode 100644 pytorch_lightning/root_module/root_module.py create mode 100644 pytorch_lightning/trainer/deprecated_api.py create mode 100644 tests/test_deprecated.py diff --git a/pytorch_lightning/callbacks/gradient_accumulation_scheduler.py b/pytorch_lightning/callbacks/gradient_accumulation_scheduler.py index fcb9b152d8333..00d73392c6ede 100644 --- a/pytorch_lightning/callbacks/gradient_accumulation_scheduler.py +++ b/pytorch_lightning/callbacks/gradient_accumulation_scheduler.py @@ -14,9 +14,9 @@ class GradientAccumulationScheduler(Callback): Change gradient accumulation factor according to scheduling. Args: - scheduling (dict): scheduling in format {epoch: accumulation_factor} - .. warning:: Epochs indexing starts from "1" until v0.6.x, but will start from "0" in - v0.8.0. + scheduling: scheduling in format {epoch: accumulation_factor} + .. warning:: Epochs indexing starts from "1" until v0.6.x, + but will start from "0" in v0.8.0. Example:: diff --git a/pytorch_lightning/core/model_saving.py b/pytorch_lightning/core/model_saving.py index 278e6467dc1d2..54f8fbc4c83be 100644 --- a/pytorch_lightning/core/model_saving.py +++ b/pytorch_lightning/core/model_saving.py @@ -8,4 +8,4 @@ warnings.warn("`model_saving` module has been renamed to `saving` since v0.6.0." " The deprecated module name will be removed in v0.8.0.", DeprecationWarning) -from pytorch_lightning.core.saving import ModelIO # noqa: E402 +from pytorch_lightning.core.saving import * # noqa: F403 diff --git a/pytorch_lightning/core/root_module.py b/pytorch_lightning/core/root_module.py index 07f290492902c..af9e89d4105c4 100644 --- a/pytorch_lightning/core/root_module.py +++ b/pytorch_lightning/core/root_module.py @@ -5,5 +5,7 @@ import warnings +from pytorch_lightning.core.lightning import * # noqa: F403 + warnings.warn("`root_module` module has been renamed to `lightning` since v0.6.0." " The deprecated module name will be removed in v0.8.0.", DeprecationWarning) diff --git a/pytorch_lightning/loggers/comet.py b/pytorch_lightning/loggers/comet.py index 4399fa802e022..a7e8118869ce5 100644 --- a/pytorch_lightning/loggers/comet.py +++ b/pytorch_lightning/loggers/comet.py @@ -5,8 +5,9 @@ CometLogger ------------- """ + +import logging as log from argparse import Namespace -from logging import getLogger from typing import Optional, Dict, Union, Any try: @@ -29,8 +30,6 @@ from pytorch_lightning.utilities.debugging import MisconfigurationException from .base import LightningLoggerBase, rank_zero_only -logger = getLogger(__name__) - class CometLogger(LightningLoggerBase): r""" @@ -99,7 +98,7 @@ def __init__(self, api_key: Optional[str] = None, save_dir: Optional[str] = None # If neither api_key nor save_dir are passed as arguments, raise an exception raise MisconfigurationException("CometLogger requires either api_key or save_dir during initialization.") - logger.info(f"CometLogger will be initialized in {self.mode} mode") + log.info(f"CometLogger will be initialized in {self.mode} mode") self.workspace = workspace self.project_name = project_name @@ -118,7 +117,7 @@ def __init__(self, api_key: Optional[str] = None, save_dir: Optional[str] = None try: self.name = experiment_name except TypeError as e: - logger.exception("Failed to set experiment name for comet.ml logger") + log.exception("Failed to set experiment name for comet.ml logger") @property def experiment(self) -> CometBaseExperiment: diff --git a/pytorch_lightning/loggers/mlflow.py b/pytorch_lightning/loggers/mlflow.py index 7f05da9227bbe..ed878a0616e62 100644 --- a/pytorch_lightning/loggers/mlflow.py +++ b/pytorch_lightning/loggers/mlflow.py @@ -23,8 +23,8 @@ def any_lightning_module_function_or_hook(...): self.logger.experiment.whatever_ml_flow_supports(...) """ +import logging as log from argparse import Namespace -from logging import getLogger from time import time from typing import Optional, Dict, Any, Union @@ -36,8 +36,6 @@ def any_lightning_module_function_or_hook(...): from .base import LightningLoggerBase, rank_zero_only -logger = getLogger(__name__) - class MLFlowLogger(LightningLoggerBase): def __init__(self, experiment_name: str, tracking_uri: Optional[str] = None, @@ -80,7 +78,7 @@ def run_id(self): if expt: self._expt_id = expt.experiment_id else: - logger.warning(f'Experiment with name {self.experiment_name} not found. Creating it.') + log.warning(f'Experiment with name {self.experiment_name} not found. Creating it.') self._expt_id = self._mlflow_client.create_experiment(name=self.experiment_name) run = self._mlflow_client.create_run(experiment_id=self._expt_id, tags=self.tags) @@ -98,7 +96,7 @@ def log_metrics(self, metrics: Dict[str, float], step: Optional[int] = None) -> timestamp_ms = int(time() * 1000) for k, v in metrics.items(): if isinstance(v, str): - logger.warning(f'Discarding metric with string value {k}={v}.') + log.warning(f'Discarding metric with string value {k}={v}.') continue self.experiment.log_metric(self.run_id, k, v, timestamp_ms, step) diff --git a/pytorch_lightning/loggers/neptune.py b/pytorch_lightning/loggers/neptune.py index b02f175f2d5f5..5e011d7426424 100644 --- a/pytorch_lightning/loggers/neptune.py +++ b/pytorch_lightning/loggers/neptune.py @@ -6,8 +6,8 @@ NeptuneLogger -------------- """ +import logging as log from argparse import Namespace -from logging import getLogger from typing import Optional, List, Dict, Any, Union, Iterable try: @@ -22,8 +22,6 @@ from pytorch_lightning.loggers.base import LightningLoggerBase, rank_zero_only -logger = getLogger(__name__) - class NeptuneLogger(LightningLoggerBase): r""" @@ -138,7 +136,7 @@ def any_lightning_module_function_or_hook(...): neptune.init(api_token=self.api_key, project_qualified_name=self.project_name) - logger.info(f'NeptuneLogger was initialized in {self.mode} mode') + log.info(f'NeptuneLogger was initialized in {self.mode} mode') @property def experiment(self) -> Experiment: diff --git a/pytorch_lightning/logging/comet.py b/pytorch_lightning/logging/comet.py index d3397f17e0ed7..48a426dd4d53e 100644 --- a/pytorch_lightning/logging/comet.py +++ b/pytorch_lightning/logging/comet.py @@ -2,4 +2,4 @@ .. warning:: `logging` package has been renamed to `loggers` since v0.7.0 and will be removed in v0.9.0 """ -from pytorch_lightning.loggers import comet # noqa: F403 +from pytorch_lightning.loggers.comet import CometLogger # noqa: F403 diff --git a/pytorch_lightning/loggers/comet_logger.py b/pytorch_lightning/logging/comet_logger.py similarity index 100% rename from pytorch_lightning/loggers/comet_logger.py rename to pytorch_lightning/logging/comet_logger.py diff --git a/pytorch_lightning/logging/mlflow.py b/pytorch_lightning/logging/mlflow.py index 4d16e4184f2e8..895f41fc5175a 100644 --- a/pytorch_lightning/logging/mlflow.py +++ b/pytorch_lightning/logging/mlflow.py @@ -2,4 +2,4 @@ .. warning:: `logging` package has been renamed to `loggers` since v0.7.0 and will be removed in v0.9.0 """ -from pytorch_lightning.loggers import mlflow # noqa: F403 +from pytorch_lightning.loggers.mlflow import MLFlowLogger # noqa: F403 diff --git a/pytorch_lightning/loggers/mlflow_logger.py b/pytorch_lightning/logging/mlflow_logger.py similarity index 100% rename from pytorch_lightning/loggers/mlflow_logger.py rename to pytorch_lightning/logging/mlflow_logger.py diff --git a/pytorch_lightning/logging/neptune.py b/pytorch_lightning/logging/neptune.py index a952daed5b421..f1b64525fe160 100644 --- a/pytorch_lightning/logging/neptune.py +++ b/pytorch_lightning/logging/neptune.py @@ -2,4 +2,4 @@ .. warning:: `logging` package has been renamed to `loggers` since v0.7.0 and will be removed in v0.9.0 """ -from pytorch_lightning.loggers import neptune # noqa: F403 +from pytorch_lightning.loggers.neptune import NeptuneLogger # noqa: F403 diff --git a/pytorch_lightning/logging/test_tube.py b/pytorch_lightning/logging/test_tube.py index f3494c130f827..a9bc71e4885dd 100644 --- a/pytorch_lightning/logging/test_tube.py +++ b/pytorch_lightning/logging/test_tube.py @@ -2,4 +2,4 @@ .. warning:: `logging` package has been renamed to `loggers` since v0.7.0 and will be removed in v0.9.0 """ -from pytorch_lightning.loggers import test_tube # noqa: F403 +from pytorch_lightning.loggers.test_tube import TestTubeLogger # noqa: F403 diff --git a/pytorch_lightning/loggers/test_tube_logger.py b/pytorch_lightning/logging/test_tube_logger.py similarity index 100% rename from pytorch_lightning/loggers/test_tube_logger.py rename to pytorch_lightning/logging/test_tube_logger.py diff --git a/pytorch_lightning/logging/wandb.py b/pytorch_lightning/logging/wandb.py index bc112b1d9dbef..e4527b7b8734a 100644 --- a/pytorch_lightning/logging/wandb.py +++ b/pytorch_lightning/logging/wandb.py @@ -2,4 +2,4 @@ .. warning:: `logging` package has been renamed to `loggers` since v0.7.0 and will be removed in v0.9.0 """ -from pytorch_lightning.loggers import wandb # noqa: F403 +from pytorch_lightning.loggers.wandb import WandbLogger # noqa: F403 diff --git a/pytorch_lightning/pt_overrides/__init__.py b/pytorch_lightning/pt_overrides/__init__.py index 9db26c1e9058b..b68986d556ccc 100644 --- a/pytorch_lightning/pt_overrides/__init__.py +++ b/pytorch_lightning/pt_overrides/__init__.py @@ -7,5 +7,3 @@ warnings.warn("`pt_overrides` package has been renamed to `overrides` since v0.6.0." " The deprecated module name will be removed in v0.8.0.", DeprecationWarning) - -from pytorch_lightning.overrides import override_data_parallel # noqa: E402 diff --git a/pytorch_lightning/pt_overrides/override_data_parallel.py b/pytorch_lightning/pt_overrides/override_data_parallel.py new file mode 100644 index 0000000000000..bc435b7d0738e --- /dev/null +++ b/pytorch_lightning/pt_overrides/override_data_parallel.py @@ -0,0 +1,12 @@ +""" +.. warning:: `override_data_parallel` module has been renamed to `data_parallel` since v0.6.0. + The deprecated module name will be removed in v0.8.0. +""" + +import warnings + +warnings.warn("`override_data_parallel` module has been renamed to `data_parallel` since v0.6.0." + " The deprecated module name will be removed in v0.8.0.", DeprecationWarning) + +from pytorch_lightning.overrides.data_parallel import ( # noqa: F402 + get_a_var, parallel_apply, LightningDataParallel, LightningDistributedDataParallel) diff --git a/pytorch_lightning/root_module/decorators.py b/pytorch_lightning/root_module/decorators.py new file mode 100644 index 0000000000000..88afe093b97d6 --- /dev/null +++ b/pytorch_lightning/root_module/decorators.py @@ -0,0 +1,11 @@ +""" +.. warning:: `root_module.decorators` module has been renamed to `core.decorators` since v0.6.0. + The deprecated module name will be removed in v0.8.0. +""" + +import warnings + +warnings.warn("`root_module.decorators` module has been renamed to `core.decorators` since v0.6.0." + " The deprecated module name will be removed in v0.8.0.", DeprecationWarning) + +from pytorch_lightning.core.decorators import * # noqa: F403 diff --git a/pytorch_lightning/root_module/grads.py b/pytorch_lightning/root_module/grads.py new file mode 100644 index 0000000000000..1f9617385e9ef --- /dev/null +++ b/pytorch_lightning/root_module/grads.py @@ -0,0 +1,11 @@ +""" +.. warning:: `root_module.grads` module has been renamed to `core.grads` since v0.6.0. + The deprecated module name will be removed in v0.8.0. +""" + +import warnings + +warnings.warn("`root_module.grads` module has been renamed to `core.grads` since v0.6.0." + " The deprecated module name will be removed in v0.8.0.", DeprecationWarning) + +from pytorch_lightning.core.grads import * # noqa: F403 diff --git a/pytorch_lightning/root_module/hooks.py b/pytorch_lightning/root_module/hooks.py new file mode 100644 index 0000000000000..e4beaee999c7f --- /dev/null +++ b/pytorch_lightning/root_module/hooks.py @@ -0,0 +1,11 @@ +""" +.. warning:: `root_module.hooks` module has been renamed to `core.hooks` since v0.6.0. + The deprecated module name will be removed in v0.8.0. +""" + +import warnings + +warnings.warn("`root_module.hooks` module has been renamed to `core.hooks` since v0.6.0." + " The deprecated module name will be removed in v0.8.0.", DeprecationWarning) + +from pytorch_lightning.core.hooks import * # noqa: F403 diff --git a/pytorch_lightning/root_module/memory.py b/pytorch_lightning/root_module/memory.py new file mode 100644 index 0000000000000..ef739ac22f183 --- /dev/null +++ b/pytorch_lightning/root_module/memory.py @@ -0,0 +1,11 @@ +""" +.. warning:: `root_module.memory` module has been renamed to `core.memory` since v0.6.0. + The deprecated module name will be removed in v0.8.0. +""" + +import warnings + +warnings.warn("`root_module.memory` module has been renamed to `core.memory` since v0.6.0." + " The deprecated module name will be removed in v0.8.0.", DeprecationWarning) + +from pytorch_lightning.core.memory import * # noqa: F403 diff --git a/pytorch_lightning/root_module/model_saving.py b/pytorch_lightning/root_module/model_saving.py new file mode 100644 index 0000000000000..5af97abf2d6b6 --- /dev/null +++ b/pytorch_lightning/root_module/model_saving.py @@ -0,0 +1,11 @@ +""" +.. warning:: `root_module.model_saving` module has been renamed to `core.saving` since v0.6.0. + The deprecated module name will be removed in v0.8.0. +""" + +import warnings + +warnings.warn("`root_module.model_saving` module has been renamed to `core.saving` since v0.6.0." + " The deprecated module name will be removed in v0.8.0.", DeprecationWarning) + +from pytorch_lightning.core.saving import * # noqa: F403 diff --git a/pytorch_lightning/root_module/root_module.py b/pytorch_lightning/root_module/root_module.py new file mode 100644 index 0000000000000..4dd472478e7b3 --- /dev/null +++ b/pytorch_lightning/root_module/root_module.py @@ -0,0 +1,11 @@ +""" +.. warning:: `root_module.root_module` module has been renamed to `core.lightning` since v0.6.0. + The deprecated module name will be removed in v0.8.0. +""" + +import warnings + +warnings.warn("`root_module.root_module` module has been renamed to `core.lightning` since v0.6.0." + " The deprecated module name will be removed in v0.8.0.", DeprecationWarning) + +from pytorch_lightning.core.lightning import * # noqa: F403 diff --git a/pytorch_lightning/trainer/__init__.py b/pytorch_lightning/trainer/__init__.py index f2e0125b06271..f8470b0ec7e90 100644 --- a/pytorch_lightning/trainer/__init__.py +++ b/pytorch_lightning/trainer/__init__.py @@ -423,7 +423,7 @@ def on_train_end(self): min_nb_epochs: .. warning:: deprecated:: 0.5.0 - Use `min_nb_epochs` instead. Will remove 0.8.0. + Use `min_epochs` instead. Will remove 0.8.0. max_steps ^^^^^^^^^ diff --git a/pytorch_lightning/trainer/deprecated_api.py b/pytorch_lightning/trainer/deprecated_api.py new file mode 100644 index 0000000000000..08f5e449eabc4 --- /dev/null +++ b/pytorch_lightning/trainer/deprecated_api.py @@ -0,0 +1,87 @@ +"""Mirroring deprecated API""" + +import warnings +from abc import ABC + + +class TrainerDeprecatedAPITillVer0_8(ABC): + + def __init__(self): + super().__init__() # mixin calls super too + + @property + def nb_gpu_nodes(self): + """Back compatibility, will be removed in v0.8.0""" + warnings.warn("Attribute `nb_gpu_nodes` has renamed to `num_nodes` since v0.5.0" + " and this method will be removed in v0.8.0", DeprecationWarning) + return self.num_nodes + + @property + def num_gpu_nodes(self): + """Back compatibility, will be removed in v0.8.0""" + warnings.warn("Attribute `num_gpu_nodes` has renamed to `num_nodes` since v0.5.0" + " and this method will be removed in v0.8.0", DeprecationWarning) + return self.num_nodes + + @num_gpu_nodes.setter + def num_gpu_nodes(self, num_nodes): + """Back compatibility, will be removed in v0.8.0""" + warnings.warn("Attribute `num_gpu_nodes` has renamed to `num_nodes` since v0.5.0" + " and this method will be removed in v0.8.0", DeprecationWarning) + self.num_nodes = num_nodes + + @property + def gradient_clip(self): + """Back compatibility, will be removed in v0.8.0""" + warnings.warn("Attribute `gradient_clip` has renamed to `gradient_clip_val` since v0.5.0" + " and this method will be removed in v0.8.0", DeprecationWarning) + return self.gradient_clip_val + + @gradient_clip.setter + def gradient_clip(self, gradient_clip): + """Back compatibility, will be removed in v0.8.0""" + warnings.warn("Attribute `gradient_clip` has renamed to `gradient_clip_val` since v0.5.0" + " and this method will be removed in v0.8.0", DeprecationWarning) + self.gradient_clip_val = gradient_clip + + @property + def max_nb_epochs(self): + """Back compatibility, will be removed in v0.8.0""" + warnings.warn("Attribute `max_nb_epochs` has renamed to `max_epochs` since v0.5.0" + " and this method will be removed in v0.8.0", DeprecationWarning) + return self.max_epochs + + @max_nb_epochs.setter + def max_nb_epochs(self, max_epochs): + """Back compatibility, will be removed in v0.8.0""" + warnings.warn("Attribute `max_nb_epochs` has renamed to `max_epochs` since v0.5.0" + " and this method will be removed in v0.8.0", DeprecationWarning) + self.max_epochs = max_epochs + + @property + def min_nb_epochs(self): + """Back compatibility, will be removed in v0.8.0""" + warnings.warn("Attribute `min_nb_epochs` has renamed to `min_epochs` since v0.5.0" + " and this method will be removed in v0.8.0", DeprecationWarning) + return self.min_epochs + + @min_nb_epochs.setter + def min_nb_epochs(self, min_epochs): + """Back compatibility, will be removed in v0.8.0""" + warnings.warn("Attribute `min_nb_epochs` has renamed to `min_epochs` since v0.5.0" + " and this method will be removed in v0.8.0", DeprecationWarning) + self.min_epochs = min_epochs + + @property + def nb_sanity_val_steps(self): + """Back compatibility, will be removed in v0.8.0""" + warnings.warn("Attribute `nb_sanity_val_steps` has renamed to `num_sanity_val_steps` since v0.5.0" + " and this method will be removed in v0.8.0", DeprecationWarning) + return self.num_sanity_val_steps + + @nb_sanity_val_steps.setter + def nb_sanity_val_steps(self, nb): + """Back compatibility, will be removed in v0.8.0""" + warnings.warn("Attribute `nb_sanity_val_steps` has renamed to `num_sanity_val_steps` since v0.5.0" + " and this method will be removed in v0.8.0", DeprecationWarning) + self.num_sanity_val_steps = nb diff --git a/pytorch_lightning/trainer/trainer.py b/pytorch_lightning/trainer/trainer.py index a9bd4fbdcd78d..506ec531a5cfd 100644 --- a/pytorch_lightning/trainer/trainer.py +++ b/pytorch_lightning/trainer/trainer.py @@ -26,13 +26,14 @@ determine_root_gpu_device ) from pytorch_lightning.core.lightning import LightningModule +from pytorch_lightning.trainer.callback_hook import TrainerCallbackHookMixin +from pytorch_lightning.trainer.deprecated_api import TrainerDeprecatedAPITillVer0_8 from pytorch_lightning.trainer.evaluation_loop import TrainerEvaluationLoopMixin from pytorch_lightning.trainer.logging import TrainerLoggingMixin from pytorch_lightning.trainer.model_hooks import TrainerModelHooksMixin from pytorch_lightning.trainer.training_io import TrainerIOMixin from pytorch_lightning.trainer.training_loop import TrainerTrainLoopMixin from pytorch_lightning.trainer.training_tricks import TrainerTrainingTricksMixin -from pytorch_lightning.trainer.callback_hook import TrainerCallbackHookMixin from pytorch_lightning.utilities.debugging import MisconfigurationException from pytorch_lightning.profiler import Profiler, PassThroughProfiler from pytorch_lightning.callbacks import Callback @@ -55,19 +56,21 @@ XLA_AVAILABLE = True -class Trainer(TrainerIOMixin, - TrainerDPMixin, - TrainerDDPMixin, - TrainerLoggingMixin, - TrainerModelHooksMixin, - TrainerTrainingTricksMixin, - TrainerDataLoadingMixin, - TrainerAMPMixin, - TrainerEvaluationLoopMixin, - TrainerTrainLoopMixin, - TrainerCallbackConfigMixin, - TrainerCallbackHookMixin - ): +class Trainer( + TrainerIOMixin, + TrainerDPMixin, + TrainerDDPMixin, + TrainerLoggingMixin, + TrainerModelHooksMixin, + TrainerTrainingTricksMixin, + TrainerDataLoadingMixin, + TrainerAMPMixin, + TrainerEvaluationLoopMixin, + TrainerTrainLoopMixin, + TrainerCallbackConfigMixin, + TrainerCallbackHookMixin, + TrainerDeprecatedAPITillVer0_8, +): def __init__( self, @@ -105,7 +108,7 @@ def __init__( row_log_interval: int = 10, add_row_log_interval=None, # backward compatible, todo: remove in v0.8.0 distributed_backend: Optional[str] = None, - use_amp=False, # backward compatible, todo: remove in v0.8.0 + use_amp=False, # backward compatible, todo: remove in v0.9.0 precision: int = 32, print_nan_grads: bool = False, weights_summary: str = 'full', @@ -202,7 +205,7 @@ def __init__( use_amp: .. warning:: .. deprecated:: 0.7.0 - Use `precision` instead. Will remove 0.8.0. + Use `precision` instead. Will remove 0.9.0. precision: Full precision (32), half precision (16). @@ -241,23 +244,20 @@ def __init__( torch.backends.cudnn.benchmark = True # Transfer params - # Backward compatibility self.num_nodes = num_nodes + # Backward compatibility, TODO: remove in v0.8.0 if nb_gpu_nodes is not None: - warnings.warn("`nb_gpu_nodes` has renamed to `num_nodes` since v0.5.0" + warnings.warn("Argument `nb_gpu_nodes` has renamed to `num_nodes` since v0.5.0" " and this method will be removed in v0.8.0", DeprecationWarning) - if not num_nodes: # in case you did not set the proper value - num_nodes = nb_gpu_nodes - self.num_gpu_nodes = num_nodes + self.num_gpu_nodes = nb_gpu_nodes self.log_gpu_memory = log_gpu_memory - # Backward compatibility + self.gradient_clip_val = gradient_clip_val + # Backward compatibility, TODO: remove in v0.8.0 if gradient_clip is not None: - warnings.warn("`gradient_clip` has renamed to `gradient_clip_val` since v0.5.0" + warnings.warn("Argument `gradient_clip` has renamed to `gradient_clip_val` since v0.5.0" " and this method will be removed in v0.8.0", DeprecationWarning) - if not gradient_clip_val: # in case you did not set the proper value - gradient_clip_val = gradient_clip - self.gradient_clip_val = gradient_clip_val + self.gradient_clip = gradient_clip self.reload_dataloaders_every_epoch = reload_dataloaders_every_epoch self.progress_bar_refresh_rate = progress_bar_refresh_rate @@ -273,33 +273,29 @@ def __init__( self.process_position = process_position self.weights_summary = weights_summary - # Backward compatibility + self.max_epochs = max_epochs + # Backward compatibility, TODO: remove in v0.8.0 if max_nb_epochs is not None: - warnings.warn("`max_nb_epochs` has renamed to `max_epochs` since v0.5.0" + warnings.warn("Argument `max_nb_epochs` has renamed to `max_epochs` since v0.5.0" " and this method will be removed in v0.8.0", DeprecationWarning) - if not max_epochs: # in case you did not set the proper value - max_epochs = max_nb_epochs - self.max_epochs = max_epochs + self.max_nb_epochs = max_nb_epochs - # Backward compatibility + self.min_epochs = min_epochs + # Backward compatibility, TODO: remove in v0.8.0 if min_nb_epochs is not None: - warnings.warn("`min_nb_epochs` has renamed to `min_epochs` since v0.5.0" + warnings.warn("Argument `min_nb_epochs` has renamed to `min_epochs` since v0.5.0" " and this method will be removed in v0.8.0", DeprecationWarning) - if not min_epochs: # in case you did not set the proper value - min_epochs = min_nb_epochs - self.min_epochs = min_epochs + self.min_nb_epochs = min_nb_epochs self.max_steps = max_steps self.min_steps = min_steps - # Backward compatibility + self.num_sanity_val_steps = num_sanity_val_steps + # Backward compatibility, TODO: remove in v0.8.0 if nb_sanity_val_steps is not None: - warnings.warn("`nb_sanity_val_steps` has renamed to `num_sanity_val_steps` since v0.5.0" + warnings.warn("Argument `nb_sanity_val_steps` has renamed to `num_sanity_val_steps` since v0.5.0" " and this method will be removed in v0.8.0", DeprecationWarning) - if not num_sanity_val_steps: # in case you did not set the proper value - num_sanity_val_steps = nb_sanity_val_steps - - self.num_sanity_val_steps = num_sanity_val_steps + self.nb_sanity_val_steps = nb_sanity_val_steps self.print_nan_grads = print_nan_grads self.truncated_bptt_steps = truncated_bptt_steps self.resume_from_checkpoint = resume_from_checkpoint @@ -380,7 +376,7 @@ def __init__( self.use_dp = False self.single_gpu = False self.distributed_backend = distributed_backend - self.set_distributed_mode(distributed_backend, num_nodes) + self.set_distributed_mode(distributed_backend, self.num_nodes) # override dist backend when using tpus if self.on_tpu: @@ -391,7 +387,7 @@ def __init__( self.proc_rank = 0 self.world_size = 1 self.node_rank = 0 - self.configure_slurm_ddp(num_nodes) + self.configure_slurm_ddp(self.num_nodes) # nvidia setup self.set_nvidia_flags(self.is_slurm_managing_tasks, self.data_parallel_device_ids) @@ -423,7 +419,7 @@ def __init__( assert self.precision in (16, 32), 'only 32 or 16 bit precision supported' - if self.precision == 16 and num_tpu_cores is None: + if self.precision == 16 and self.num_tpu_cores is None: use_amp = True self.init_amp(use_amp) diff --git a/pytorch_lightning/trainer/training_loop.py b/pytorch_lightning/trainer/training_loop.py index 839b59018fa84..c6f844370b477 100644 --- a/pytorch_lightning/trainer/training_loop.py +++ b/pytorch_lightning/trainer/training_loop.py @@ -215,24 +215,6 @@ class TrainerTrainLoopMixin(ABC): on_epoch_end: Callable on_validation_end: Callable - @property - def max_nb_epochs(self): - """ - .. warning:: `max_nb_epochs` is deprecated and will be removed in v0.8.0, use `max_epochs` instead. - """ - warnings.warn("`max_nb_epochs` is deprecated and will be removed in " - "v0.8.0, use `max_epochs` instead.", DeprecationWarning) - return self.max_epochs - - @property - def min_nb_epochs(self): - """ - .. warning:: `min_nb_epochs` is deprecated and will be removed in v0.8.0, use `min_epochs` instead. - """ - warnings.warn("`min_nb_epochs` is deprecated and will be removed in " - "v0.8.0, use `min_epochs` instead.", DeprecationWarning) - return self.min_epochs - @abstractmethod def get_model(self): """Warning: this is just empty shell for code implemented in other class.""" diff --git a/tests/test_deprecated.py b/tests/test_deprecated.py new file mode 100644 index 0000000000000..b014c5a29bdaf --- /dev/null +++ b/tests/test_deprecated.py @@ -0,0 +1,55 @@ +"""Test deprecated functionality which will be removed in vX.Y.Z""" + +from pytorch_lightning import Trainer + + +def test_to_be_removed_in_v0_8_0_module_imports(): + from pytorch_lightning.logging.comet_logger import CometLogger # noqa: F811 + from pytorch_lightning.logging.mlflow_logger import MLFlowLogger # noqa: F811 + from pytorch_lightning.logging.test_tube_logger import TestTubeLogger # noqa: F811 + + from pytorch_lightning.pt_overrides.override_data_parallel import ( # noqa: F811 + LightningDataParallel, LightningDistributedDataParallel) + from pytorch_lightning.overrides.override_data_parallel import ( # noqa: F811 + LightningDataParallel, LightningDistributedDataParallel) + + from pytorch_lightning.core.model_saving import ModelIO # noqa: F811 + from pytorch_lightning.core.root_module import LightningModule # noqa: F811 + + from pytorch_lightning.root_module.decorators import data_loader # noqa: F811 + from pytorch_lightning.root_module.grads import GradInformation # noqa: F811 + from pytorch_lightning.root_module.hooks import ModelHooks # noqa: F811 + from pytorch_lightning.root_module.memory import ModelSummary # noqa: F811 + from pytorch_lightning.root_module.model_saving import ModelIO # noqa: F811 + from pytorch_lightning.root_module.root_module import LightningModule # noqa: F811 + + +def test_to_be_removed_in_v0_8_0_trainer(): + mapping_old_new = { + 'gradient_clip': 'gradient_clip_val', + 'nb_gpu_nodes': 'num_nodes', + 'max_nb_epochs': 'max_epochs', + 'min_nb_epochs': 'min_epochs', + 'nb_sanity_val_steps': 'num_sanity_val_steps', + } + # skip 0 since it may be interested as False + kwargs = {k: (i + 1) for i, k in enumerate(mapping_old_new)} + + trainer = Trainer(**kwargs) + + for attr_old in mapping_old_new: + attr_new = mapping_old_new[attr_old] + assert kwargs[attr_old] == getattr(trainer, attr_old), \ + 'Missing deprecated attribute "%s"' % attr_old + assert kwargs[attr_old] == getattr(trainer, attr_new), \ + 'Wrongly passed deprecated argument "%s" to attribute "%s"' % (attr_old, attr_new) + + +def test_to_be_removed_in_v0_9_0_module_imports(): + from pytorch_lightning.core.decorators import data_loader # noqa: F811 + + from pytorch_lightning.logging.comet import CometLogger # noqa: F402 + from pytorch_lightning.logging.mlflow import MLFlowLogger # noqa: F402 + from pytorch_lightning.logging.neptune import NeptuneLogger # noqa: F402 + from pytorch_lightning.logging.test_tube import TestTubeLogger # noqa: F402 + from pytorch_lightning.logging.wandb import WandbLogger # noqa: F402 From 64afdc81c953b539382e1be05841f72dbfee1424 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 12:12:01 -0500 Subject: [PATCH 09/21] updated test --- docs/source/child_modules.rst | 2 +- docs/source/introduction_guide.rst | 66 +++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/docs/source/child_modules.rst b/docs/source/child_modules.rst index a31fb245ba865..6ea0c59951f9a 100644 --- a/docs/source/child_modules.rst +++ b/docs/source/child_modules.rst @@ -3,7 +3,7 @@ Child Modules Research projects tend to test different approaches to the same dataset. This is very easy to do in Lightning with inheritance. -For example, imaging we now want to train an Autoencoder to use as a feature extractor for MNIST images. +For example, imagine we now want to train an Autoencoder to use as a feature extractor for MNIST images. Recall that `LitMNIST` already defines all the dataloading etc... The only things that change in the `Autoencoder` model are the init, forward, training, validation and test step. diff --git a/docs/source/introduction_guide.rst b/docs/source/introduction_guide.rst index 5d90539cc1327..4e0d390030411 100644 --- a/docs/source/introduction_guide.rst +++ b/docs/source/introduction_guide.rst @@ -212,6 +212,50 @@ Notice the code is exactly the same, except now the training dataloading has bee under the `train_dataloader` method. This is great because if you run into a project that uses Lightning and want to figure out how they prepare their training data you can just look in the `train_dataloader` method. +Usually though, we want to separate the things that write to disk in data-processing from +things like transforms which happen in memory. + +.. code-block:: python + + class LitMNIST(pl.LightningModule): + + def prepare_data(self): + # download only + MNIST(os.getcwd(), train=True, download=True) + + def train_dataloader(self): + # no download, just transform + transform=transforms.Compose([transforms.ToTensor(), + transforms.Normalize((0.1307,), (0.3081,))]) + mnist_train = MNIST(os.getcwd(), train=True, download=False, + transform=transform) + return DataLoader(mnist_train, batch_size=64) + +Doing it in the `prepare_data` method ensures that when you have +multiple GPUs you won't overwrite the data. This is a contrived example +but it gets more complicated with things like NLP or Imagenet. + +In general fill these methods with the following: + +.. code-block:: python + + class LitMNIST(pl.LightningModule): + + def prepare_data(self): + # stuff here is done once at the very beginning of training + # before any distributed training starts + + # download stuff + # save to disk + # etc... + + def train_dataloader(self): + # data transforms + # dataset creation + # return a DataLoader + + + Optimizer ^^^^^^^^^ @@ -606,11 +650,11 @@ metrics we care about, generate samples or add more to our logs. loss = loss(y_hat, x) # validation_step outputs.append({'val_loss': loss}) # validation_step - full_loss = outputs.mean() # validation_end + full_loss = outputs.mean() # validation_epoch_end Since the `validation_step` processes a single batch, -in Lightning we also have a `validation_end` method which allows you to compute -statistics on the full dataset and not just the batch. +in Lightning we also have a `validation_epoch_end` method which allows you to compute +statistics on the full dataset after an epoch of validation data and not just the batch. In addition, we define a `val_dataloader` method which tells the trainer what data to use for validation. Notice we split the train split of MNIST into train, validation. We also have to make sure to do the @@ -640,7 +684,7 @@ sample split in the `train_dataloader` method. return mnist_val Again, we've just organized the regular PyTorch code into two steps, the `validation_step` method which -operates on a single batch and the `validation_end` method to compute statistics on all batches. +operates on a single batch and the `validation_epoch_end` method to compute statistics on all batches. If you have these methods defined, Lightning will call them automatically. Now we can train while checking the validation set. @@ -669,7 +713,7 @@ how it will generalize in the "real world." For this, we use a held-out split of Just like the validation loop, we define exactly the same steps for testing: - test_step -- test_end +- test_epoch_end - test_dataloader .. code-block:: python @@ -707,6 +751,17 @@ Once you train your model simply call `.test()`. # run test set trainer.test() +.. rst-class:: sphx-glr-script-out + + Out: + + .. code-block:: none + + -------------------------------------------------------------- + TEST RESULTS + {'test_loss': tensor(1.1703, device='cuda:0')} + -------------------------------------------------------------- + You can also run the test from a saved lightning model .. code-block:: python @@ -881,6 +936,7 @@ you could do your own: Every single part of training is configurable this way. For a full list look at `lightningModule `_. +--------- Callbacks --------- From e4e93b131fd9d38ac6c51df3ca66625422c35149 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 14:12:35 -0500 Subject: [PATCH 10/21] updated test --- pytorch_lightning/trainer/trainer.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pytorch_lightning/trainer/trainer.py b/pytorch_lightning/trainer/trainer.py index 506ec531a5cfd..f524f7c4487f6 100644 --- a/pytorch_lightning/trainer/trainer.py +++ b/pytorch_lightning/trainer/trainer.py @@ -437,7 +437,11 @@ def slurm_job_id(self) -> int: @classmethod def default_attributes(cls): - return vars(cls()) + args = vars(cls()) + none_args = ['checkpoint_callback', 'profiler', 'early_stop_callback'] + for arg in none_args: + args[arg] = None + return args @classmethod def add_argparse_args(cls, parent_parser: ArgumentParser) -> ArgumentParser: From 56ce66b3c9267902ade5ea1a226df6c49476c9f2 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 14:14:23 -0500 Subject: [PATCH 11/21] updated test --- pytorch_lightning/trainer/trainer.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pytorch_lightning/trainer/trainer.py b/pytorch_lightning/trainer/trainer.py index f524f7c4487f6..2098622a0c569 100644 --- a/pytorch_lightning/trainer/trainer.py +++ b/pytorch_lightning/trainer/trainer.py @@ -438,7 +438,14 @@ def slurm_job_id(self) -> int: @classmethod def default_attributes(cls): args = vars(cls()) - none_args = ['checkpoint_callback', 'profiler', 'early_stop_callback'] + none_args = [ + 'checkpoint_callback', + 'profiler', + 'early_stop_callback', + 'accumulation_scheduler', + 'logger' + ] + for arg in none_args: args[arg] = None return args From 4a7259119e5a1988b25f2ab06442c6046f9d8eda Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 14:25:38 -0500 Subject: [PATCH 12/21] updated test --- pytorch_lightning/trainer/trainer.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/pytorch_lightning/trainer/trainer.py b/pytorch_lightning/trainer/trainer.py index 2098622a0c569..722bc38a548a0 100644 --- a/pytorch_lightning/trainer/trainer.py +++ b/pytorch_lightning/trainer/trainer.py @@ -437,17 +437,15 @@ def slurm_job_id(self) -> int: @classmethod def default_attributes(cls): - args = vars(cls()) - none_args = [ - 'checkpoint_callback', - 'profiler', - 'early_stop_callback', - 'accumulation_scheduler', - 'logger' - ] - - for arg in none_args: - args[arg] = None + import inspect + + init_signature = inspect.signature(Trainer) + + args = {} + for param_name in init_signature.parameters: + value = init_signature.parameters[param_name].default + args[param_name] = value + return args @classmethod From 77925dc25d962bf5f3c89d76512879a351bb2e53 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 14:28:11 -0500 Subject: [PATCH 13/21] updated test --- pytorch_lightning/trainer/trainer.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pytorch_lightning/trainer/trainer.py b/pytorch_lightning/trainer/trainer.py index 722bc38a548a0..fd692aa8eacf9 100644 --- a/pytorch_lightning/trainer/trainer.py +++ b/pytorch_lightning/trainer/trainer.py @@ -456,7 +456,12 @@ def add_argparse_args(cls, parent_parser: ArgumentParser) -> ArgumentParser: trainer_default_params = Trainer.default_attributes() for arg in trainer_default_params: - parser.add_argument('--{0}'.format(arg), default=trainer_default_params[arg], dest=arg) + parser.add_argument( + f'--{arg}', + default=trainer_default_params[arg], + dest=arg, + help='autogenerated by pl.Trainer' + ) return parser From 36a3653e35a6be21d6f92fda834bd07cbb7803b1 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 14:28:27 -0500 Subject: [PATCH 14/21] updated test --- pytorch_lightning/trainer/trainer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pytorch_lightning/trainer/trainer.py b/pytorch_lightning/trainer/trainer.py index fd692aa8eacf9..6248fb27aef68 100644 --- a/pytorch_lightning/trainer/trainer.py +++ b/pytorch_lightning/trainer/trainer.py @@ -455,6 +455,7 @@ def add_argparse_args(cls, parent_parser: ArgumentParser) -> ArgumentParser: trainer_default_params = Trainer.default_attributes() + # TODO: get "help" from docstring :) for arg in trainer_default_params: parser.add_argument( f'--{arg}', From 99812146740e336233e78e3f788395c3299ad1ac Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 14:33:26 -0500 Subject: [PATCH 15/21] updated test --- docs/source/introduction_guide.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/introduction_guide.rst b/docs/source/introduction_guide.rst index 4e0d390030411..8a372c5a8046c 100644 --- a/docs/source/introduction_guide.rst +++ b/docs/source/introduction_guide.rst @@ -588,7 +588,7 @@ modify the network. The `Trainer` can add all the available options to an Argume # parametrize the network parser.add_argument('--layer_1_dim', type=int, default=128) - parser.add_argument('--layer_1_dim', type=int, default=256) + parser.add_argument('--layer_2_dim', type=int, default=256) parser.add_argument('--batch_size', type=int, default=64) args = parser.parse_args() From 7493d2b4bba0d4fd0f6ad65cb38ca8f21f6f3dc1 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 14:34:46 -0500 Subject: [PATCH 16/21] updated test --- pytorch_lightning/trainer/trainer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytorch_lightning/trainer/trainer.py b/pytorch_lightning/trainer/trainer.py index 6248fb27aef68..22829c0f187d7 100644 --- a/pytorch_lightning/trainer/trainer.py +++ b/pytorch_lightning/trainer/trainer.py @@ -451,7 +451,7 @@ def default_attributes(cls): @classmethod def add_argparse_args(cls, parent_parser: ArgumentParser) -> ArgumentParser: """Extend existing argparse by default `Trainer` attributes.""" - parser = ArgumentParser(parents=[parent_parser]) + parser = ArgumentParser(parents=[parent_parser], add_help=False) trainer_default_params = Trainer.default_attributes() From 28f6200444188617a928c9020a551a5e0badc4b5 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 14:37:41 -0500 Subject: [PATCH 17/21] updated test --- docs/source/introduction_guide.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/introduction_guide.rst b/docs/source/introduction_guide.rst index 8a372c5a8046c..ad3761ef03f9e 100644 --- a/docs/source/introduction_guide.rst +++ b/docs/source/introduction_guide.rst @@ -590,6 +590,8 @@ modify the network. The `Trainer` can add all the available options to an Argume 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 = pl.Trainer.add_argparse_args(parser) + args = parser.parse_args() Now we can parametrize the LightningModule. From c9e39362a0bccc0de53ef440f1a8a162ccd2f1ab Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 14:39:26 -0500 Subject: [PATCH 18/21] updated test --- docs/source/introduction_guide.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/introduction_guide.rst b/docs/source/introduction_guide.rst index ad3761ef03f9e..3fcf7189554c1 100644 --- a/docs/source/introduction_guide.rst +++ b/docs/source/introduction_guide.rst @@ -590,6 +590,8 @@ modify the network. The `Trainer` can add all the available options to an Argume 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) + + # add all the available options to the trainer parser = pl.Trainer.add_argparse_args(parser) args = parser.parse_args() From 767dc2b9659586ab72a6c04c60cae389010aa028 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 14:39:47 -0500 Subject: [PATCH 19/21] updated test --- docs/source/hyperparameters.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/source/hyperparameters.rst b/docs/source/hyperparameters.rst index e802473f7ba06..ef0c9ce3ae3fd 100644 --- a/docs/source/hyperparameters.rst +++ b/docs/source/hyperparameters.rst @@ -19,6 +19,10 @@ modify the network. The `Trainer` can add all the available options to an Argume 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) + + # add all the available options to the trainer + parser = pl.Trainer.add_argparse_args(parser) + args = parser.parse_args() Now we can parametrize the LightningModule. From 532c55c2a2444116b184008ee9b3c7008ae4bb15 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 14:41:40 -0500 Subject: [PATCH 20/21] updated test --- pytorch_lightning/trainer/deprecated_api.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pytorch_lightning/trainer/deprecated_api.py b/pytorch_lightning/trainer/deprecated_api.py index 08f5e449eabc4..8c4ca8648b5bb 100644 --- a/pytorch_lightning/trainer/deprecated_api.py +++ b/pytorch_lightning/trainer/deprecated_api.py @@ -75,13 +75,15 @@ def min_nb_epochs(self, min_epochs): @property def nb_sanity_val_steps(self): """Back compatibility, will be removed in v0.8.0""" - warnings.warn("Attribute `nb_sanity_val_steps` has renamed to `num_sanity_val_steps` since v0.5.0" + warnings.warn("Attribute `nb_sanity_val_steps` has renamed to " + "`num_sanity_val_steps` since v0.5.0" " and this method will be removed in v0.8.0", DeprecationWarning) return self.num_sanity_val_steps @nb_sanity_val_steps.setter def nb_sanity_val_steps(self, nb): """Back compatibility, will be removed in v0.8.0""" - warnings.warn("Attribute `nb_sanity_val_steps` has renamed to `num_sanity_val_steps` since v0.5.0" + warnings.warn("Attribute `nb_sanity_val_steps` has renamed to " + "`num_sanity_val_steps` since v0.5.0" " and this method will be removed in v0.8.0", DeprecationWarning) self.num_sanity_val_steps = nb From c3cd720371918d19ca902e7897a7c6304e7f6ae2 Mon Sep 17 00:00:00 2001 From: William Falcon Date: Fri, 6 Mar 2020 14:42:13 -0500 Subject: [PATCH 21/21] updated test --- pytorch_lightning/trainer/trainer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pytorch_lightning/trainer/trainer.py b/pytorch_lightning/trainer/trainer.py index 22829c0f187d7..12eeeb5b2bfcf 100644 --- a/pytorch_lightning/trainer/trainer.py +++ b/pytorch_lightning/trainer/trainer.py @@ -293,7 +293,8 @@ def __init__( self.num_sanity_val_steps = num_sanity_val_steps # Backward compatibility, TODO: remove in v0.8.0 if nb_sanity_val_steps is not None: - warnings.warn("Argument `nb_sanity_val_steps` has renamed to `num_sanity_val_steps` since v0.5.0" + warnings.warn("Argument `nb_sanity_val_steps` has renamed to " + "`num_sanity_val_steps` since v0.5.0" " and this method will be removed in v0.8.0", DeprecationWarning) self.nb_sanity_val_steps = nb_sanity_val_steps self.print_nan_grads = print_nan_grads