Beispiel #1
0
def tic_gauge(self, fig, gridspec):
    """TIC gauge, showing the TIC versus iteration.

    Args:
        self (cockpit.plotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec): GridSpec where the instrument should be
            placed
    """
    # Plot Trace vs iteration
    title = "TIC"

    if check_data(self.tracking_data, ["tic_diag"]):
        plot_args = {
            "x": "iteration",
            "y": "tic_diag",
            "data": self.tracking_data,
            "x_scale": "symlog" if self.show_log_iter else "linear",
            "y_scale": "linear",
            "cmap": self.cmap,
            "EMA": "y",
            "EMA_alpha": self.EMA_alpha,
            "EMA_cmap": self.cmap2,
            "title": title,
            "xlim": "tight",
            "ylim": None,
            "fontweight": "bold",
            "facecolor": self.bg_color_instruments,
        }
        ax = fig.add_subplot(gridspec)
        create_basic_plot(**plot_args, ax=ax)

    if check_data(self.tracking_data, ["tic_trace"]):
        if "ax" in locals():
            ax2 = ax.twinx()
        else:
            ax2 = fig.add_subplot(gridspec)
        plot_args = {
            "x": "iteration",
            "y": "tic_trace",
            "data": self.tracking_data,
            "x_scale": "symlog" if self.show_log_iter else "linear",
            "y_scale": "linear",
            "cmap": self.cmap_backup,
            "EMA": "y",
            "EMA_alpha": self.EMA_alpha,
            "EMA_cmap": self.cmap2_backup,
            "title": title,
            "xlim": "tight",
            "ylim": None,
            "fontweight": "bold",
            "facecolor": self.bg_color_instruments,
        }
        create_basic_plot(**plot_args, ax=ax2)
Beispiel #2
0
def gradient_tests_gauge(self, fig, gridspec):
    """Gauge, showing the the status of several gradient tests.

    All three gradient tests (the norm test, the inner product test, and the
    orthogonality test) indicate how strongly individual gradients in a mini-batch
    scatter around the mean gradient. This information can be used to adapt the
    batch size whenever the information becomes to noisy, as indicated by large
    values.

    The central plot visualizes all three tests in different colors. Each area shows
    how far the individual gradients scatter. The smaller plots show their evolution
    over time.

    **Preview**

    .. image:: ../../_static/instrument_previews/GradientTests.png
        :alt: Preview GradientTests Gauge

    **Requires**

    The gradient test instrument requires data from all three gradient test quantities,
    namely the :class:`~cockpit.quantities.InnerTest`,
    :class:`~cockpit.quantities.NormTest`, and :class:`~cockpit.quantities.OrthoTest`
    quantity classes.

    Args:
        self (CockpitPlotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure.Figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec.GridSpec): GridSpec where the instrument should be
            placed
    """
    # Plot
    title = "Gradient Tests"

    # Check if the required data is available, else skip this instrument
    requires = ["iteration", "InnerTest", "NormTest", "OrthoTest"]
    plot_possible = check_data(self.tracking_data, requires, min_elements=1)
    if not plot_possible:
        if self.debug:
            warnings.warn(
                "Couldn't get the required data for the " + title +
                " instrument",
                stacklevel=1,
            )
        return

    ax = fig.add_subplot(gridspec)
    ax.set_title(title, fontweight="bold", fontsize="large")
    ax.set_axis_off()

    # Gridspecs (inside gridspec)
    gs = gridspec.subgridspec(3, 3, wspace=0.05, hspace=0.1)

    ax_all = fig.add_subplot(gs[1:, 1:])
    ax_norm = fig.add_subplot(gs[1, 0])
    ax_inner = fig.add_subplot(gs[2, 0])
    ax_ortho = fig.add_subplot(gs[0, 2])

    _format(self, ax_all, ax_norm, ax_inner, ax_ortho)
    _plot(self, ax_all, ax_norm, ax_inner, ax_ortho)
Beispiel #3
0
def mean_gsnr_gauge(self, fig, gridspec):
    """Mean GSNR gauge, showing the mean GSNR versus iteration.

    The mean GSNR describes the average gradient signal-to-noise-ratio. `Recent
    work <https://arxiv.org/abs/2001.07384>`_ used this quantity to study the
    generalization performances of neural networks, noting "that larger GSNR during
    training process leads to better generalization performance. The instrument
    shows the mean GSNR versus iteration, overlayed with an exponentially weighted
    average.

    **Preview**

    .. image:: ../../_static/instrument_previews/MeanGSNR.png
        :alt: Preview MeanGSNR Gauge

    **Requires**

    This instrument requires data from the :class:`~cockpit.quantities.MeanGSNR`
    quantity class.

    Args:
        self (CockpitPlotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure.Figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec.GridSpec): GridSpec where the instrument should be
            placed
    """
    # Plot Trace vs iteration
    title = "Mean GSNR"

    # Check if the required data is available, else skip this instrument
    requires = ["MeanGSNR"]
    plot_possible = check_data(self.tracking_data, requires)
    if not plot_possible:
        if self.debug:
            warnings.warn(
                "Couldn't get the required data for the " + title + " instrument",
                stacklevel=1,
            )
        return

    plot_args = {
        "x": "iteration",
        "y": "MeanGSNR",
        "data": self.tracking_data,
        "x_scale": "symlog" if self.show_log_iter else "linear",
        "y_scale": "linear",
        "cmap": self.cmap,
        "EMA": "y",
        "EMA_alpha": self.EMA_alpha,
        "EMA_cmap": self.cmap2,
        "title": title,
        "xlim": "tight",
        "ylim": None,
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments,
    }
    ax = fig.add_subplot(gridspec)
    create_basic_plot(**plot_args, ax=ax)
Beispiel #4
0
def histogram_1d_gauge(self, fig, gridspec, y_scale="log"):
    """One-dimensional histogram of the individual gradient elements.

    This instrument provides a histogram of the gradient element values across all
    individual gradients in a mini-batch. The histogram shows the distribution for
    the last tracked iteration only.

    **Preview**

    .. image:: ../../_static/instrument_previews/Hist1d.png
        :alt: Preview Hist1d Gauge

    **Requires**

    This two dimensional histogram instrument requires data from the
    :class:`~cockpit.quantities.GradHist1d` quantity class.

    Args:
        self (CockpitPlotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure.Figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec.GridSpec): GridSpec where the instrument should be
            placed
        y_scale (str, optional): Scale of the y-axis. Defaults to "log".
    """
    # Plot
    title = "Gradient Element Histogram"

    # Check if the required data is available, else skip this instrument
    requires = ["GradHist1d"]
    plot_possible = check_data(self.tracking_data, requires, min_elements=1)
    if not plot_possible:
        if self.debug:
            warnings.warn(
                "Couldn't get the required data for the " + title +
                " instrument",
                stacklevel=1,
            )
        return

    ax = fig.add_subplot(gridspec)

    plot_args = {
        "title": title,
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments,
        "xlabel": "Gradient Element Value",
        "ylabel": "Frequency",
        "y_scale": y_scale,
    }

    vals, mid_points, width = _get_histogram_data(self.tracking_data)

    ax.bar(mid_points, vals, width=width, color=self.primary_color)

    _beautify_plot(ax=ax, **plot_args)

    ax.set_title(title, fontweight="bold", fontsize="large")
