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

Abstract log_figure API that implements reasonable default for all lo… #6227

Conversation

Haydnspass
Copy link

@Haydnspass Haydnspass commented Feb 26, 2021

Transfer of #4975
Sorry for the mess with choosing the wrong branch. It was faster for me to manually include the changes, so I am opening a new PR.

What does this PR do?

Make abstraction layer for figure logging, i.e. add default for logging figures for all implemented loggers.

My suggestion to #4973

ToDo:

  • Base implementation (can close figure)
  • Comet.ML
  • MLFlow.
  • Neptune
  • Tensorboard
  • TestTube (defaults to base)
  • CSV (defaults to base)

Before submitting

  • Was this discussed/approved via a Github issue? (no need for typos and docs improvements)
  • Did you read the contributor guideline, Pull Request section?
  • Did you make sure your PR does only one thing, instead of bundling different changes together? Otherwise, we ask you to create a separate PR for every change.
  • Did you make sure to update the documentation with your changes?
  • Did you write any new necessary tests?
  • Did you verify new and existing tests pass locally with your changes?
  • If you made a notable change (that affects users), did you update the CHANGELOG?

PR review

Anyone in the community is free to review the PR once the tests have passed.
Before you start reviewing make sure you have read Review guidelines. In short, see the following bullet-list:

  • Is this pull request ready for review? (if not, please submit in draft mode)
  • Check that all items from Before submitting are resolved
  • Make sure the title is self-explanatory and the description concisely explains the PR
  • Add labels and milestones (and optionally projects) to the PR so it can be classified; Bugfixes should be including in bug-fix release milestones (m.f.X) and features should be included in (m.X.b) releases.

Did you have fun?

Make sure you had fun coding 🙃

…ggers

Takes a plt.figure (along with some metadata) and logs it to the respective logger
- CSV logger and testtube are in silent no-op
- matplotlib becomes base requirement
@pep8speaks
Copy link

pep8speaks commented Feb 26, 2021

Hello @Haydnspass! Thanks for updating this PR.

There are currently no PEP 8 issues detected in this Pull Request. Cheers! 🍻

Comment last updated at 2021-06-18 11:17:14 UTC

