Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix logger, tensorboard #610

Merged
merged 6 commits into from
Dec 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pytorch_lightning/logging/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def __init__(self, hparams):
from os import environ
from .base import LightningLoggerBase, rank_zero_only

from .tensorboard import TensorboardLogger
from .tensorboard import TensorBoardLogger

try:
from .test_tube import TestTubeLogger
Expand Down
34 changes: 23 additions & 11 deletions pytorch_lightning/logging/tensorboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from .base import LightningLoggerBase, rank_zero_only


class TensorboardLogger(LightningLoggerBase):
r"""Log to local file system in Tensorboard format
class TensorBoardLogger(LightningLoggerBase):
r"""Log to local file system in TensorBoard format

Implemented using :class:`torch.utils.tensorboard.SummaryWriter`. Logs are saved to
`os.path.join(save_dir, name, version)`
Expand All @@ -18,7 +18,7 @@ class TensorboardLogger(LightningLoggerBase):

.. code-block:: python

logger = TensorboardLogger("tb_logs", name="my_model")
logger = TensorBoardLogger("tb_logs", name="my_model")
trainer = Trainer(logger=logger)
trainer.train(model)

Expand All @@ -35,7 +35,7 @@ def __init__(self, save_dir, name="default", version=None, **kwargs):
super().__init__()
self.save_dir = save_dir
self._name = name
self._version = version if version is not None else None
self._version = version

self._experiment = None
self.kwargs = kwargs
Expand All @@ -59,23 +59,35 @@ def experiment(self):
def log_hyperparams(self, params):
if parse_version(torch.__version__) < parse_version("1.3.0"):
warn(
f"Hyperparameter logging is not available for Torch version {torch.__version__}. "
"Skipping log_hyperparams. Upgrade to Torch 1.3.0 or above to enable "
"hyperparameter logging"
f"Hyperparameter logging is not available for Torch version {torch.__version__}."
" Skipping log_hyperparams. Upgrade to Torch 1.3.0 or above to enable"
" hyperparameter logging."
)
# TODO: some alternative should be added
return
self.experiment.add_hparams(hparam_dict=vars(params))
try:
# in case converting from namespace, todo: rather test if it is namespace
params = vars(params)
except TypeError:
pass
if params is not None:
# `add_hparams` requires both - hparams and metric
self.experiment.add_hparams(hparam_dict=dict(params), metric_dict={})

@rank_zero_only
def log_metrics(self, metrics, step_idx=None):
def log_metrics(self, metrics, step=None):
for k, v in metrics.items():
if isinstance(v, torch.Tensor):
v = v.item()
self.experiment.add_scalar(k, v, step_idx)
self.experiment.add_scalar(k, v, step)

@rank_zero_only
def save(self):
self.experiment.flush()
try:
self.experiment.flush()
except AttributeError:
# you are using PT version (<v1.2) which does not have implemented flush
self.experiment._get_file_writer().flush()

@rank_zero_only
def finalize(self, status):
Expand Down
5 changes: 3 additions & 2 deletions pytorch_lightning/trainer/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def __init__(self):
self.use_ddp2 = None
self.num_gpus = None

def log_metrics(self, metrics, grad_norm_dic):
def log_metrics(self, metrics, grad_norm_dic, step=None):
"""Logs the metric dict passed in.

:param metrics:
Expand All @@ -41,9 +41,10 @@ def log_metrics(self, metrics, grad_norm_dic):
# turn all tensors to scalars
scalar_metrics = self.metrics_to_scalars(metrics)

step = step if step is not None else self.global_step
# log actual metrics
if self.proc_rank == 0 and self.logger is not None:
self.logger.log_metrics(scalar_metrics, step=self.global_step)
self.logger.log_metrics(scalar_metrics, step=step)
self.logger.save()

def add_tqdm_metrics(self, metrics):
Expand Down
28 changes: 13 additions & 15 deletions tests/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from pytorch_lightning.logging import (
LightningLoggerBase,
rank_zero_only,
TensorboardLogger,
TensorBoardLogger,
)
from pytorch_lightning.testing import LightningTestModel

Expand Down Expand Up @@ -169,8 +169,8 @@ def test_comet_pickle(tmpdir, monkeypatch):
except ModuleNotFoundError:
return

hparams = tutils.get_hparams()
model = LightningTestModel(hparams)
# hparams = tutils.get_hparams()
# model = LightningTestModel(hparams)

comet_dir = os.path.join(tmpdir, "cometruns")

Expand Down Expand Up @@ -199,9 +199,9 @@ def test_tensorboard_logger(tmpdir):
hparams = tutils.get_hparams()
model = LightningTestModel(hparams)

logger = TensorboardLogger(save_dir=tmpdir, name="tensorboard_logger_test")
logger = TensorBoardLogger(save_dir=tmpdir, name="tensorboard_logger_test")

trainer_options = dict(max_num_epochs=1, train_percent_check=0.01, logger=logger)
trainer_options = dict(max_epochs=1, train_percent_check=0.01, logger=logger)

trainer = Trainer(**trainer_options)
result = trainer.fit(model)
Expand All @@ -213,14 +213,12 @@ def test_tensorboard_logger(tmpdir):
def test_tensorboard_pickle(tmpdir):
"""Verify that pickling trainer with Tensorboard logger works."""

hparams = tutils.get_hparams()
model = LightningTestModel(hparams)

comet_dir = os.path.join(tmpdir, "cometruns")
# hparams = tutils.get_hparams()
# model = LightningTestModel(hparams)

logger = TensorboardLogger(save_dir=tmpdir, name="tensorboard_pickle_test")
logger = TensorBoardLogger(save_dir=tmpdir, name="tensorboard_pickle_test")

trainer_options = dict(max_num_epochs=1, logger=logger)
trainer_options = dict(max_epochs=1, logger=logger)

trainer = Trainer(**trainer_options)
pkl_bytes = pickle.dumps(trainer)
Expand All @@ -235,7 +233,7 @@ def test_tensorboard_automatic_versioning(tmpdir):
root_dir.mkdir("0")
root_dir.mkdir("1")

logger = TensorboardLogger(save_dir=tmpdir, name="tb_versioning")
logger = TensorBoardLogger(save_dir=tmpdir, name="tb_versioning")

assert logger.version == 2

Expand All @@ -248,14 +246,14 @@ def test_tensorboard_manual_versioning(tmpdir):
root_dir.mkdir("1")
root_dir.mkdir("2")

logger = TensorboardLogger(save_dir=tmpdir, name="tb_versioning", version=1)
logger = TensorBoardLogger(save_dir=tmpdir, name="tb_versioning", version=1)

assert logger.version == 1


@pytest.mark.parametrize("step_idx", [10, None])
def test_tensorboard_log_metrics(tmpdir, step_idx):
logger = TensorboardLogger(tmpdir)
logger = TensorBoardLogger(tmpdir)
metrics = {
"float": 0.3,
"int": 1,
Expand All @@ -266,7 +264,7 @@ def test_tensorboard_log_metrics(tmpdir, step_idx):


def test_tensorboard_log_hyperparams(tmpdir):
logger = TensorboardLogger(tmpdir)
logger = TensorBoardLogger(tmpdir)
hparams = {
"float": 0.3,
"int": 1,
Expand Down