def hyperparameter_gauge(self, fig, gridspec):
    """Hyperparameter gauge, currently showing the learning rate over time.

    Args:
        self (cockpit.plotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec): GridSpec where the instrument should be
            placed
    """
    # Plot Trace vs iteration
    title = "Hyperparameters"

    # Check if the required data is available, else skip this instrument
    requires = ["iteration", "learning_rate"]
    plot_possible = check_data(self.tracking_data, requires)
    if not plot_possible:
        warnings.warn(
            "Couldn't get the required data for the " + title + " instrument",
            stacklevel=1,
        )
        return

    ax = fig.add_subplot(gridspec)

    clean_learning_rate = self.tracking_data[["iteration",
                                              "learning_rate"]].dropna()

    # Plot Settings
    plot_args = {
        "x": "iteration",
        "y": "learning_rate",
        "data": clean_learning_rate,
    }
    ylabel = plot_args["y"].replace("_", " ").title()
    sns.lineplot(**plot_args,
                 ax=ax,
                 label=ylabel,
                 linewidth=2,
                 color=self.secondary_color)

    _beautify_plot(
        ax=ax,
        xlabel=plot_args["x"],
        ylabel=ylabel,
        x_scale="symlog" if self.show_log_iter else "linear",
        title=title,
        xlim="tight",
        fontweight="bold",
        facecolor=self.bg_color_instruments2,
    )

    ax.legend()
    _add_last_value_to_legend(ax)
Beispiel #6
0
def cabs_gauge(self, fig, gridspec):
    """CABS gauge, showing the CABS rule versus iteration.

    If the stopping criterion becomes positive, this suggests stopping the training
    according to

    - Balles, L., Romero, J., & Hennig, P.,
      Coupling adaptive batch sizes with learning rates (2017).

    Args:
        self (cockpit.plotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec): GridSpec where the instrument should be
            placed
    """
    # Plot Trace vs iteration
    title = "CABS"

    # Check if the required data is available, else skip this instrument
    requires = ["cabs"]
    plot_possible = check_data(self.tracking_data, requires)
    if not plot_possible:
        warnings.warn(
            "Couldn't get the required data for the " + title + " instrument",
            stacklevel=1,
        )
        return

    plot_args = {
        "x": "iteration",
        "y": "cabs",
        "data": self.tracking_data,
        "x_scale": "symlog" if self.show_log_iter else "linear",
        "y_scale": "linear",
        "cmap": self.cmap,
        "EMA": "y",
        "EMA_alpha": self.EMA_alpha,
        "EMA_cmap": self.cmap2,
        "title": title,
        "xlim": "tight",
        "ylim": None,
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments,
    }
    ax = fig.add_subplot(gridspec)
    create_basic_plot(**plot_args, ax=ax)
def grad_norm_gauge(self, fig, gridspec):
    """Showing the gradient norm versus iteration.

    Args:
        self (cockpit.plotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec): GridSpec where the instrument should be
            placed
    """
    # Plot Trace vs iteration
    title = "Gradient Norm"

    # Check if the required data is available, else skip this instrument
    requires = ["grad_norm"]
    plot_possible = check_data(self.tracking_data, requires)
    if not plot_possible:
        warnings.warn(
            "Couldn't get the required data for the " + title + " instrument",
            stacklevel=1,
        )
        return

    # Compute
    self.tracking_data["grad_norm_all"] = self.tracking_data.grad_norm.map(
        lambda x: _root_sum_of_squares(x) if type(x) == list else x)

    plot_args = {
        "x": "iteration",
        "y": "grad_norm_all",
        "data": self.tracking_data,
        "x_scale": "symlog" if self.show_log_iter else "linear",
        "y_scale": "linear",
        "cmap": self.cmap,
        "EMA": "y",
        "EMA_alpha": self.EMA_alpha,
        "EMA_cmap": self.cmap2,
        "title": title,
        "xlim": "tight",
        "ylim": None,
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments,
    }
    ax = fig.add_subplot(gridspec)
    create_basic_plot(**plot_args, ax=ax)
def histogram_1d_gauge(self, fig, gridspec, y_scale="log"):
    """One-dimensional histogram of the individual gradient elements.

    Args:
        self (cockpit.plotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec): GridSpec where the instrument should be
            placed
        y_scale (str, optional): Scale of the y-axis. Defaults to "log".
    """
    # Plot
    title = "Gradient Element Histogram"

    # Check if the required data is available, else skip this instrument
    requires = ["edges", "hist_1d"]
    plot_possible = check_data(self.tracking_data, requires, min_elements=1)
    if not plot_possible:
        warnings.warn(
            "Couldn't get the required data for the " + title + " instrument",
            stacklevel=1,
        )
        return

    ax = fig.add_subplot(gridspec)

    plot_args = {
        "title": title,
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments,
        "xlabel": "gradient element value",
        "ylabel": "frequency",
        "y_scale": y_scale,
    }

    vals, mid_points, width = _get_histogram_data(self.tracking_data)

    ax.bar(mid_points, vals, width=width, color=self.primary_color)

    _beautify_plot(ax=ax, **plot_args)

    ax.set_title(title, fontweight="bold", fontsize="large")
Beispiel #9
0
def max_ev_gauge(self, fig, gridspec):
    """Showing the largest eigenvalue of the Hessian versus iteration.

    Args:
        self (cockpit.plotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec): GridSpec where the instrument should be
            placed.
    """
    # Plot Trace vs iteration
    title = "Max Eigenvalue"

    # Check if the required data is available, else skip this instrument
    requires = ["max_ev"]
    plot_possible = check_data(self.tracking_data, requires)
    if not plot_possible:
        warnings.warn(
            "Couldn't get the required data for the " + title + " instrument",
            stacklevel=1,
        )
        return

    plot_args = {
        "x": "iteration",
        "y": "max_ev",
        "data": self.tracking_data,
        "x_scale": "symlog" if self.show_log_iter else "linear",
        "y_scale": "log",
        "cmap": self.cmap,
        "EMA": "y",
        "EMA_alpha": self.EMA_alpha,
        "EMA_cmap": self.cmap2,
        "title": title,
        "xlim": "tight",
        "ylim": None,
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments,
    }
    # part that should be plotted
    ax = fig.add_subplot(gridspec)
    create_basic_plot(**plot_args, ax=ax)
