diff --git a/pytorch_lightning/loggers/neptune.py b/pytorch_lightning/loggers/neptune.py index 486527cd59..9e7e37c7a6 100644 --- a/pytorch_lightning/loggers/neptune.py +++ b/pytorch_lightning/loggers/neptune.py @@ -22,11 +22,9 @@ from typing import Any, Dict, Iterable, List, Optional, Union try: import neptune from neptune.experiments import Experiment - _NEPTUNE_AVAILABLE = True except ImportError: # pragma: no-cover neptune = None Experiment = None - _NEPTUNE_AVAILABLE = False import torch from torch import is_tensor @@ -50,52 +48,57 @@ class NeptuneLogger(LightningLoggerBase): **ONLINE MODE** - Example: - >>> from pytorch_lightning import Trainer - >>> from pytorch_lightning.loggers import NeptuneLogger - >>> # arguments made to NeptuneLogger are passed on to the neptune.experiments.Experiment class - >>> # We are using an api_key for the anonymous user "neptuner" but you can use your own. - >>> neptune_logger = NeptuneLogger( - ... api_key='ANONYMOUS', - ... project_name='shared/pytorch-lightning-integration', - ... experiment_name='default', # Optional, - ... params={'max_epochs': 10}, # Optional, - ... tags=['pytorch-lightning', 'mlp'] # Optional, - ... ) - >>> trainer = Trainer(max_epochs=10, logger=neptune_logger) + .. code-block:: python + + from pytorch_lightning import Trainer + from pytorch_lightning.loggers import NeptuneLogger + + # arguments made to NeptuneLogger are passed on to the neptune.experiments.Experiment class + # We are using an api_key for the anonymous user "neptuner" but you can use your own. + neptune_logger = NeptuneLogger( + api_key='ANONYMOUS', + project_name='shared/pytorch-lightning-integration', + experiment_name='default', # Optional, + params={'max_epochs': 10}, # Optional, + tags=['pytorch-lightning', 'mlp'] # Optional, + ) + trainer = Trainer(max_epochs=10, logger=neptune_logger) **OFFLINE MODE** - Example: - >>> from pytorch_lightning.loggers import NeptuneLogger - >>> # arguments made to NeptuneLogger are passed on to the neptune.experiments.Experiment class - >>> neptune_logger = NeptuneLogger( - ... offline_mode=True, - ... project_name='USER_NAME/PROJECT_NAME', - ... experiment_name='default', # Optional, - ... params={'max_epochs': 10}, # Optional, - ... tags=['pytorch-lightning', 'mlp'] # Optional, - ... ) - >>> trainer = Trainer(max_epochs=10, logger=neptune_logger) + .. code-block:: python + + from pytorch_lightning.loggers import NeptuneLogger + + # arguments made to NeptuneLogger are passed on to the neptune.experiments.Experiment class + neptune_logger = NeptuneLogger( + offline_mode=True, + project_name='USER_NAME/PROJECT_NAME', + experiment_name='default', # Optional, + params={'max_epochs': 10}, # Optional, + tags=['pytorch-lightning', 'mlp'] # Optional, + ) + trainer = Trainer(max_epochs=10, logger=neptune_logger) Use the logger anywhere in you :class:`~pytorch_lightning.core.lightning.LightningModule` as follows: - >>> from pytorch_lightning import LightningModule - >>> class LitModel(LightningModule): - ... def training_step(self, batch, batch_idx): - ... # log metrics - ... self.logger.experiment.log_metric('acc_train', ...) - ... # log images - ... self.logger.experiment.log_image('worse_predictions', ...) - ... # log model checkpoint - ... self.logger.experiment.log_artifact('model_checkpoint.pt', ...) - ... self.logger.experiment.whatever_neptune_supports(...) - ... - ... def any_lightning_module_function_or_hook(self): - ... self.logger.experiment.log_metric('acc_train', ...) - ... self.logger.experiment.log_image('worse_predictions', ...) - ... self.logger.experiment.log_artifact('model_checkpoint.pt', ...) - ... self.logger.experiment.whatever_neptune_supports(...) + .. code-block:: python + + class LitModel(LightningModule): + def training_step(self, batch, batch_idx): + # log metrics + self.logger.experiment.log_metric('acc_train', ...) + # log images + self.logger.experiment.log_image('worse_predictions', ...) + # log model checkpoint + self.logger.experiment.log_artifact('model_checkpoint.pt', ...) + self.logger.experiment.whatever_neptune_supports(...) + + def any_lightning_module_function_or_hook(self): + self.logger.experiment.log_metric('acc_train', ...) + self.logger.experiment.log_image('worse_predictions', ...) + self.logger.experiment.log_artifact('model_checkpoint.pt', ...) + self.logger.experiment.whatever_neptune_supports(...) If you want to log objects after the training is finished use ``close_after_fit=False``: @@ -171,7 +174,7 @@ class NeptuneLogger(LightningLoggerBase): experiment_name: Optional[str] = None, **kwargs ): - if not _NEPTUNE_AVAILABLE: + if neptune is None: raise ImportError('You want to use `neptune` logger which is not installed yet,' ' install it with `pip install neptune-client`.') super().__init__() diff --git a/requirements/extra.txt b/requirements/extra.txt index ea1e00631f..dc5d80926b 100644 --- a/requirements/extra.txt +++ b/requirements/extra.txt @@ -1,7 +1,6 @@ # extended list of package dependencies to reach full functionality # TODO: this shall be removed as we mock them in tests -neptune-client>=0.4.109 comet-ml>=3.1.12 mlflow>=1.0.0 test_tube>=0.7.5 diff --git a/tests/loggers/test_all.py b/tests/loggers/test_all.py index 5e5c7afbd8..44c2ea1de7 100644 --- a/tests/loggers/test_all.py +++ b/tests/loggers/test_all.py @@ -40,8 +40,9 @@ def _get_logger_args(logger_class, save_dir): TestTubeLogger, WandbLogger, ]) +@mock.patch('pytorch_lightning.loggers.neptune.neptune') @mock.patch('pytorch_lightning.loggers.wandb.wandb') -def test_loggers_fit_test(wandb, tmpdir, monkeypatch, logger_class): +def test_loggers_fit_test(wandb, neptune, tmpdir, monkeypatch, logger_class): """Verify that basic functionality of all loggers.""" os.environ['PL_DEV_DEBUG'] = '0' @@ -169,7 +170,8 @@ def test_loggers_save_dir_and_weights_save_path(wandb, tmpdir, monkeypatch, logg TestTubeLogger, # The WandbLogger gets tested for pickling in its own test. ]) -def test_loggers_pickle(tmpdir, monkeypatch, logger_class): +@mock.patch('pytorch_lightning.loggers.neptune.neptune') +def test_loggers_pickle(neptune, tmpdir, monkeypatch, logger_class): """Verify that pickling trainer with logger works.""" if logger_class == CometLogger: # prevent comet logger from trying to print at exit, since @@ -242,11 +244,12 @@ class RankZeroLoggerCheck(Callback): @pytest.mark.parametrize("logger_class", [ TensorBoardLogger, MLFlowLogger, - NeptuneLogger, + # NeptuneLogger, # TODO: fix: https://github.com/PyTorchLightning/pytorch-lightning/pull/3256 TestTubeLogger, ]) -def test_logger_created_on_rank_zero_only(tmpdir, monkeypatch, logger_class): - """ Test that loggers get replaced by dummy logges on global rank > 0""" +@mock.patch('pytorch_lightning.loggers.neptune.neptune') +def test_logger_created_on_rank_zero_only(neptune, tmpdir, monkeypatch, logger_class): + """ Test that loggers get replaced by dummy loggers on global rank > 0""" if logger_class == CometLogger: # prevent comet logger from trying to print at exit, since # pytest's stdout/stderr redirection breaks it diff --git a/tests/loggers/test_neptune.py b/tests/loggers/test_neptune.py index 3e8bb8c6bf..a0ce25fbe6 100644 --- a/tests/loggers/test_neptune.py +++ b/tests/loggers/test_neptune.py @@ -73,7 +73,8 @@ def test_neptune_additional_methods(neptune): created_experiment.append_tags.assert_called_once_with('two', 'tags') -def test_neptune_leave_open_experiment_after_fit(tmpdir): +@patch('pytorch_lightning.loggers.neptune.neptune') +def test_neptune_leave_open_experiment_after_fit(neptune, tmpdir): """Verify that neptune experiment was closed after training""" model = EvalModelTemplate()