2020-06-19 15:00:46 +00:00
|
|
|
.. testsetup:: *
|
|
|
|
|
|
|
|
from pytorch_lightning.core.lightning import LightningModule
|
|
|
|
from pytorch_lightning.trainer.trainer import Trainer
|
|
|
|
from pytorch_lightning import loggers as pl_loggers
|
|
|
|
|
2020-01-21 20:18:32 +00:00
|
|
|
.. role:: hidden
|
|
|
|
:class: hidden-section
|
2020-08-13 22:56:51 +00:00
|
|
|
|
|
|
|
.. _loggers:
|
2020-01-21 20:18:32 +00:00
|
|
|
|
2020-02-11 04:55:22 +00:00
|
|
|
Loggers
|
2020-01-21 20:18:32 +00:00
|
|
|
===========
|
2020-08-13 13:58:05 +00:00
|
|
|
Lightning supports the most popular logging frameworks (TensorBoard, Comet, etc...).
|
2020-06-19 06:38:10 +00:00
|
|
|
To use a logger, simply pass it into the :class:`~pytorch_lightning.trainer.trainer.Trainer`.
|
|
|
|
Lightning uses TensorBoard by default.
|
|
|
|
|
2020-06-19 15:00:46 +00:00
|
|
|
.. testcode::
|
2020-06-19 06:38:10 +00:00
|
|
|
|
2020-06-19 15:00:46 +00:00
|
|
|
from pytorch_lightning import loggers as pl_loggers
|
|
|
|
|
|
|
|
tb_logger = pl_loggers.TensorBoardLogger('logs/')
|
2020-06-19 06:38:10 +00:00
|
|
|
trainer = Trainer(logger=tb_logger)
|
|
|
|
|
|
|
|
Choose from any of the others such as MLflow, Comet, Neptune, WandB, ...
|
|
|
|
|
2020-06-19 15:00:46 +00:00
|
|
|
.. testcode::
|
2020-06-19 06:38:10 +00:00
|
|
|
|
2020-06-19 15:00:46 +00:00
|
|
|
comet_logger = pl_loggers.CometLogger(save_dir='logs/')
|
2020-06-19 06:38:10 +00:00
|
|
|
trainer = Trainer(logger=comet_logger)
|
|
|
|
|
|
|
|
To use multiple loggers, simply pass in a ``list`` or ``tuple`` of loggers ...
|
|
|
|
|
2020-06-19 15:00:46 +00:00
|
|
|
.. testcode::
|
2020-06-19 06:38:10 +00:00
|
|
|
|
2020-06-19 15:00:46 +00:00
|
|
|
tb_logger = pl_loggers.TensorBoardLogger('logs/')
|
|
|
|
comet_logger = pl_loggers.CometLogger(save_dir='logs/')
|
2020-06-19 06:38:10 +00:00
|
|
|
trainer = Trainer(logger=[tb_logger, comet_logger])
|
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
.. note::
|
|
|
|
|
|
|
|
All loggers log by default to `os.getcwd()`. To change the path without creating a logger set
|
|
|
|
`Trainer(default_root_dir='/your/path/to/save/checkpoints')`
|
2020-06-19 06:38:10 +00:00
|
|
|
|
|
|
|
----------
|
|
|
|
|
2020-08-02 02:31:56 +00:00
|
|
|
Logging from a LightningModule
|
|
|
|
------------------------------
|
2020-08-13 13:58:05 +00:00
|
|
|
Use the Result objects to log from any lightning module.
|
2020-08-02 02:31:56 +00:00
|
|
|
|
|
|
|
Training loop logging
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^
|
2020-08-13 13:58:05 +00:00
|
|
|
To log in the training loop use the :class:`TrainResult`.
|
2020-08-02 02:31:56 +00:00
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
def training_step(self, batch, batch_idx):
|
2020-08-13 13:58:05 +00:00
|
|
|
loss = ...
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
result = pl.TrainResult(minimize=loss)
|
|
|
|
result.log('train_loss', loss)
|
|
|
|
return result
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
The `Result` object is simply a dictionary that gives you added methods like `log` and `write`
|
|
|
|
and automatically detaches tensors (except for the minimize value).
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
.. code-block:: python
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
result = pl.TrainResult(minimize=loss)
|
|
|
|
result.log('train_loss', loss)
|
|
|
|
print(result)
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
{'train_loss': tensor([0.2262])}
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
The `TrainResult` can log at two places in the training, on each step (`TrainResult(on_step=True)`) and
|
|
|
|
the aggregate at the end of the epoch (`TrainResult(on_epoch=True)`).
|
2020-08-02 02:31:56 +00:00
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
for epoch in epochs:
|
|
|
|
epoch_outs = []
|
|
|
|
for batch in train_dataloader():
|
|
|
|
# ......
|
|
|
|
out = training_step(batch)
|
|
|
|
# < ----------- log (on_step=True)
|
|
|
|
epoch_outs.append(out)
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
# < -------------- log (on_epoch=True)
|
|
|
|
auto_reduce_log(epoch_outs)
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
Validation loop logging
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
To log in the training loop use the :class:`EvalResult`.
|
2020-08-02 02:31:56 +00:00
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
def validation_step(self, batch, batch_idx):
|
2020-08-02 02:31:56 +00:00
|
|
|
loss = ...
|
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
result = pl.EvalResult()
|
|
|
|
result.log('val_loss', loss)
|
2020-08-02 02:31:56 +00:00
|
|
|
return result
|
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
The `EvalResult` object is simply a dictionary that gives you added methods like `log` and `write`
|
|
|
|
and automatically detaches tensors (except for the minimize value).
|
2020-08-02 02:31:56 +00:00
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
result = pl.EvalResult()
|
|
|
|
result.log('val_loss', loss)
|
|
|
|
print(result)
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
{'val_loss': tensor([0.2262])}
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
The `EvalResult` can log at two places in the validation loop, on each step (`EvalResult(on_step=True)`) and
|
|
|
|
the aggregate at the end of the epoch (`EvalResult(on_epoch=True)`).
|
2020-08-02 02:31:56 +00:00
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
def run_val_loop():
|
|
|
|
epoch_outs = []
|
|
|
|
for batch in val_dataloader():
|
|
|
|
out = validation_step(batch)
|
|
|
|
# < ----------- log (on_step=True)
|
|
|
|
epoch_outs.append(out)
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
# < -------------- log (on_epoch=True)
|
|
|
|
auto_reduce_log(epoch_outs)
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
Test loop logging
|
|
|
|
^^^^^^^^^^^^^^^^^
|
|
|
|
See the previous section.
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
Manual logging
|
|
|
|
^^^^^^^^^^^^^^
|
|
|
|
For certain things like histograms, text, images, etc... you may need to use the logger object directly.
|
2020-08-02 02:31:56 +00:00
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
def training_step(...):
|
|
|
|
...
|
|
|
|
# the logger you used (in this case tensorboard)
|
|
|
|
tensorboard = self.logger.experiment
|
|
|
|
tensorboard.add_histogram(...)
|
|
|
|
tensorboard.add_figure(...)
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
This also applies to Callbacks
|
2020-08-02 02:31:56 +00:00
|
|
|
|
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
----------
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
Logging from a Callback
|
|
|
|
-----------------------
|
|
|
|
To log from a callback, access the logger object directly
|
2020-08-02 02:31:56 +00:00
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
class MyCallback(Callback):
|
2020-08-02 02:31:56 +00:00
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
def on_train_epoch_end(self, trainer, pl_module):
|
|
|
|
tensorboard = pl_module.logger.experiment
|
|
|
|
tensorboard.add_histogram(...)
|
|
|
|
tensorboard.add_figure(...)
|
2020-08-02 02:31:56 +00:00
|
|
|
|
|
|
|
----------
|
|
|
|
|
2020-08-13 13:58:05 +00:00
|
|
|
Make a Custom Logger
|
|
|
|
--------------------
|
2020-06-19 06:38:10 +00:00
|
|
|
|
|
|
|
You can implement your own logger by writing a class that inherits from
|
|
|
|
:class:`LightningLoggerBase`. Use the :func:`~pytorch_lightning.loggers.base.rank_zero_only`
|
|
|
|
decorator to make sure that only the first process in DDP training logs data.
|
|
|
|
|
2020-06-19 15:00:46 +00:00
|
|
|
.. testcode::
|
2020-06-19 06:38:10 +00:00
|
|
|
|
|
|
|
from pytorch_lightning.utilities import rank_zero_only
|
|
|
|
from pytorch_lightning.loggers import LightningLoggerBase
|
2020-06-19 15:00:46 +00:00
|
|
|
|
2020-06-19 06:38:10 +00:00
|
|
|
class MyLogger(LightningLoggerBase):
|
|
|
|
|
|
|
|
@rank_zero_only
|
|
|
|
def log_hyperparams(self, params):
|
|
|
|
# params is an argparse.Namespace
|
|
|
|
# your code to record hyperparameters goes here
|
|
|
|
pass
|
|
|
|
|
|
|
|
@rank_zero_only
|
|
|
|
def log_metrics(self, metrics, step):
|
|
|
|
# metrics is a dictionary of metric names and values
|
|
|
|
# your code to record metrics goes here
|
|
|
|
pass
|
|
|
|
|
|
|
|
def save(self):
|
|
|
|
# Optional. Any code necessary to save logger data goes here
|
|
|
|
pass
|
|
|
|
|
|
|
|
@rank_zero_only
|
|
|
|
def finalize(self, status):
|
|
|
|
# Optional. Any code that needs to be run after training
|
|
|
|
# finishes goes here
|
|
|
|
pass
|
|
|
|
|
|
|
|
If you write a logger that may be useful to others, please send
|
|
|
|
a pull request to add it to Lighting!
|
|
|
|
|
|
|
|
----------
|
|
|
|
|
|
|
|
Supported Loggers
|
|
|
|
-----------------
|
|
|
|
The following are loggers we support
|
|
|
|
|
|
|
|
Comet
|
|
|
|
^^^^^
|
|
|
|
|
|
|
|
.. autoclass:: pytorch_lightning.loggers.comet.CometLogger
|
|
|
|
:noindex:
|
|
|
|
|
2020-08-06 20:05:06 +00:00
|
|
|
CSVLogger
|
|
|
|
^^^^^^^^^
|
|
|
|
|
|
|
|
.. autoclass:: pytorch_lightning.loggers.csv_logs.CSVLogger
|
|
|
|
:noindex:
|
|
|
|
|
2020-06-19 06:38:10 +00:00
|
|
|
MLFlow
|
|
|
|
^^^^^^
|
|
|
|
|
|
|
|
.. autoclass:: pytorch_lightning.loggers.mlflow.MLFlowLogger
|
|
|
|
:noindex:
|
|
|
|
|
|
|
|
Neptune
|
|
|
|
^^^^^^^
|
|
|
|
|
|
|
|
.. autoclass:: pytorch_lightning.loggers.neptune.NeptuneLogger
|
|
|
|
:noindex:
|
|
|
|
|
|
|
|
Tensorboard
|
|
|
|
^^^^^^^^^^^^
|
|
|
|
|
|
|
|
.. autoclass:: pytorch_lightning.loggers.tensorboard.TensorBoardLogger
|
|
|
|
:noindex:
|
|
|
|
|
|
|
|
Test-tube
|
|
|
|
^^^^^^^^^
|
|
|
|
|
|
|
|
.. autoclass:: pytorch_lightning.loggers.test_tube.TestTubeLogger
|
2020-08-06 10:08:25 +00:00
|
|
|
:noindex:
|
|
|
|
|
2020-08-06 20:05:06 +00:00
|
|
|
Weights and Biases
|
|
|
|
^^^^^^^^^^^^^^^^^^
|
2020-08-06 10:08:25 +00:00
|
|
|
|
2020-08-06 20:05:06 +00:00
|
|
|
.. autoclass:: pytorch_lightning.loggers.wandb.WandbLogger
|
|
|
|
:noindex:
|