Beispiel #10
0
def gradient_tests_gauge(self, fig, gridspec):
    """Gauge, showing the the status of several gradient tests.

    Args:
        self (cockpit.plotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec): GridSpec where the instrument should be
            placed
    """
    # Plot
    title = "Gradient Tests"

    # Check if the required data is available, else skip this instrument
    requires = ["iteration", "inner_product_test", "norm_test", "orthogonality_test"]
    plot_possible = check_data(self.tracking_data, requires, min_elements=1)
    if not plot_possible:
        warnings.warn(
            "Couldn't get the required data for the " + title + " instrument",
            stacklevel=1,
        )
        return

    ax = fig.add_subplot(gridspec)
    ax.set_title(title, fontweight="bold", fontsize="large")
    ax.set_axis_off()

    # Gridspecs (inside gridspec)
    gs = gridspec.subgridspec(3, 3, wspace=0.05, hspace=0.1)

    ax_all = fig.add_subplot(gs[1:, 1:])
    ax_norm = fig.add_subplot(gs[1, 0])
    ax_inner = fig.add_subplot(gs[2, 0])
    ax_ortho = fig.add_subplot(gs[0, 2])

    _format(self, ax_all, ax_norm, ax_inner, ax_ortho)
    _plot(self, ax_all, ax_norm, ax_inner, ax_ortho)
Beispiel #11
0
def hyperparameter_gauge(self, fig, gridspec):
    """Hyperparameter gauge, currently showing the learning rate over time.

    This instrument visualizes the hyperparameters values over the course of the
    training. Currently, it shows the learning rate, the most likely parameter to
    be adapted during training. The current learning rate is additionally shown
    in the figure's legend.

    **Preview**

    .. image:: ../../_static/instrument_previews/Hyperparameters.png
        :alt: Preview Hyperparameter Gauge

    **Requires**

    This instrument requires the learning rate data passed via the
    :func:`cockpit.Cockpit.log()` method.

    Args:
        self (CockpitPlotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure.Figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec.GridSpec): GridSpec where the instrument should be
            placed
    """
    # Plot Trace vs iteration
    title = "Hyperparameters"

    # Check if the required data is available, else skip this instrument
    requires = ["iteration", "learning_rate"]
    plot_possible = check_data(self.tracking_data, requires)
    if not plot_possible:
        if self.debug:
            warnings.warn(
                "Couldn't get the required data for the " + title +
                " instrument",
                stacklevel=1,
            )
        return

    ax = fig.add_subplot(gridspec)

    clean_learning_rate = self.tracking_data[["iteration",
                                              "learning_rate"]].dropna()

    # Plot Settings
    plot_args = {
        "x": "iteration",
        "y": "learning_rate",
        "data": clean_learning_rate,
    }
    ylabel = plot_args["y"].replace("_", " ").title()
    sns.lineplot(**plot_args,
                 ax=ax,
                 label=ylabel,
                 linewidth=2,
                 color=self.secondary_color)

    _beautify_plot(
        ax=ax,
        xlabel=plot_args["x"],
        ylabel=ylabel,
        x_scale="symlog" if self.show_log_iter else "linear",
        title=title,
        xlim="tight",
        fontweight="bold",
        facecolor=self.bg_color_instruments2,
    )

    ax.legend()
    _add_last_value_to_legend(ax)
Beispiel #12
0
def trace_gauge(self, fig, gridspec):
    """Trace gauge, showing the trace of the Hessian versus iteration.

    The trace of the hessian is the sum of its eigenvalues and thus can indicate
    the overall or average curvature of the loss landscape at the current point.
    Increasing values for the trace indicate a steeper curvature, for example, a
    narrower valley. This instrument shows the trace versus iteration, overlayed
    with an exponentially weighted average.

    **Preview**

    .. image:: ../../_static/instrument_previews/HessTrace.png
        :alt: Preview HessTrace Gauge

    **Requires**

    The trace instrument requires data from the :class:`~cockpit.quantities.HessTrace`
    quantity class.

    Args:
        self (CockpitPlotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure.Figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec.GridSpec): GridSpec where the instrument should be
            placed
    """
    # Plot Trace vs iteration
    title = "Trace"

    # Check if the required data is available, else skip this instrument
    requires = ["HessTrace"]
    plot_possible = check_data(self.tracking_data, requires)
    if not plot_possible:
        if self.debug:
            warnings.warn(
                "Couldn't get the required data for the " + title +
                " instrument",
                stacklevel=1,
            )
        return

    # Compute
    self.tracking_data["HessTrace_all"] = self.tracking_data.HessTrace.map(
        lambda x: sum(x) if type(x) == list else x)

    plot_args = {
        "x": "iteration",
        "y": "HessTrace_all",
        "data": self.tracking_data,
        "x_scale": "symlog" if self.show_log_iter else "linear",
        "y_scale": "linear",
        "cmap": self.cmap,
        "EMA": "y",
        "EMA_alpha": self.EMA_alpha,
        "EMA_cmap": self.cmap2,
        "title": title,
        "xlim": "tight",
        "ylim": None,
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments,
    }
    ax = fig.add_subplot(gridspec)
    create_basic_plot(**plot_args, ax=ax)
Beispiel #13
0
def grad_norm_gauge(self, fig, gridspec):
    """Showing the gradient norm versus iteration.

    If the training gets stuck, due to a small
    :class:`~cockpit.quantities.UpdateSize` it can be the result of both a badly
    chosen learning rate, or from a flat plateau in the loss landscape.
    This instrument shows the gradient norm at each iteration, overlayed with an
    exponentially weighted average, and can thus distinguish these two cases.

    **Preview**

    .. image:: ../../_static/instrument_previews/GradientNorm.png
        :alt: Preview GradientNorm Gauge

    **Requires**

    The gradient norm instrument requires data from the
    :class:`~cockpit.quantities.GradNorm` quantity class.

    Args:
        self (CockpitPlotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure.Figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec.GridSpec): GridSpec where the instrument should be
            placed
    """
    # Plot Trace vs iteration
    title = "Gradient Norm"

    # Check if the required data is available, else skip this instrument
    requires = ["GradNorm"]
    plot_possible = check_data(self.tracking_data, requires)
    if not plot_possible:
        if self.debug:
            warnings.warn(
                "Couldn't get the required data for the " + title +
                " instrument",
                stacklevel=1,
            )
        return

    # Compute
    self.tracking_data["GradNorm_all"] = self.tracking_data.GradNorm.map(
        lambda x: _root_sum_of_squares(x) if type(x) == list else x)

    plot_args = {
        "x": "iteration",
        "y": "GradNorm_all",
        "data": self.tracking_data,
        "x_scale": "symlog" if self.show_log_iter else "linear",
        "y_scale": "linear",
        "cmap": self.cmap,
        "EMA": "y",
        "EMA_alpha": self.EMA_alpha,
        "EMA_cmap": self.cmap2,
        "title": title,
        "xlim": "tight",
        "ylim": None,
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments,
    }
    ax = fig.add_subplot(gridspec)
    create_basic_plot(**plot_args, ax=ax)
Beispiel #14
0
def histogram_2d_gauge(self,
                       fig,
                       gridspec,
                       transformation=None,
                       marginals=True,
                       idx=None):
    """Two-dimensional histogram of the individual gradient and parameter elements.

    This instrument provides a combined histogram of parameter-gradient pairs of
    the network. The values are collected across an entire mini-batch and thus
    captures indvidual gradients as well. The marignal distributions across the
    parameters and gradient values are shown at the top and right respectively.

    The histogram shows the distribution of gradient and parameter elements for
    the last tracked iteration only.

    **Preview**

    .. image:: ../../_static/instrument_previews/Hist2d.png
        :alt: Preview Hist2d Gauge

    **Requires**

    This two dimensional histogram instrument requires data from the
    :class:`~cockpit.quantities.GradHist2d` quantity class.

    Args:
        self (CockpitPlotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure.Figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec.GridSpec): GridSpec where the instrument should be
            placed
        transformation (callable): Some map applied to the bin values as a
            transformation for the plot. Defaults to `None` which means no
            transformation.
        marginals (bool): Whether to plot the marginal histograms as well.
        idx (int): Index of parameter whose histogram data should be used.
            If ``None`` (default), uses data of all parameters.
    """
    # Plot
    title_suffix = "(all)" if idx is None else f"(parameter {idx})"
    title = f"Gradient/Parameter Element Histogram {title_suffix}"

    # Check if the required data is available, else skip this instrument
    requires = ["GradHist2d"]

    plot_possible = check_data(self.tracking_data, requires, min_elements=1)
    if not plot_possible:
        if self.debug:
            warnings.warn(
                "Couldn't get the required data for the " + title +
                " instrument",
                stacklevel=1,
            )
        return

    ax = fig.add_subplot(gridspec)
    ax.set_axis_off()
    ax.set_title(title, fontweight="bold", fontsize="large")

    # Gridspecs (inside gridspec)
    gs = gridspec.subgridspec(3, 3, wspace=0, hspace=0)

    # plot the joint
    if marginals:
        ax_joint = fig.add_subplot(gs[1:, :2])
    else:
        ax_joint = fig.add_subplot(gs[:, :])

    joint_plot_args = {
        "facecolor": self.bg_color_instruments,
        "xlabel": "Parameter Element Value",
        "ylabel": "Gradient Element\nValue",
    }

    df = _get_2d_histogram_data(self.tracking_data,
                                transformation=transformation,
                                idx=idx)

    cmap = self.alpha_cmap

    sns.heatmap(data=df, cbar=False, cmap=cmap, ax=ax_joint)

    _beautify_plot(ax=ax_joint, **joint_plot_args)

    ax_joint.set_xticklabels(_ticks_formatter(ax_joint.get_xticklabels()))
    ax_joint.set_yticklabels(_ticks_formatter(ax_joint.get_yticklabels()))

    # "Zero lines
    # TODO This assumes that the bins are symmetrical!
    ax_joint.axvline(df.shape[1] / 2,
                     ls="-",
                     color="#ababba",
                     linewidth=1.5,
                     zorder=0)
    ax_joint.axhline(df.shape[0] / 2,
                     ls="-",
                     color="#ababba",
                     linewidth=1.5,
                     zorder=0)

    # plot the marginals
    if marginals:
        ax_xmargin = fig.add_subplot(gs[1:, 2])
        ax_xmargin.set_xscale("log")
        ax_xmargin.get_yaxis().set_visible(False)

        vals, mid_points, bin_size = _get_xmargin_histogram_data(
            self.tracking_data, idx=idx)
        ax_xmargin.set_ylim(
            [mid_points[0] - bin_size / 2, mid_points[-1] + bin_size / 2])
        ax_xmargin.barh(mid_points,
                        vals,
                        height=bin_size,
                        color=self.primary_color,
                        linewidth=0.1)
        ax_xmargin.xaxis.set_minor_locator(ticker.MaxNLocator(3))

        ax_ymargin = fig.add_subplot(gs[0, :2])
        ax_ymargin.set_yscale("log")
        ax_ymargin.get_xaxis().set_visible(False)

        vals, mid_points, bin_size = _get_ymargin_histogram_data(
            self.tracking_data, idx=idx)
        ax_ymargin.set_xlim(
            [mid_points[0] - bin_size / 2, mid_points[-1] + bin_size / 2])
        ax_ymargin.bar(
            mid_points,
            vals,
            width=bin_size,
            color=self.primary_color,
            linewidth=0.2,
        )
        ax_ymargin.yaxis.set_minor_locator(ticker.MaxNLocator(3))
        ax_ymargin.yaxis.set_minor_formatter(ticker.FormatStrFormatter("%.3g"))
Beispiel #15
0
def histogram_2d_gauge(self,
                       fig,
                       gridspec,
                       transformation=None,
                       marginals=True,
                       idx=None):
    """Two-dimensional histogram of the individual gradient and parameter elements.

    Args:
        self (cockpit.plotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec): GridSpec where the instrument should be
            placed
        transformation (method): Some map applied to the bin values as a
            transformation for the plot. Defaults to `None` which means no
            transformation.
        marginal (bool): Whether to plot the marginal histograms as well.
        idx (int): Index of parameter whose histogram data should be used.
            If ``None`` (default), uses data of all parameters.
    """
    # Plot
    title_suffix = "(all)" if idx is None else f"(parameter {idx})"
    title = f"Gradient/Parameter Element Histogram {title_suffix}"

    # Check if the required data is available, else skip this instrument
    key_prefix = "" if idx is None else f"param_{idx}_"
    x_key = key_prefix + "x_edges"
    y_key = key_prefix + "y_edges"
    hist_key = key_prefix + "hist_2d"
    requires = [x_key, y_key, hist_key]

    plot_possible = check_data(self.tracking_data, requires, min_elements=1)
    if not plot_possible:
        warnings.warn(
            "Couldn't get the required data for the " + title + " instrument",
            stacklevel=1,
        )
        return

    ax = fig.add_subplot(gridspec)
    ax.set_axis_off()
    ax.set_title(title, fontweight="bold", fontsize="large")

    # Gridspecs (inside gridspec)
    gs = gridspec.subgridspec(3, 3, wspace=0, hspace=0)

    # plot the joint
    if marginals:
        ax_joint = fig.add_subplot(gs[1:, :2])
    else:
        ax_joint = fig.add_subplot(gs[:, :])

    joint_plot_args = {
        "facecolor": self.bg_color_instruments,
        "xlabel": "parameter element value",
        "ylabel": "gradient element value",
    }

    df = _get_2d_histogram_data(self.tracking_data,
                                transformation=transformation,
                                idx=idx)

    cmap = self.alpha_cmap

    sns.heatmap(data=df, cbar=False, cmap=cmap, ax=ax_joint)

    _beautify_plot(ax=ax_joint, **joint_plot_args)

    # "Zero lines
    # TODO This assumes that the bins are symmetrical!
    ax_joint.axvline(df.shape[1] / 2,
                     ls="-",
                     color="#ababba",
                     linewidth=1.5,
                     zorder=0)
    ax_joint.axhline(df.shape[0] / 2,
                     ls="-",
                     color="#ababba",
                     linewidth=1.5,
                     zorder=0)

    # plot the marginals
    if marginals:
        ax_xmargin = fig.add_subplot(gs[1:, 2])
        ax_xmargin.set_xscale("log")
        ax_xmargin.get_yaxis().set_visible(False)

        vals, mid_points, bin_size = _get_xmargin_histogram_data(
            self.tracking_data, idx=idx)
        ax_xmargin.set_ylim(
            [mid_points[0] - bin_size / 2, mid_points[-1] + bin_size / 2])
        ax_xmargin.barh(mid_points,
                        vals,
                        height=bin_size,
                        color=self.primary_color,
                        linewidth=0.1)

        ax_ymargin = fig.add_subplot(gs[0, :2])
        ax_ymargin.set_yscale("log")
        ax_ymargin.get_xaxis().set_visible(False)

        vals, mid_points, bin_size = _get_ymargin_histogram_data(
            self.tracking_data, idx=idx)
        ax_ymargin.set_xlim(
            [mid_points[0] - bin_size / 2, mid_points[-1] + bin_size / 2])
        ax_ymargin.bar(
            mid_points,
            vals,
            width=bin_size,
            color=self.primary_color,
            linewidth=0.2,
        )
Beispiel #16
0
def alpha_gauge(self, fig, gridspec):
    """Showing a distribution of the alpha values since the last plot.

    Args:
        self (cockpit.plotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec): GridSpec where the instrument should be
            placed.
    """
    # Plot Alpha Distribution
    title = "Alpha Distribution"

    # Check if the required data is available, else skip this instrument
    requires = ["alpha"]
    plot_possible = check_data(self.tracking_data, requires, min_elements=2)
    if not plot_possible:
        warnings.warn(
            "Couldn't get the required data for the " + title + " instrument",
            stacklevel=1,
        )
        return

    plot_args = {
        "xlabel": "Local Step Length",
        "ylabel": "Stand. Loss",
        "title": title,
        "xlim": [-1.5, 1.5],
        "ylim": [0, 1.75],
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments,
        "zero_lines": True,
        "center": [True, False],
    }
    color_all = "gray"
    color_last = self.primary_color
    color_parabola = self.secondary_color

    ax = fig.add_subplot(gridspec)

    # Plot unit parabola
    x = np.linspace(plot_args["xlim"][0], plot_args["xlim"][1], 100)
    y = x ** 2
    ax.plot(x, y, linewidth=2, color=color_parabola)

    _beautify_plot(**plot_args, ax=ax)

    # Alpha Histogram
    ax2 = ax.twinx()
    # All alphas
    sns.distplot(
        self.tracking_data["alpha"].dropna(),
        ax=ax2,
        # norm_hist=True,
        fit=stats.norm,
        kde=False,
        color=color_all,
        fit_kws={"color": color_all},
        hist_kws={"linewidth": 0, "alpha": 0.5},
        label="all",
    )
    (mu_all, _) = stats.norm.fit(self.tracking_data["alpha"].dropna())
    # Last 10% alphas
    len_last_elements = int(len(self.tracking_data["alpha"]) / 10)
    try:
        sns.distplot(
            self.tracking_data["alpha"][-len_last_elements:].dropna(),
            ax=ax2,
            # norm_hist=True,
            fit=stats.norm,
            kde=False,
            color=color_last,
            fit_kws={"color": color_last},
            hist_kws={"linewidth": 0, "alpha": 0.85},
            label="last 10 %",
        )
        (mu_last, _) = stats.norm.fit(
            self.tracking_data["alpha"][-len_last_elements:].dropna()
        )
    except ValueError:
        mu_last = None

    # Manually beautify the plot:
    # Adding Zone Lines
    ax.axvline(0, ls="-", color="#ababba", linewidth=1.5, zorder=0)
    ax.axvline(-1, ls="-", color="#ababba", linewidth=1.5, zorder=0)
    ax.axvline(1, ls="-", color="#ababba", linewidth=1.5, zorder=0)
    ax.axhline(0, ls="-", color="#ababba", linewidth=1.5, zorder=0)
    ax.axhline(1, ls="-", color="#ababba", linewidth=0.5, zorder=0)
    # Labels
    ax.set_xlabel(r"Local step length $\alpha$")
    ax2.set_ylabel(r"$\alpha$ density")
    # Add indicator for outliers
    if max(self.tracking_data["alpha"][-len_last_elements:]) > plot_args["xlim"][1]:
        ax.annotate(
            "",
            xy=(1.8, 0.3),
            xytext=(1.7, 0.3),
            size=20,
            arrowprops=dict(color=color_last),
        )
    elif max(self.tracking_data["alpha"]) > plot_args["xlim"][1]:
        ax.annotate(
            "",
            xy=(1.8, 0.3),
            xytext=(1.7, 0.3),
            size=20,
            arrowprops=dict(color=color_all),
        )
    if min(self.tracking_data["alpha"][-len_last_elements:]) < plot_args["xlim"][0]:
        ax.annotate(
            "",
            xy=(-1.8, 0.3),
            xytext=(-1.7, 0.3),
            size=20,
            arrowprops=dict(color=color_last),
        )
    elif min(self.tracking_data["alpha"]) < plot_args["xlim"][0]:
        ax.annotate(
            "",
            xy=(-1.8, 0.3),
            xytext=(-1.7, 0.3),
            size=20,
            arrowprops=dict(color=color_all),
        )
    # Legend
    # Get the fitted parameters used by sns
    lines2, labels2 = ax2.get_legend_handles_labels()
    legend = []
    if mu_all is not None:
        legend.append("{0} ($\mu=${1:.2f})".format(labels2[0], mu_all))  # noqa: W605
    if mu_last is not None:
        legend.append("{0} ($\mu=${1:.2f})".format(labels2[1], mu_last))  # noqa: W605
    ax2.legend(legend)
Beispiel #17
0
def alpha_gauge(self, fig, gridspec):
    r"""Showing a distribution of the alpha values.

    This alpha instruments provides a summary of the alpha values of all tracked
    iterations (shown in gray) as well as the last 10% of them (shown in blue).

    The alpha value uses loss and gradient information to build a noise-informed
    univariate quadratic approximation of the loss function to assess to which
    point on this parabola the optimizer moves. The parabola (shown in orange) is
    always normalized such that the starting point of each iteration is at
    :math:`x=-1`. If the optimzer takes a single step to the local minimum (e.g.
    the valley floor) it would be indicated by an :math:`\alpha` value of :math:`0`.
    Analogously, taking a step to the exact opposite side of the valley, will be
    descrbied by :math:`\alpha=1`.

    The instruments shows a histogram and a distribution fit of all alpha values,
    as well as the last 10% of tracked iterations. The mean values of both distributions
    are also shown in the figure's legend.

    For a more detailed explanation of the alpha value and why - perhaps against
    intuition - values larger than zero might be desirable, have a look at the
    Cockpit paper:

    - `Schneider, F., Dangel, F., & Hennig, P.,
      Cockpit: A Practical Debugging Tool for Training Deep Neural Networks (2021).
      <https://arxiv.org/abs/2102.06604>`_

    .. image:: ../../_static/instrument_previews/Alpha.png
        :alt: Preview Alpha Gauge

    **Requires**

    This instrument requires data from the :class:`~cockpit.quantities.Alpha`
    quantity class.

    Args:
        self (CockpitPlotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure.Figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec.GridSpec): GridSpec where the instrument
            should be placed.
    """
    # Plot Alpha Distribution
    title = "Alpha Distribution"

    # Check if the required data is available, else skip this instrument
    requires = ["Alpha"]
    plot_possible = check_data(self.tracking_data, requires, min_elements=2)
    if not plot_possible:
        if self.debug:
            warnings.warn(
                "Couldn't get the required data for the " + title +
                " instrument",
                stacklevel=1,
            )
        return

    plot_args = {
        "xlabel": "Local Step Length",
        "ylabel": "Stand. Loss",
        "title": title,
        "xlim": [-1.5, 1.5],
        "ylim": [0, 1.75],
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments,
        "zero_lines": True,
        "center": [True, False],
    }
    color_all = "gray"
    color_last = self.primary_color
    color_parabola = self.secondary_color

    ax = fig.add_subplot(gridspec)

    # Plot unit parabola
    x = np.linspace(plot_args["xlim"][0], plot_args["xlim"][1], 100)
    y = x**2
    ax.plot(x, y, linewidth=2, color=color_parabola)

    _beautify_plot(**plot_args, ax=ax)

    # Alpha Histogram
    ax2 = ax.twinx()
    # All alphas
    sns.histplot(
        self.tracking_data["Alpha"].dropna(),
        ax=ax2,
        kde=True,
        color=color_all,
        kde_kws={"cut": 10},
        alpha=0.5,
        stat="probability",
        label="all",
    )
    (mu_all, _) = stats.norm.fit(self.tracking_data["Alpha"].dropna())
    # Last 10% alphas
    len_last_elements = int(len(self.tracking_data["Alpha"]) / 10)
    sns.histplot(
        self.tracking_data["Alpha"].dropna().tail(len_last_elements),
        ax=ax2,
        kde=True,
        color=color_last,
        kde_kws={"cut": 10},
        alpha=0.5,
        stat="probability",
        label="last 10 %",
    )
    if len_last_elements == 0:
        mu_last = math.nan
    else:
        (mu_last, _) = stats.norm.fit(
            self.tracking_data["Alpha"].dropna().tail(len_last_elements))

    # Manually beautify the plot:
    # Adding Zone Lines
    ax.axvline(0, ls="-", color="#ababba", linewidth=1.5, zorder=0)
    ax.axvline(-1, ls="-", color="#ababba", linewidth=1.5, zorder=0)
    ax.axvline(1, ls="-", color="#ababba", linewidth=1.5, zorder=0)
    ax.axhline(0, ls="-", color="#ababba", linewidth=1.5, zorder=0)
    ax.axhline(1, ls="-", color="#ababba", linewidth=0.5, zorder=0)
    # Labels
    ax.set_xlabel(r"Local step length $\alpha$")
    ax2.set_ylabel(r"$\alpha$ density")
    _add_indicators(self, ax, mu_last, plot_args, color_all, color_last,
                    len_last_elements)

    # Legend
    # Get the fitted parameters used by sns
    lines2, labels2 = ax2.get_legend_handles_labels()
    for idx, lab in enumerate(labels2):
        if "all" in lab and not math.isnan(mu_all):
            labels2[idx] = lab + " ($\mu=${0:.2f})".format(
                mu_all)  # noqa: W605
        if "last 10 %" in lab and not math.isnan(mu_last):
            labels2[idx] = lab + " ($\mu=${0:.2f})".format(
                mu_last)  # noqa: W605
    ax2.legend(lines2, labels2)
Beispiel #18
0
def tic_gauge(self, fig, gridspec):
    """TIC gauge, showing the TIC versus iteration.

    The TIC (either approximated via traces or using a diagonal approximation)
    describes the relation between the curvature and the gradient noise. `Recent
    work <https://arxiv.org/abs/1906.07774>`_ suggested that *at a local minimum*,
    this quantitiy can estimate the generalization gap. This instrument shows the
    TIC versus iteration, overlayed with an exponentially weighted average.

    **Preview**

    .. image:: ../../_static/instrument_previews/TIC.png
        :alt: Preview TIC Gauge

    **Requires**

    The trace instrument requires data from the :class:`~cockpit.quantities.TICDiag`
    or :class:`~cockpit.quantities.TICTrace` quantity class.

    Args:
        self (CockpitPlotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure.Figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec.GridSpec): GridSpec where the instrument should be
            placed
    """
    # Plot Trace vs iteration
    title = "TIC"

    if check_data(self.tracking_data, ["TICDiag"]):
        plot_args = {
            "x": "iteration",
            "y": "TICDiag",
            "data": self.tracking_data,
            "x_scale": "symlog" if self.show_log_iter else "linear",
            "y_scale": "linear",
            "cmap": self.cmap,
            "EMA": "y",
            "EMA_alpha": self.EMA_alpha,
            "EMA_cmap": self.cmap2,
            "title": title,
            "xlim": "tight",
            "ylim": None,
            "fontweight": "bold",
            "facecolor": self.bg_color_instruments,
        }
        ax = fig.add_subplot(gridspec)
        create_basic_plot(**plot_args, ax=ax)

    if check_data(self.tracking_data, ["TICTrace"]):
        if "ax" in locals():
            ax2 = ax.twinx()
        else:
            ax2 = fig.add_subplot(gridspec)
        plot_args = {
            "x": "iteration",
            "y": "TICTrace",
            "data": self.tracking_data,
            "x_scale": "symlog" if self.show_log_iter else "linear",
            "y_scale": "linear",
            "cmap": self.cmap_backup,
            "EMA": "y",
            "EMA_alpha": self.EMA_alpha,
            "EMA_cmap": self.cmap2_backup,
            "title": title,
            "xlim": "tight",
            "ylim": None,
            "fontweight": "bold",
            "facecolor": self.bg_color_instruments,
        }
        create_basic_plot(**plot_args, ax=ax2)
Beispiel #19
0
def max_ev_gauge(self, fig, gridspec):
    """Showing the largest eigenvalue of the Hessian versus iteration.

    The largest eigenvalue of the Hessian indicates the loss surface's sharpest
    valley. Together with the :func:`~cockpit.instruments.trace_gauge()`, which
    provides a notion of "average curvature", it can help understand the "average
    condition number" of the loss landscape at the current point. The instrument
    shows the largest eigenvalue of the Hessian versus iteration, overlayed with
    an exponentially weighted average.

    **Preview**

    .. image:: ../../_static/instrument_previews/HessMaxEV.png
        :alt: Preview HessMaxEV Gauge

    **Requires**

    The trace instrument requires data from the :class:`~cockpit.quantities.HessMaxEv`
    quantity class.

    Args:
        self (CockpitPlotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure.Figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec.GridSpec): GridSpec where the instrument should be
            placed.
    """
    # Plot Trace vs iteration
    title = "Max Eigenvalue"

    # Check if the required data is available, else skip this instrument
    requires = ["HessMaxEV"]
    plot_possible = check_data(self.tracking_data, requires)
    if not plot_possible:
        if self.debug:
            warnings.warn(
                "Couldn't get the required data for the " + title +
                " instrument",
                stacklevel=1,
            )
        return

    plot_args = {
        "x": "iteration",
        "y": "HessMaxEV",
        "data": self.tracking_data,
        "x_scale": "symlog" if self.show_log_iter else "linear",
        "y_scale": "log",
        "cmap": self.cmap,
        "EMA": "y",
        "EMA_alpha": self.EMA_alpha,
        "EMA_cmap": self.cmap2,
        "title": title,
        "xlim": "tight",
        "ylim": None,
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments,
    }
    # part that should be plotted
    ax = fig.add_subplot(gridspec)
    create_basic_plot(**plot_args, ax=ax)

    ax.yaxis.set_minor_formatter(ticker.FormatStrFormatter("%.2g"))
Beispiel #20
0
def distance_gauge(self, fig, gridspec):
    """Distance gauge showing two different quantities related to distance.

    This instruments shows two quantities at once. Firstly, the :math:`L_2`-distance
    of the current parameters to their initialization. This describes the total distance
    that the optimization trajectory "has traveled so far" and can be seen via the
    blue-to-green dots (and the left y-axis).

    Secondly, the update sizes of individual steps are shown via the yellow-to-blue
    dots (and the right y-axis). It measure the distance that a single parameter
    update covers.

    Both quantities are overlayed with an exponentially weighted average.

    .. image:: ../../_static/instrument_previews/Distances.png
        :alt: Preview Distances Gauge

    **Requires**

    The distance instrument requires data from both, the
    :class:`~cockpit.quantities.UpdateSize` and the
    :class:`~cockpit.quantities.Distance` quantity class.

    Args:
        self (CockpitPlotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure.Figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec.GridSpec): GridSpec where the instrument should be
            placed
    """
    # Plot Trace vs iteration
    title = "Distance"

    # Check if the required data is available, else skip this instrument
    requires = ["Distance", "UpdateSize"]
    plot_possible = check_data(self.tracking_data, requires)
    if not plot_possible:
        if self.debug:
            warnings.warn(
                "Couldn't get the required data for the " + title +
                " instrument",
                stacklevel=1,
            )
        return

    # Compute
    self.tracking_data["Distance_all"] = self.tracking_data.Distance.map(
        lambda x: _root_sum_of_squares(x) if type(x) == list else x)
    self.tracking_data["UpdateSize_all"] = self.tracking_data.UpdateSize.map(
        lambda x: _root_sum_of_squares(x) if type(x) == list else x)

    plot_args = {
        "x": "iteration",
        "y": "Distance_all",
        "data": self.tracking_data,
        "y_scale": "linear",
        "x_scale": "symlog" if self.show_log_iter else "linear",
        "cmap": self.cmap,
        "EMA": "y",
        "EMA_alpha": self.EMA_alpha,
        "EMA_cmap": self.cmap2,
        "title": title,
        "xlim": "tight",
        "ylim": None,
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments,
    }
    ax = fig.add_subplot(gridspec)
    create_basic_plot(**plot_args, ax=ax)

    ax2 = ax.twinx()
    plot_args = {
        "x": "iteration",
        "y": "UpdateSize_all",
        "data": self.tracking_data,
        "y_scale": "linear",
        "x_scale": "symlog" if self.show_log_iter else "linear",
        "cmap": self.cmap.reversed(),
        "EMA": "y",
        "EMA_alpha": self.EMA_alpha,
        "EMA_cmap": self.cmap2.reversed(),
        "xlim": "tight",
        "ylim": None,
        "marker": ",",
    }
    create_basic_plot(**plot_args, ax=ax2)
Beispiel #21
0
def cabs_gauge(self, fig, gridspec):
    """CABS gauge, showing the CABS rule versus iteration.

    The batch size trades-off more accurate gradient approximations with longer
    computation. The `CABS criterion <https://arxiv.org/abs/1612.05086>`_ describes
    the optimal batch size under certain assumptions.

    The instruments shows the suggested batch size (and an exponential weighted
    average) over the course of training, according to

    - `Balles, L., Romero, J., & Hennig, P.,
      Coupling adaptive batch sizes with learning rates (2017).
      <https://arxiv.org/abs/1612.05086>`_

    **Preview**

    .. image:: ../../_static/instrument_previews/CABS.png
        :alt: Preview CABS Gauge

    **Requires**

    This instrument requires data from the :class:`~cockpit.quantities.CABS`
    quantity class.

    Args:
        self (CockpitPlotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure.Figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec.GridSpec): GridSpec where the instrument should be
            placed
    """
    # Plot Trace vs iteration
    title = "CABS"

    # Check if the required data is available, else skip this instrument
    requires = ["CABS"]
    plot_possible = check_data(self.tracking_data, requires)
    if not plot_possible:
        if self.debug:
            warnings.warn(
                "Couldn't get the required data for the " + title + " instrument",
                stacklevel=1,
            )
        return

    plot_args = {
        "x": "iteration",
        "y": "CABS",
        "data": self.tracking_data,
        "x_scale": "symlog" if self.show_log_iter else "linear",
        "y_scale": "linear",
        "cmap": self.cmap,
        "EMA": "y",
        "EMA_alpha": self.EMA_alpha,
        "EMA_cmap": self.cmap2,
        "title": title,
        "xlim": "tight",
        "ylim": None,
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments,
    }
    ax = fig.add_subplot(gridspec)
    create_basic_plot(**plot_args, ax=ax)
