From 81765d45aaca37ac9c02d834ccb91b52fe1dd43c Mon Sep 17 00:00:00 2001 From: Namratha Urs Date: Mon, 8 Sep 2025 15:44:21 +0000 Subject: [PATCH 1/3] initial round of development for loss curves --- src/deepdiagnostics/plots/lossPlot.py | 56 +++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/deepdiagnostics/plots/lossPlot.py diff --git a/src/deepdiagnostics/plots/lossPlot.py b/src/deepdiagnostics/plots/lossPlot.py new file mode 100644 index 0000000..fd949d6 --- /dev/null +++ b/src/deepdiagnostics/plots/lossPlot.py @@ -0,0 +1,56 @@ +import matplotlib.pyplot as plt +from typing import Dict, List + +from deepdiagnostics.plots.plot import Display + +class LossPlot(Display): + def __init__(self, model=None, data=None): + ... + + def _data_setup(self): + raise NotImplementedError + + def plot_name(self): + return "loss_curves.png" + + def plot( + self, + training_history: Dict[str, List[float]], + epochs: int = None, + best_val_loss: float = None + ): + + try: + training_loss_data = training_history["train_loss"] + validation_loss_data = training_history["val_loss"] + except Exception as e: + raise KeyError(f"Key {e} not found in supplied training history") + + if epochs is None: + if len(training_loss_data) != len(validation_loss_data): + raise ValueError("Inconsistent training history data supplied [length of train and validation losses not equal]") + epochs = len(training_loss_data) + print(f"Number of epochs determined: {epochs}") + else: + if epochs != len(training_loss_data) or epochs != len(validation_loss_data): + raise ValueError("Epochs supplied inconsistent with training history data [epochs and loss history not equal]") + + if best_val_loss is None: + best_val_loss = min(validation_loss_data) + print(f"Best validation loss found: {best_val_loss}") + + epochs_trained = [ x for x in range(1, epochs+1) ] + plt.plot(epochs_trained, training_loss_data, label='Training Loss') + plt.plot(epochs_trained, validation_loss_data, label='Validation Loss') + plt.axhline(y=best_val_loss, color='m', linestyle='--', label="Best Val. Loss") + + plt.xlabel('Epochs') + plt.ylabel('Loss') + plt.title('Training and Validation Loss Over Epochs') + + plt.legend() + plt.grid() + plt.show() + + def __call__(self, **kwargs): + raise NotImplementedError("Plotting loss is not supported in pipeline mode") From ce2e32939274f0a22c140f946207b1af37d1f942 Mon Sep 17 00:00:00 2001 From: Namratha Urs Date: Mon, 8 Sep 2025 10:49:45 -0500 Subject: [PATCH 2/3] fix mismatched indentation --- src/deepdiagnostics/plots/lossPlot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deepdiagnostics/plots/lossPlot.py b/src/deepdiagnostics/plots/lossPlot.py index fd949d6..4c00910 100644 --- a/src/deepdiagnostics/plots/lossPlot.py +++ b/src/deepdiagnostics/plots/lossPlot.py @@ -52,5 +52,5 @@ def plot( plt.grid() plt.show() - def __call__(self, **kwargs): + def __call__(self, **kwargs): raise NotImplementedError("Plotting loss is not supported in pipeline mode") From dcc31b7ecb5355a7d4faea102e308ccb8c984b2c Mon Sep 17 00:00:00 2001 From: Namratha Urs Date: Mon, 8 Sep 2025 15:55:23 +0000 Subject: [PATCH 3/3] fixing inconsistent indentation --- src/deepdiagnostics/plots/lossPlot.py | 71 +++++++++++++-------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/src/deepdiagnostics/plots/lossPlot.py b/src/deepdiagnostics/plots/lossPlot.py index 4c00910..0974de1 100644 --- a/src/deepdiagnostics/plots/lossPlot.py +++ b/src/deepdiagnostics/plots/lossPlot.py @@ -5,13 +5,13 @@ class LossPlot(Display): def __init__(self, model=None, data=None): - ... + ... - def _data_setup(self): - raise NotImplementedError + def _data_setup(self): + raise NotImplementedError def plot_name(self): - return "loss_curves.png" + return "loss_curves.png" def plot( self, @@ -19,38 +19,37 @@ def plot( epochs: int = None, best_val_loss: float = None ): - - try: - training_loss_data = training_history["train_loss"] - validation_loss_data = training_history["val_loss"] - except Exception as e: + try: + training_loss_data = training_history["train_loss"] + validation_loss_data = training_history["val_loss"] + except Exception as e: raise KeyError(f"Key {e} not found in supplied training history") - if epochs is None: - if len(training_loss_data) != len(validation_loss_data): - raise ValueError("Inconsistent training history data supplied [length of train and validation losses not equal]") - epochs = len(training_loss_data) - print(f"Number of epochs determined: {epochs}") - else: - if epochs != len(training_loss_data) or epochs != len(validation_loss_data): - raise ValueError("Epochs supplied inconsistent with training history data [epochs and loss history not equal]") + if epochs is None: + if len(training_loss_data) != len(validation_loss_data): + raise ValueError("Inconsistent training history data supplied [length of train and validation losses not equal]") + epochs = len(training_loss_data) + print(f"Number of epochs determined: {epochs}") + else: + if epochs != len(training_loss_data) or epochs != len(validation_loss_data): + raise ValueError("Epochs supplied inconsistent with training history data [epochs and loss history not equal]") - if best_val_loss is None: - best_val_loss = min(validation_loss_data) - print(f"Best validation loss found: {best_val_loss}") - - epochs_trained = [ x for x in range(1, epochs+1) ] - plt.plot(epochs_trained, training_loss_data, label='Training Loss') - plt.plot(epochs_trained, validation_loss_data, label='Validation Loss') - plt.axhline(y=best_val_loss, color='m', linestyle='--', label="Best Val. Loss") - - plt.xlabel('Epochs') - plt.ylabel('Loss') - plt.title('Training and Validation Loss Over Epochs') - - plt.legend() - plt.grid() - plt.show() - - def __call__(self, **kwargs): - raise NotImplementedError("Plotting loss is not supported in pipeline mode") + if best_val_loss is None: + best_val_loss = min(validation_loss_data) + print(f"Best validation loss found: {best_val_loss}") + + epochs_trained = [ x for x in range(1, epochs+1) ] + plt.plot(epochs_trained, training_loss_data, label='Training Loss') + plt.plot(epochs_trained, validation_loss_data, label='Validation Loss') + plt.axhline(y=best_val_loss, color='m', linestyle='--', label="Best Val. Loss") + + plt.xlabel('Epochs') + plt.ylabel('Loss') + plt.title('Training and Validation Loss Over Epochs') + + plt.legend() + plt.grid() + plt.show() + + def __call__(self, **kwargs): + raise NotImplementedError("Plotting loss is not supported in pipeline mode")