CHANGELOG.md Outdated Show resolved Hide resolved
pytorch_lightning/loggers/base.py Outdated Show resolved Hide resolved
pytorch_lightning/loggers/neptune.py Outdated Show resolved Hide resolved
pytorch_lightning/loggers/base.py Outdated Show resolved Hide resolved
pytorch_lightning/loggers/base.py Outdated Show resolved Hide resolved
@@ -173,6 +174,20 @@ def log_metrics(self, metrics: Dict[str, float], step: Optional[int] = None):
"""
pass

def log_figure(self, name: str, figure: plt.figure, step: Optional[int] = None, close: bool = True) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add additional **kwargs here.
When the user knows they are using a particular logger that supports additinal arguments, we should allow it to be passed down.

for example, in one of the loggers you have a description, and this could be customized then by the user.
This would then still be logger agnostic, where loggers simply ignore unknown **kwargs when it's not applicable.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Funnily I had it including **kwargs two times, and changed it back and forth ...

I do not like it because:

  • Silently ignoring arguments that are unexpected is not what python does by default when you parse **kwargs
  • It'll most certainly break for LoggerCollection unless one implements a more complex logic which then makes the whole implementation unnecessary

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think **kwargs is really necessary here. Each logger can have many different arguments

Silently ignoring arguments that are unexpected is not what python does by default when you parse **kwargs

I don't get this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you add **kwargs it will break LoggerCollection if you don't do anything. So what do you do if you have logger A that can take a certain argument that logger B in your collection does not? Ignore argument, raise?
Or add more complex logic that looks something like this

my_mwargs = {
    'loggerA': {'kwarga': 1},
    'loggerB': {'kwargb': 2},
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--> Needs design decision

requirements.txt Outdated Show resolved Hide resolved
figure.savefig(filename)
self.experiment.log_artifact(self.run_id, filename, artifact_path="figure_" + name)

Path(filename).unlink() # delete temporary file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to wait here before this was uploaded (upload may be async, not sure)?

Also if this is temporary, can we consider this to be saved in /tmp?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point, couldn't find anything in the docs of mlflow ...
I don't like this temporary thing anyways but could not come up with a better solution

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to temporary file

requirements.txt Outdated Show resolved Hide resolved
Copy link
Contributor

@tchaton tchaton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good ! Some comments to be addressed from @awaelchli @justusschock

pytorch_lightning/loggers/mlflow.py Outdated Show resolved Hide resolved
Haydnspass and others added 7 commits March 12, 2021 10:32
@mergify mergify bot removed the has conflicts label Mar 12, 2021
tests/loggers/test_all.py Outdated Show resolved Hide resolved
@awaelchli awaelchli added feature Is an improvement or enhancement logger Related to the Loggers labels May 21, 2021
@Haydnspass Haydnspass marked this pull request as ready for review May 21, 2021 13:56
@stale
Copy link

stale bot commented Jun 4, 2021

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. If you need further help see our docs: https://pytorch-lightning.readthedocs.io/en/latest/generated/CONTRIBUTING.html#pull-request or ask the assistance of a core contributor here or on Slack. Thank you for your contributions.

@stale stale bot added the won't fix This will not be worked on label Jun 4, 2021
@Haydnspass
Copy link
Author

@carmocca @Borda what's the status of the review? The tests pass :)
Changelog.md is conflicting but it does not make sense to update it, cause it will always run behind master if you take a bit of time for the review.

@stale stale bot removed the won't fix This will not be worked on label Jun 4, 2021
@awaelchli awaelchli added the design Includes a design discussion label Jun 14, 2021
@awaelchli awaelchli added this to the v1.4 milestone Jun 14, 2021
@mergify mergify bot removed the has conflicts label Jun 14, 2021
pytorch_lightning/loggers/neptune.py Outdated Show resolved Hide resolved
# ToDo: Once its stable, use ml_flow.log_figure
with tempfile.TemporaryDirectory() as tmp_dir:
figure_path = Path(tmp_dir) / figure_fname
figure.savefig(figure_path)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you check the figure is properly rendered ? From past experience, figure.savefig never worked for me.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just changed the test for it to an actual functional one instead of mocking, and for me it works fine. The .png / .pdf is created as expected.
Locally it works as well. What happened in your case? The file was created but not filled?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was filled, but savefig was adding borders and axis around the image.

@edenlightning edenlightning modified the milestones: v1.4, v1.5 Jul 9, 2021
@Haydnspass
Copy link
Author

@tchaton @Borda how can we best move this forward? I figure there are a few small design decisions to me made by your team which can be found in the conversation above :)

@justusschock
Copy link
Member

justusschock commented Sep 16, 2021

Hi @Haydnspass , I am sorry that the response was delayed so much. What do you think about enabling general media logging first (see #9545 for an example in wandb) for all loggers and then treat (matplotlib) figures just as a special case of images?

That does not mean, that we need to abandon this PR, but maybe you and @borisdayma can put together a draft for a more general logger API for media upon which we can then rebuild this PR?

@Haydnspass
Copy link
Author

Haydnspass commented Sep 20, 2021

Hi @Haydnspass , I am sorry that the response was delayed so much. What do you think about enabling general media logging first (see #9545 for an example in wandb) for all loggers and then treat (matplotlib) figures just as a special case of images?

That does not mean, that we need to abandon this PR, but maybe you and @borisdayma can put together a draft for a more general logger API for media upon which we can then rebuild this PR?

@justusschock
I would argue to start with the log_figure thing cause I have the impression this is a nice little well-defined scope and not too different among the different loggers. Later on, one could try to generalise?

But of course, I don't have an emotional connection to this PR :D if something better/more general appears then this should be used.

The issue for me is, that I don't have much time to work on this, and its a bit unfortunate to run behind master all the time and spend the time on resolving conflicts :/

@awaelchli awaelchli modified the milestones: v1.5, v1.6 Nov 1, 2021
@carmocca
Copy link
Contributor

We've chosen to move away from defining a set interface for all logger implementations as it becomes limiting and difficult when all their nuances and differences are considered.

Closing this PR. Thank you so much for your effort anyways @Haydnspass! 💜

cc @daniellepintz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design Includes a design discussion feature Is an improvement or enhancement has conflicts logger Related to the Loggers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants