Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "deepaudio-x"
version = "0.4.5"
version = "0.4.6"
description = "DeepAudio-X: Self-supervised audio toolkit for audio classification and beyond."
authors = [
{ name = "Christos Nikou", email = "chrisnick92@gmail.com" },
Expand Down
2 changes: 1 addition & 1 deletion src/deepaudiox/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
This page provides the core API reference for DeepAudioX.
"""

__version__ = "0.4.5"
__version__ = "0.4.6"

from deepaudiox.datasets.audio_classification_dataset import ( # noqa: F401
AudioClassificationDataset,
Expand Down
3 changes: 3 additions & 0 deletions src/deepaudiox/callbacks/early_stopper.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,7 @@ def on_epoch_end(self, trainer):
trainer.state.early_stop = True
self.logger.info("[EARLY STOPPING] Patience exceeded, early stoping ...")

# Update current patience in trainer's state
trainer.state.current_patience = self.elapsed_epochs

return
4 changes: 2 additions & 2 deletions src/deepaudiox/loops/evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def __init__(
class_mapping: dict,
batch_size: int = 16,
num_workers: int = 4,
device: DeviceName = "cuda",
device: DeviceName = "cpu",
device_index: int | None = None,
verbose: bool = True,
):
Expand All @@ -64,7 +64,7 @@ def __init__(
batch_size (int, optional): The batch size for Python Data Loaders. Defaults to 16.
num_workers (int, optional): The number of workers for Python Data Loaders. Defaults to 4.
device (DeviceName): The device to use for evaluation. One of ``"cuda"``, ``"mps"``, or ``"cpu"``.
Defaults to ``"cuda"``.
Defaults to ``"cpu"``.
device_index (int | None): The GPU device index. Only applicable when ``device="cuda"``.
If ``None``, uses the default CUDA device.
verbose (bool): If True, prints the classification report, confusion matrix, and average
Expand Down
20 changes: 11 additions & 9 deletions src/deepaudiox/loops/trainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from torch.utils.data import DataLoader
from tqdm import tqdm

from deepaudiox.callbacks.base_callback import BaseCallback
from deepaudiox.callbacks.checkpointer import Checkpointer
from deepaudiox.callbacks.early_stopper import EarlyStopper
from deepaudiox.datasets.audio_classification_dataset import AudioClassificationDataset
Expand All @@ -35,6 +36,7 @@ class State:
train_loss: list[float] = field(default_factory=list)
validation_loss: list[float] = field(default_factory=list)
early_stop: bool = False
current_patience: int = 0


class Trainer:
Expand Down Expand Up @@ -70,11 +72,11 @@ def __init__(
loss_function: nn.Module | None = None,
train_ratio: float = 0.8,
epochs: int = 100,
patience: int = 15,
patience: int | None = None,
num_workers: int = 4,
batch_size: int = 16,
path_to_checkpoint: str = "checkpoint.pt",
device: DeviceName = "cuda",
device: DeviceName = "cpu",
device_index: int | None = None,
verbose: bool = True,
):
Expand All @@ -91,12 +93,12 @@ def __init__(
loss_function (nn.Module | None): The loss function used for training. Uses CrossEntropy if None.
train_ratio (float, optional): The ratio of the train split when validation_dset is None. Defaults to 0.8.
epochs (int, optional): The maximum number of training epochs. Defaults to 100.
patience (int, optional): The maximum number of epochs with no decrease in loss. Defaults to 15.
patience (int | None): Epochs to wait without loss improvement before stopping. Disabled if None.
num_workers (int, optional): The number of workers for Python Data Loaders. Defaults to 4.
batch_size (int, optional): The batch size for Python Data Loaders. Defaults to 16.
path_to_checkpoint (str, optional): The path to the saved model checpoint. Defaults to "checkpoint.pt".
device (DeviceName): The device to use for training. One of ``"cuda"``, ``"mps"``, or ``"cpu"``.
Defaults to ``"cuda"``.
Defaults to ``"cpu"``.
device_index (int | None): The GPU device index. Only applicable when ``device="cuda"``.
If ``None``, uses the default CUDA device.
verbose (bool): If True, logs epoch-level artifacts (loss, time). If False, only
Expand Down Expand Up @@ -141,11 +143,11 @@ def __init__(
self.scheduler = lr_scheduler or ReduceLROnPlateau(self.optimizer, "min")
self.loss_function = loss_function or nn.CrossEntropyLoss()

# Configure callbacks
self.callbacks = [
Checkpointer(path_to_checkpoint=path_to_checkpoint, logger=self.logger),
EarlyStopper(patience=patience, logger=self.logger),
]
# Configure callbacks — Checkpointer must precede EarlyStopper (updates lowest_loss first)
self.callbacks: list[BaseCallback] = [Checkpointer(path_to_checkpoint=path_to_checkpoint, logger=self.logger)]
if patience:
self.callbacks.append(EarlyStopper(patience=patience, logger=self.logger))

self._epoch_start_time: float = 0.0

def train_step(self) -> float:
Expand Down
10 changes: 5 additions & 5 deletions src/deepaudiox/utils/training_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ def get_class_mapping_from_dir(root_dir: str) -> dict[str, int]:
return class_mapping


def get_device(device: DeviceName = "cuda", device_index: int | None = None) -> torch.device:
def get_device(device: DeviceName = "cpu", device_index: int | None = None) -> torch.device:
"""Returns a PyTorch device based on the user's choice.

Args:
device (DeviceName): The device to use. One of ``"cuda"``, ``"mps"``, or ``"cpu"``.
Defaults to ``"cuda"``.
Defaults to ``"cpu"``.
device_index (int | None): The GPU device index. Only applicable when ``device="cuda"``.
If ``None``, uses the default CUDA device.

Expand All @@ -102,7 +102,7 @@ def get_device(device: DeviceName = "cuda", device_index: int | None = None) ->
"""
if device == "cuda":
if not torch.cuda.is_available():
raise ValueError("CUDA is not available on this machine.")
raise ValueError("CUDA is not available on this machine. Use device='cpu' or device='mps' instead.")
if device_index is not None and (device_index < 0 or device_index >= torch.cuda.device_count()):
raise ValueError(f"Invalid device_index {device_index}. Available GPU count: {torch.cuda.device_count()}")
if device_index is not None:
Expand All @@ -113,7 +113,7 @@ def get_device(device: DeviceName = "cuda", device_index: int | None = None) ->
print(f"Using GPU: {torch.cuda.get_device_name(0)}")
elif device == "mps":
if not torch.backends.mps.is_available():
raise ValueError("MPS is not available on this machine.")
raise ValueError("MPS is not available on this machine. Use device='cpu' instead.")
if device_index is not None:
raise ValueError("device_index is not supported for MPS. Apple Silicon has a single GPU.")
torch_device = torch.device("mps")
Expand All @@ -122,7 +122,7 @@ def get_device(device: DeviceName = "cuda", device_index: int | None = None) ->
if device_index is not None:
print("Warning: device_index is ignored when device='cpu'.")
torch_device = torch.device("cpu")
print("Using CPU")
print("Using CPU.")

return torch_device

Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading