Package livelossplot

livelossplot

livelossplot version - PyPI PyPI status MIT license - PyPI Python version - PyPI GitHub Workflow Status Downloads Twitter @pmigdal

Don't train deep learning models blindfolded! Be impatient and look at each epoch of your training!

(RECENT CHANGES, EXAMPLES IN COLAB, API LOOKUP, CODE)

A live training loss plot in Jupyter Notebook for Keras, PyTorch and other frameworks. An open-source Python package by Piotr Migdał, Bartłomiej Olechno and others. Open for collaboration! (Some tasks are as simple as writing code docstrings, so - no excuses! :))

from livelossplot import PlotLossesKeras

model.fit(X_train, Y_train,
          epochs=10,
          validation_data=(X_test, Y_test),
          callbacks=[PlotLossesKeras()],
          verbose=0)

Animated fig for livelossplot tracking log-loss and accuracy

  • (The most FA)Q: Why not TensorBoard?
  • A: Jupyter Notebook compatibility (for exploration and teaching). The simplicity of use.

Installation

To install this version from PyPI, type:

pip install livelossplot

To get the newest one from this repo (note that we are in the alpha stage, so there may be frequent updates), type:

pip install git+git://github.com/stared/livelossplot.git

Examples

Look at notebook files with full working examples:

You run examples in Colab.

Overview

Text logs are easy, but it's easy to miss the most crucial information: is it learning, doing nothing or overfitting? Visual feedback allows us to keep track of the training process. Now there is one for Jupyter.

If you want to get serious - use TensorBoard, . But what if you just want to train a small model in Jupyter Notebook? Here is a way to do so, using livelossplot as a plug&play component

from livelossplot import …

PlotLosses for a generic API.

plotlosses = PlotLosses()
plotlosses.update({'acc': 0.7, 'val_acc': 0.4, 'loss': 0.9, 'val_loss': 1.1})
plot.send()  # draw, update logs, etc

There are callbacks for common libraries and frameworks: PlotLossesKeras(), PlotLossesKerasTF(), PlotLossesPoutyne(), PlotLossesIgnite().

Feel invited to write, and contribute, your adapter. If you want to use a bare logger, there is MainLogger.

from livelossplot.outputs import …

Plots: MatplotlibPlot, BokehPlot.

Loggers: ExtremaPrinter (to standard output), TensorboardLogger, TensorboardTFLogger, NeptuneLogger.

To use them, initialize PlotLosses with some outputs:

plotlosses = PlotLosses(outputs=[MatplotlibPlot(), TensorboardLogger()])

There are custom matplotlib plots in livelossplot.outputs.matplotlib_subplots you can pass in MatplotlibPlot arguments.

If you like to plot with Bokeh instead of matplotlib, use

plotlosses = PlotLosses(outputs=[BokehPlot()])

Sponsors

This project supported by Jacek Migdał, Marek Cichy, Casper da Costa-Luis, and Piotr Zientara. Join the sponsors - show your ❤️ and support, and appear on the list! It will give me time and energy to work on this project.

This project is also supported by a European program Program Operacyjny Inteligentny Rozwój for GearShift - building the engine of behavior of wheeled motor vehicles and map’s generation based on artificial intelligence algorithms implemented on the Unreal Engine platform lead by ECC Games (NCBR grant GameINN).

Trivia

It started as this gist. Since it went popular, I decided to rewrite it as a package.

Oh, and I am in general interested in data vis, see Simple diagrams of convoluted neural networks (and overview of deep learning architecture diagrams):

A good diagram is worth a thousand equations — let’s create more of these!

…or my other data vis projects.

Todo

If you want more functionality - open an Issue or even better - prepare a Pull Request.

Expand source code
"""
.. include:: ../README.md
"""

import sys
import warnings
from importlib.util import find_spec

from .main_logger import MainLogger
from .plot_losses import PlotLosses
from . import inputs
from .inputs import *
from . import outputs
from .version import __version__

_input_plugin_dict = {
    'keras': 'Keras',
    'tf_keras': 'KerasTF',
    'pytorch_ignite': 'Ignite',
    'poutyne': 'Poutyne',
}


class OldDependenciesFinder:
    """
    Data package module loader finder. This class sits on `sys.meta_path` and returns the
    loader it knows for a given path, if it knows a compatible loader.
    """
    @classmethod
    def find_spec(self, fullname: str, *_, **__):
        """This functions is what gets executed by the loader.
        Args:
            fullname: name of the called module
        """
        parts = fullname.split('.')
        if len(parts) == 2 and parts[0] == 'livelossplot' and parts[1] in _input_plugin_dict:
            name = parts[1]
            msg = 'livelossplot.{name} will be deprecated, please use livelossplot.inputs.{name}\n'
            msg += 'or use callback directly: from livelossplot import PlotLosses{new_name}'
            warnings.warn(msg.format(name=name, new_name=_input_plugin_dict[name]), DeprecationWarning)
            fullname = 'livelossplot.inputs.{name}'.format(name=name)
            return find_spec(fullname)
        return None


sys.meta_path.append(OldDependenciesFinder())

__all__ = [
    'MainLogger', 'inputs', 'outputs', 'PlotLosses', 'PlotLossesKeras', 'PlotLossesKerasTF', 'PlotLossesIgnite',
    'PlotLossesPoutyne'
]

Sub-modules

livelossplot.inputs
livelossplot.main_logger
livelossplot.outputs
livelossplot.plot_losses
livelossplot.version

Livelossplot version number

Functions

def PlotLossesIgnite(**kwargs)

PlotLosses callback for PyTorch-Ignite, a library for PyTorch.

Args

**kwargs
key-arguments which are passed to PlotLosses

Notes

Requires pytorch-ignite to be installed, https://github.com/pytorch/ignite.

Expand source code
def PlotLossesIgnite(**kwargs):
    """PlotLosses callback for PyTorch-Ignite, a library for PyTorch.
    Args:
        **kwargs: key-arguments which are passed to PlotLosses

    Notes:
        Requires pytorch-ignite to be installed, <https://github.com/pytorch/ignite>.
    """
    from .pytorch_ignite import PlotLossesCallback
    return PlotLossesCallback(**kwargs)
def PlotLossesKeras(**kwargs)

PlotLosses callback for Keras (as a standalone library, not a TensorFlow module).

Args

**kwargs
key-arguments which are passed to PlotLosses

Notes

Requires keras to be installed.

Expand source code
def PlotLossesKeras(**kwargs):
    """PlotLosses callback for Keras (as a standalone library, not a TensorFlow module).
    Args:
        **kwargs: key-arguments which are passed to PlotLosses

    Notes:
        Requires keras to be installed.
    """
    from .keras import PlotLossesCallback
    return PlotLossesCallback(**kwargs)
def PlotLossesKerasTF(**kwargs)

PlotLosses callback for Keras (as a module of TensorFlow).

Args

**kwargs
key-arguments which are passed to PlotLosses

Notes

Requires tensorflow to be installed.

Expand source code
def PlotLossesKerasTF(**kwargs):
    """PlotLosses callback for Keras (as a module of TensorFlow).
    Args:
        **kwargs: key-arguments which are passed to PlotLosses

    Notes:
        Requires tensorflow to be installed.
    """
    from .tf_keras import PlotLossesCallback
    return PlotLossesCallback(**kwargs)
def PlotLossesPoutyne(**kwargs)

PlotLosses callback for Poutyne, a library for PyTorch.

Args

**kwargs
key-arguments which are passed to PlotLosses

Notes

Requires poutyne to be installed, https://poutyne.org/.

Expand source code
def PlotLossesPoutyne(**kwargs):
    """PlotLosses callback for Poutyne, a library for PyTorch.
    Args:
        **kwargs: key-arguments which are passed to PlotLosses

    Notes:
        Requires poutyne to be installed, <https://poutyne.org/>.
    """
    from .poutyne import PlotLossesCallback
    return PlotLossesCallback(**kwargs)

Classes

class MainLogger (groups: Optional[Dict[str, List[str]]] = None, metric_to_name: Optional[Dict[str, str]] = None, from_step: int = 0, current_step: int = -1, auto_generate_groups_if_not_available: bool = True, auto_generate_metric_to_name: bool = True, group_patterns: Iterable[Tuple[Pattern[~AnyStr], str]] = (('^(?!val(_|-))(.*)', 'training'), ('^(val(_|-))(.*)', 'validation')), step_names: Union[str, Dict[str, str]] = 'epoch')

Main logger - the aim of this class is to store every log from training Log is a float value with corresponding training engine step

Args

groups
dictionary with grouped metrics for example the group 'accuracy' can contains different stages for example 'validation_accuracy', 'training_accuracy' etc.
metric_to_name
transformation of metric name which can be used to display name we can have short name in the code (acc), but full name on charts (Accuracy)
from_step
step to show in plots (positive: show steps from this one, negative: show only this many last steps)
current_step
current step of the train loop
auto_generate_groups_if_not_available
flag, that enable auto-creation of metric groups base on group patterns
auto_generate_metric_to_name
flag, that enable auto-creation of metric long names base on common shortcuts
group_patterns
you can put there regular expressions to match a few metric names with group and replace its name using second value
step_names
dictionary with a name of x axis for each metrics group or one name for all metrics
Expand source code
class MainLogger:
    """
    Main logger - the aim of this class is to store every log from training
    Log is a float value with corresponding training engine step
    """
    def __init__(
        self,
        groups: Optional[Dict[str, List[str]]] = None,
        metric_to_name: Optional[Dict[str, str]] = None,
        from_step: int = 0,
        current_step: int = -1,
        auto_generate_groups_if_not_available: bool = True,
        auto_generate_metric_to_name: bool = True,
        group_patterns: Iterable[Tuple[Pattern, str]] = (
            (r'^(?!val(_|-))(.*)', 'training'),
            (r'^(val(_|-))(.*)', 'validation'),
        ),
        step_names: Union[str, Dict[str, str]] = 'epoch'
    ):
        """
        Args:
            groups: dictionary with grouped metrics for example the group 'accuracy' can contains different stages
                for example 'validation_accuracy', 'training_accuracy' etc.
            metric_to_name: transformation of metric name which can be used to display name
                we can have short name in the code (acc), but full name on charts (Accuracy)
            from_step: step to show in plots (positive: show steps from this one, negative: show only this many last steps)
            current_step: current step of the train loop
            auto_generate_groups_if_not_available: flag, that enable auto-creation of metric groups
                base on group patterns
            auto_generate_metric_to_name: flag, that enable auto-creation of metric long names
                base on common shortcuts
            group_patterns: you can put there regular expressions to match a few metric names with group
                and replace its name using second value
            step_names: dictionary with a name of x axis for each metrics group or one name for all metrics
        """
        self.log_history = {}
        self.groups = groups if groups is not None else {}
        self.metric_to_name = metric_to_name if metric_to_name else {}
        self.from_step = from_step
        self.current_step = current_step
        self.auto_generate_groups = all((not groups, auto_generate_groups_if_not_available))
        self.auto_generate_metric_to_name = auto_generate_metric_to_name
        self.group_patterns = tuple((re.compile(pattern), replace_with) for pattern, replace_with in group_patterns)
        if isinstance(step_names, str):
            self.step_names = defaultdict(lambda: step_names)
        else:
            self.step_names = defaultdict(lambda: 'epoch', step_names)

    def update(self, logs: Dict[str, float], current_step: Optional[int] = None) -> None:
        """
        Args:
            logs: dictionary with metric names and values
            current_step: current step of the training loop

        Notes:
            Loop step can be controlled outside or inside main logger with autoincrement of self.current_step
        """
        if current_step is None:
            self.current_step += 1
            current_step = self.current_step
        else:
            self.current_step = current_step
        for k, v in logs.items():
            if k not in self.log_history:
                self._add_new_metric(k)
            self.log_history[k].append(LogItem(step=current_step, value=v))

    def _add_new_metric(self, metric_name: str):
        """Add empty list for a new metric and extend metric name transformations
        Args:
            metric_name: name of metric that will be added to log_history as empty list
        """
        self.log_history[metric_name] = []
        if not self.metric_to_name.get(metric_name):
            self._auto_generate_metrics_to_name(metric_name)

    def _auto_generate_metrics_to_name(self, metric_name: str):
        """The function generate transforms for metric names base on patterns
        Args:
            metric_name: name of new appended metric

        Example:
            It can create transformation from val_acc to Validation Accuracy
        """
        suffix = self._find_suffix_with_group_patterns(metric_name)
        if suffix is None and suffix != metric_name:
            return
        similar_metric_names = [m for m in self.log_history.keys() if m.endswith(suffix)]
        if len(similar_metric_names) == 1:
            return
        for name in similar_metric_names:
            new_name = name
            for pattern_to_replace, replace_with in self.group_patterns:
                new_name = re.sub(pattern_to_replace, replace_with, new_name)
            if suffix in COMMON_NAME_SHORTCUTS.keys():
                new_name = new_name.replace(suffix, COMMON_NAME_SHORTCUTS[suffix])
            self.metric_to_name[name] = new_name

    def grouped_log_history(self,
                            raw_names: bool = False,
                            raw_group_names: bool = False) -> Dict[str, Dict[str, List[LogItem]]]:
        """
        Args:
            raw_names: flag, return raw names instead of transformed by metric to name (as in update() input dictionary)
            raw_group_names: flag, return group names without transforming them with COMMON_NAME_SHORTCUTS

        Returns:
            logs grouped by metric groups - groups are passed in the class constructor

        Notes:
            method use group patterns instead of groups if they are available
        """
        if self.auto_generate_groups:
            self.groups = self._auto_generate_groups()
        ret = {}
        sorted_groups = OrderedDict(sorted(self.groups.items(), key=lambda t: t[0]))
        for group_name, names in sorted_groups.items():
            group_name = group_name if raw_group_names else COMMON_NAME_SHORTCUTS.get(group_name, group_name)
            ret[group_name] = {
                name if raw_names else self.metric_to_name.get(name, name): self.history_shorter(name)
                for name in names
            }
        return ret

    def history_shorter(self, name: str, full: bool = False) -> List[LogItem]:
        """
        Args:
            name: metrics name, e.g. 'val_acc' or 'loss'
            full: flag, if True return all, otherwise as specified by the from_step parameter

        Returns:
            a list of log items
        """
        log_metrics = self.log_history[name]
        if full or self.from_step == 0:
            return log_metrics
        elif self.from_step > 0:
            return [x for x in log_metrics if x.step >= self.from_step]
        else:
            current_from_step = self.current_step + self.from_step
            return [x for x in log_metrics if x.step >= current_from_step]

    def _auto_generate_groups(self) -> Dict[str, List[str]]:
        """
        Returns:
            groups generated with group patterns

        Notes:
            Auto create groups base on val_ prefix - this step is skipped if groups are set
                or if group patterns are available
        """
        groups = {}
        for key in self.log_history.keys():
            abs_key = self._find_suffix_with_group_patterns(key)
            if not groups.get(abs_key):
                groups[abs_key] = []
            groups[abs_key].append(key)
        return groups

    def _find_suffix_with_group_patterns(self, metric_name: str) -> str:
        suffix = metric_name
        for pattern, _ in self.group_patterns:
            match = re.match(pattern, metric_name)
            if match:
                suffix = match.groups()[-1]
        return suffix

    def reset(self) -> None:
        """Method clears logs, groups and reset step counter"""
        self.log_history = {}
        self.groups = {}
        self.current_step = -1

    @property
    def groups(self) -> Dict[str, List[str]]:
        """groups getter"""
        return self._groups

    @groups.setter
    def groups(self, value: Dict[str, List[str]]) -> None:
        """groups setter - groups should be dictionary"""
        if value is None:
            self._groups = {}
        self._groups = value

    @property
    def log_history(self) -> Dict[str, List[LogItem]]:
        """logs getter"""
        return self._log_history

    @log_history.setter
    def log_history(self, value: Dict[str, List[LogItem]]) -> None:
        """logs setter - logs can not be overwritten - you can only reset it to empty state"""
        if len(value) > 0:
            raise RuntimeError('Cannot overwrite log history with non empty dictionary')
        self._log_history = value

Instance variables

var groups : Dict[str, List[str]]

groups getter

Expand source code
@property
def groups(self) -> Dict[str, List[str]]:
    """groups getter"""
    return self._groups
var log_history : Dict[str, List[LogItem]]

logs getter

Expand source code
@property
def log_history(self) -> Dict[str, List[LogItem]]:
    """logs getter"""
    return self._log_history

Methods

def grouped_log_history(self, raw_names: bool = False, raw_group_names: bool = False) ‑> Dict[str, Dict[str, List[LogItem]]]

Args

raw_names
flag, return raw names instead of transformed by metric to name (as in update() input dictionary)
raw_group_names
flag, return group names without transforming them with COMMON_NAME_SHORTCUTS

Returns

logs grouped by metric groups - groups are passed in the class constructor

Notes

method use group patterns instead of groups if they are available

Expand source code
def grouped_log_history(self,
                        raw_names: bool = False,
                        raw_group_names: bool = False) -> Dict[str, Dict[str, List[LogItem]]]:
    """
    Args:
        raw_names: flag, return raw names instead of transformed by metric to name (as in update() input dictionary)
        raw_group_names: flag, return group names without transforming them with COMMON_NAME_SHORTCUTS

    Returns:
        logs grouped by metric groups - groups are passed in the class constructor

    Notes:
        method use group patterns instead of groups if they are available
    """
    if self.auto_generate_groups:
        self.groups = self._auto_generate_groups()
    ret = {}
    sorted_groups = OrderedDict(sorted(self.groups.items(), key=lambda t: t[0]))
    for group_name, names in sorted_groups.items():
        group_name = group_name if raw_group_names else COMMON_NAME_SHORTCUTS.get(group_name, group_name)
        ret[group_name] = {
            name if raw_names else self.metric_to_name.get(name, name): self.history_shorter(name)
            for name in names
        }
    return ret
def history_shorter(self, name: str, full: bool = False) ‑> List[LogItem]

Args

name
metrics name, e.g. 'val_acc' or 'loss'
full
flag, if True return all, otherwise as specified by the from_step parameter

Returns

a list of log items

Expand source code
def history_shorter(self, name: str, full: bool = False) -> List[LogItem]:
    """
    Args:
        name: metrics name, e.g. 'val_acc' or 'loss'
        full: flag, if True return all, otherwise as specified by the from_step parameter

    Returns:
        a list of log items
    """
    log_metrics = self.log_history[name]
    if full or self.from_step == 0:
        return log_metrics
    elif self.from_step > 0:
        return [x for x in log_metrics if x.step >= self.from_step]
    else:
        current_from_step = self.current_step + self.from_step
        return [x for x in log_metrics if x.step >= current_from_step]
def reset(self) ‑> None

Method clears logs, groups and reset step counter

Expand source code
def reset(self) -> None:
    """Method clears logs, groups and reset step counter"""
    self.log_history = {}
    self.groups = {}
    self.current_step = -1
def update(self, logs: Dict[str, float], current_step: Optional[int] = None) ‑> None

Args

logs
dictionary with metric names and values
current_step
current step of the training loop

Notes

Loop step can be controlled outside or inside main logger with autoincrement of self.current_step

Expand source code
def update(self, logs: Dict[str, float], current_step: Optional[int] = None) -> None:
    """
    Args:
        logs: dictionary with metric names and values
        current_step: current step of the training loop

    Notes:
        Loop step can be controlled outside or inside main logger with autoincrement of self.current_step
    """
    if current_step is None:
        self.current_step += 1
        current_step = self.current_step
    else:
        self.current_step = current_step
    for k, v in logs.items():
        if k not in self.log_history:
            self._add_new_metric(k)
        self.log_history[k].append(LogItem(step=current_step, value=v))
class PlotLosses (outputs: List[Union[Type[~BO], str]] = ['MatplotlibPlot', 'ExtremaPrinter'], mode: str = 'notebook', **kwargs)

Class collect metrics from the training engine and send it to plugins, when send is called

Args

outputs
list of output modules: objects inheriting from BaseOutput or strings for livelossplot built-in output methods with default parameters
mode
Options: 'notebook' or 'script' - some of outputs need to change some behaviors, depending on the working environment
**kwargs
key-arguments which are passed to MainLogger constructor
Expand source code
class PlotLosses:
    """
    Class collect metrics from the training engine and send it to plugins, when send is called
    """
    def __init__(
        self,
        outputs: List[Union[Type[BO], str]] = ['MatplotlibPlot', 'ExtremaPrinter'],
        mode: str = 'notebook',
        **kwargs
    ):
        """
        Args:
            outputs: list of output modules: objects inheriting from BaseOutput
                or strings for livelossplot built-in output methods with default parameters
            mode: Options: 'notebook' or 'script' - some of outputs need to change some behaviors,
                depending on the working environment
            **kwargs: key-arguments which are passed to MainLogger constructor
        """
        self.logger = MainLogger(**kwargs)
        self.outputs = [getattr(livelossplot.outputs, out)() if isinstance(out, str) else out for out in outputs]
        for out in self.outputs:
            out.set_output_mode(mode)

    def update(self, *args, **kwargs):
        """update logs with arguments that will be passed to main logger"""
        self.logger.update(*args, **kwargs)

    def send(self):
        """Method will send logs to every output class"""
        for output in self.outputs:
            output.send(self.logger)

    def draw(self):
        """Send method substitute from old livelossplot api"""
        warnings.warn('draw will be deprecated, please use send method', PendingDeprecationWarning)
        self.send()

    def reset_outputs(self) -> 'PlotLosses':
        """Resets all outputs.

        Returns:
            Plotlosses object (so it works for chaining)
        """
        self.outputs = []
        return self

    def to_matplotlib(self, **kwargs) -> 'PlotLosses':
        """Appends outputs.MatplotlibPlot output, with specified parameters.

        Args:
            **kwargs: keyword arguments for MatplotlibPlot

        Returns:
            Plotlosses object (so it works for chaining)
        """
        self.outputs.append(outputs.MatplotlibPlot(**kwargs))
        return self

    def to_extrema_printer(self, **kwargs) -> 'PlotLosses':
        """Appends outputs.ExtremaPrinter output, with specified parameters.

        Args:
            **kwargs: keyword arguments for ExtremaPrinter

        Returns:
            Plotlosses object (so it works for chaining)
        """
        self.outputs.append(outputs.ExtremaPrinter(**kwargs))
        return self

    def to_bokeh(self, **kwargs) -> 'PlotLosses':
        """Appends outputs.BokehPlot output, with specified parameters.

        Args:
            **kwargs: keyword arguments for BokehPlot

        Returns:
            Plotlosses object (so it works for chaining)
        """
        self.outputs.append(outputs.BokehPlot(**kwargs))
        return self

    def to_neptune(self, **kwargs) -> 'PlotLosses':
        """Appends outputs.NeptuneLogger output, with specified parameters.

        Args:
            **kwargs: keyword arguments for NeptuneLogger

        Returns:
            Plotlosses object (so it works for chaining)
        """
        self.outputs.append(outputs.NeptuneLogger(**kwargs))
        return self

    def to_tensorboard(self, **kwargs) -> 'PlotLosses':
        """Appends outputs.TensorboardLogger output, with specified parameters.

        Args:
            **kwargs: keyword arguments for TensorboardLogger

        Returns:
            Plotlosses object (so it works for chaining)
        """
        self.outputs.append(outputs.TensorboardLogger(**kwargs))
        return self

    def to_tensorboard_tf(self, **kwargs) -> 'PlotLosses':
        """Appends outputs.TensorboardTFLogger output, with specified parameters.

        Args:
            **kwargs: keyword arguments for TensorboardTFLogger

        Returns:
            Plotlosses object (so it works for chaining)
        """
        self.outputs.append(outputs.TensorboardTFLogger(**kwargs))
        return self

Methods

def draw(self)

Send method substitute from old livelossplot api

Expand source code
def draw(self):
    """Send method substitute from old livelossplot api"""
    warnings.warn('draw will be deprecated, please use send method', PendingDeprecationWarning)
    self.send()
def reset_outputs(self) ‑> PlotLosses

Resets all outputs.

Returns

Plotlosses object (so it works for chaining)

Expand source code
def reset_outputs(self) -> 'PlotLosses':
    """Resets all outputs.

    Returns:
        Plotlosses object (so it works for chaining)
    """
    self.outputs = []
    return self
def send(self)

Method will send logs to every output class

Expand source code
def send(self):
    """Method will send logs to every output class"""
    for output in self.outputs:
        output.send(self.logger)
def to_bokeh(self, **kwargs) ‑> PlotLosses

Appends outputs.BokehPlot output, with specified parameters.

Args

**kwargs
keyword arguments for BokehPlot

Returns

Plotlosses object (so it works for chaining)

Expand source code
def to_bokeh(self, **kwargs) -> 'PlotLosses':
    """Appends outputs.BokehPlot output, with specified parameters.

    Args:
        **kwargs: keyword arguments for BokehPlot

    Returns:
        Plotlosses object (so it works for chaining)
    """
    self.outputs.append(outputs.BokehPlot(**kwargs))
    return self
def to_extrema_printer(self, **kwargs) ‑> PlotLosses

Appends outputs.ExtremaPrinter output, with specified parameters.

Args

**kwargs
keyword arguments for ExtremaPrinter

Returns

Plotlosses object (so it works for chaining)

Expand source code
def to_extrema_printer(self, **kwargs) -> 'PlotLosses':
    """Appends outputs.ExtremaPrinter output, with specified parameters.

    Args:
        **kwargs: keyword arguments for ExtremaPrinter

    Returns:
        Plotlosses object (so it works for chaining)
    """
    self.outputs.append(outputs.ExtremaPrinter(**kwargs))
    return self
def to_matplotlib(self, **kwargs) ‑> PlotLosses

Appends outputs.MatplotlibPlot output, with specified parameters.

Args

**kwargs
keyword arguments for MatplotlibPlot

Returns

Plotlosses object (so it works for chaining)

Expand source code
def to_matplotlib(self, **kwargs) -> 'PlotLosses':
    """Appends outputs.MatplotlibPlot output, with specified parameters.

    Args:
        **kwargs: keyword arguments for MatplotlibPlot

    Returns:
        Plotlosses object (so it works for chaining)
    """
    self.outputs.append(outputs.MatplotlibPlot(**kwargs))
    return self
def to_neptune(self, **kwargs) ‑> PlotLosses

Appends outputs.NeptuneLogger output, with specified parameters.

Args

**kwargs
keyword arguments for NeptuneLogger

Returns

Plotlosses object (so it works for chaining)

Expand source code
def to_neptune(self, **kwargs) -> 'PlotLosses':
    """Appends outputs.NeptuneLogger output, with specified parameters.

    Args:
        **kwargs: keyword arguments for NeptuneLogger

    Returns:
        Plotlosses object (so it works for chaining)
    """
    self.outputs.append(outputs.NeptuneLogger(**kwargs))
    return self
def to_tensorboard(self, **kwargs) ‑> PlotLosses

Appends outputs.TensorboardLogger output, with specified parameters.

Args

**kwargs
keyword arguments for TensorboardLogger

Returns

Plotlosses object (so it works for chaining)

Expand source code
def to_tensorboard(self, **kwargs) -> 'PlotLosses':
    """Appends outputs.TensorboardLogger output, with specified parameters.

    Args:
        **kwargs: keyword arguments for TensorboardLogger

    Returns:
        Plotlosses object (so it works for chaining)
    """
    self.outputs.append(outputs.TensorboardLogger(**kwargs))
    return self
def to_tensorboard_tf(self, **kwargs) ‑> PlotLosses

Appends outputs.TensorboardTFLogger output, with specified parameters.

Args

**kwargs
keyword arguments for TensorboardTFLogger

Returns

Plotlosses object (so it works for chaining)

Expand source code
def to_tensorboard_tf(self, **kwargs) -> 'PlotLosses':
    """Appends outputs.TensorboardTFLogger output, with specified parameters.

    Args:
        **kwargs: keyword arguments for TensorboardTFLogger

    Returns:
        Plotlosses object (so it works for chaining)
    """
    self.outputs.append(outputs.TensorboardTFLogger(**kwargs))
    return self
def update(self, *args, **kwargs)

update logs with arguments that will be passed to main logger

Expand source code
def update(self, *args, **kwargs):
    """update logs with arguments that will be passed to main logger"""
    self.logger.update(*args, **kwargs)