Beispiel #22
0
def performance_gauge(self, fig, gridspec):
    """Plotting train/valid accuracy vs. epoch and mini-batch loss vs. iteration.

    Args:
        self (cockpit.plotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec): GridSpec where the instrument should be
            placed
    """
    # Plot Trace vs iteration
    title = "Performance Plot"

    # Check if the required data is available, else skip this instrument
    requires = [
        "iteration", "train_accuracy", "valid_accuracy", "mini_batch_loss"
    ]
    plot_possible = check_data(self.tracking_data, requires)
    if not plot_possible:
        warnings.warn(
            "Couldn't get the required data for the " + title + " instrument",
            stacklevel=1,
        )
        return

    # Mini-batch train loss
    plot_args = {
        "x": "iteration",
        "y": "mini_batch_loss",
        "data": self.tracking_data,
        "EMA": "y",
        "EMA_alpha": self.EMA_alpha,
        "EMA_cmap": self.cmap2,
        "x_scale": "symlog" if self.show_log_iter else "linear",
        "y_scale": "linear",
        "cmap": self.cmap,
        "title": title,
        "xlim": "tight",
        "ylim": None,
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments2,
    }
    ax = fig.add_subplot(gridspec)
    create_basic_plot(**plot_args, ax=ax)

    clean_accuracies = self.tracking_data[[
        "iteration", "train_accuracy", "valid_accuracy"
    ]].dropna()

    # Train Accuracy
    plot_args = {
        "x": "iteration",
        "y": "train_accuracy",
        "data": clean_accuracies,
    }
    ax2 = ax.twinx()
    sns.lineplot(
        **plot_args,
        ax=ax2,
        label=plot_args["y"].title().replace("_", " "),
        linewidth=2,
        color=self.primary_color,
    )

    # Train Accuracy
    plot_args = {
        "x": "iteration",
        "y": "valid_accuracy",
        "data": clean_accuracies,
    }
    sns.lineplot(
        **plot_args,
        ax=ax2,
        label=plot_args["y"].title().replace("_", " "),
        linewidth=2,
        color=self.secondary_color,
    )

    # Customization
    ax2.set_ylim([0, 1])
    ax2.set_ylabel("Accuracy")
    _add_last_value_to_legend(ax2, percentage=True)
def early_stopping_gauge(self, fig, gridspec):
    """Early Stopping gauge, showing the LHS of the stopping criterion versus iteration.

    Early stopping the training has been widely used to prevent poor generalization
    due to over-fitting. `Mahsereci et al. (2017) <https://arxiv.org/abs/1703.09580>`_
    proposed an evidence-based stopping criterion based on mini-batch statistics.
    This instruments visualizes this criterion versus iteration, overlayed
    with an exponentially weighted average. If the stopping criterion becomes
    positive, this suggests stopping the training according to

    - `Mahsereci, M., Balles, L., Lassner, C., & Hennig, P.,
      Early stopping without a validation set (2017).
      <https://arxiv.org/abs/1703.09580>`_

    **Preview**

    .. image:: ../../_static/instrument_previews/EarlyStopping.png
        :alt: Preview EarlyStopping Gauge

    **Requires**

    This instrument requires data from the :class:`~cockpit.quantities.EarlyStopping`
    quantity class.

    Args:
        self (CockpitPlotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure.Figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec.GridSpec): GridSpec where the instrument should be
            placed
    """
    # Plot Trace vs iteration
    title = "Early stopping"

    # Check if the required data is available, else skip this instrument
    requires = ["EarlyStopping"]
    plot_possible = check_data(self.tracking_data, requires)
    if not plot_possible:
        if self.debug:
            warnings.warn(
                "Couldn't get the required data for the " + title +
                " instrument",
                stacklevel=1,
            )
        return

    plot_args = {
        "x": "iteration",
        "y": "EarlyStopping",
        "data": self.tracking_data,
        "x_scale": "symlog" if self.show_log_iter else "linear",
        "y_scale": "linear",
        "cmap": self.cmap,
        "EMA": "y",
        "EMA_alpha": self.EMA_alpha,
        "EMA_cmap": self.cmap2,
        "title": title,
        "xlim": "tight",
        "ylim": None,
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments,
    }
    ax = fig.add_subplot(gridspec)
    create_basic_plot(**plot_args, ax=ax)
Beispiel #24
0
def performance_gauge(self, fig, gridspec):
    """Plotting train/valid accuracy vs. epoch and mini-batch loss vs. iteration.

    This instruments visualizes the currently most popular diagnostic metrics. It
    shows the mini-batch loss in each iteration (overlayed with an exponentially
    weighted average) as well as accuracies for both the training as well as the
    validation set. The current accuracy numbers are also shown in the legend.

    **Preview**

    .. image:: ../../_static/instrument_previews/Performance.png
        :alt: Preview Performance Gauge

    **Requires**

    This instrument visualizes quantities passed via the
    :func:`cockpit.Cockpit.log()` method.

    Args:
        self (CockpitPlotter): The cockpit plotter requesting this instrument.
        fig (matplotlib.figure.Figure): Figure of the Cockpit.
        gridspec (matplotlib.gridspec.GridSpec): GridSpec where the instrument should be
            placed
    """
    # Plot Trace vs iteration
    title = "Performance Plot"

    # Check if the required data is available, else skip this instrument
    requires = ["iteration", "Loss"]
    plot_possible = check_data(self.tracking_data, requires)
    if not plot_possible:
        if self.debug:
            warnings.warn(
                "Couldn't get the loss data for the " + title + " instrument",
                stacklevel=1,
            )
        return

    # Mini-batch train loss
    plot_args = {
        "x": "iteration",
        "y": "Loss",
        "data": self.tracking_data,
        "EMA": "y",
        "EMA_alpha": self.EMA_alpha,
        "EMA_cmap": self.cmap2,
        "x_scale": "symlog" if self.show_log_iter else "linear",
        "y_scale": "linear",
        "cmap": self.cmap,
        "title": title,
        "xlim": "tight",
        "ylim": None,
        "fontweight": "bold",
        "facecolor": self.bg_color_instruments2,
    }
    ax = fig.add_subplot(gridspec)
    create_basic_plot(**plot_args, ax=ax)

    requires = ["iteration", "train_accuracy", "valid_accuracy"]
    plot_possible = check_data(self.tracking_data, requires)
    if not plot_possible:
        if self.debug:
            warnings.warn(
                "Couldn't get the accuracy data for the " + title +
                " instrument",
                stacklevel=1,
            )
        return
    else:
        clean_accuracies = self.tracking_data[[
            "iteration", "train_accuracy", "valid_accuracy"
        ]].dropna()

        # Train Accuracy
        plot_args = {
            "x": "iteration",
            "y": "train_accuracy",
            "data": clean_accuracies,
        }
        ax2 = ax.twinx()
        sns.lineplot(
            **plot_args,
            ax=ax2,
            label=plot_args["y"].title().replace("_", " "),
            linewidth=2,
            color=self.primary_color,
        )

        # Train Accuracy
        plot_args = {
            "x": "iteration",
            "y": "valid_accuracy",
            "data": clean_accuracies,
        }
        sns.lineplot(
            **plot_args,
            ax=ax2,
            label=plot_args["y"].title().replace("_", " "),
            linewidth=2,
            color=self.secondary_color,
        )

        # Customization
        ax2.set_ylim([0, 1])
        ax2.set_ylabel("Accuracy")
        _add_last_value_to_legend(ax2, percentage=True)