Define a Model

SleePyPhases uses pyPhasesML’s ModelManager to discover, load, and save models. Models are Python classes stored in a conventional directory layout inside your project.

Directory layout

myproject/
└── models/
    └── SimpleCNN/
        └── SimpleCNN.py   # class name must match directory name

Config keys

Key Type Default Description
modelName str Model class name. Must match the subdirectory and class name
modelPath str Path to the models/ directory (relative or absolute)
inputShape list[int] [samples, channels] passed to the model’s define() method
pretraining.pretrainedModel str Path to a model weights file, to use for evaluation and predict
model dict Specific model configuration options

In project.yaml

modelPath: simplecnn/models
modelName: SimpleCNN
inputShape: [806400, 1]

Writing a model class

Subclass ModelTorchAdapter (for PyTorch) or ModelTFAdapter (for TensorFlow):

# simplecnn/models/SimpleCNN/SimpleCNN.py

import torch.nn as nn
from pyPhasesML.adapter.ModelTorchAdapter import ModelTorchAdapter

class SimpleCNNTorch(nn.Module):
    def __init__(self, num_classes=5, num_channels=1, output_steps=840):
        super().__init__()
        self.cnn_layers = nn.Sequential(
            nn.Conv1d(num_channels, 32, kernel_size=7, stride=1, padding=3),
            nn.ReLU(),
            nn.Conv1d(32, 32, kernel_size=5, stride=1, padding=2),
            nn.ReLU(),
            nn.Conv1d(32, 64, kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.AdaptiveAvgPool1d(output_steps),
        )
        self.classifier = nn.Conv1d(64, num_classes, kernel_size=1)

    def forward(self, x):
        features = self.cnn_layers(x)
        logits = self.classifier(features)
        return logits.transpose(1, 2)   # → (batch, steps, classes)


class SimpleCNN(ModelTorchAdapter):
    def define(self):
        """Called once at model creation. self.inputShape is set from config."""
        options = self.options # all config keys under `model` in the YAML are available here
        self.model = SimpleCNNTorch(
            num_classes=5,
            num_channels=self.inputShape[1],
            output_steps=840,
        )

    def prepareY(self, y, validation=False):
        y = super().prepareY(y, validation)
        return y.long().squeeze(2)

    def getLossFunction(self):
        return nn.CrossEntropyLoss(ignore_index=self.ignoreClassIndex)

    def mapOutputForLoss(self, output):
        return output.permute(0, 2, 1)

    def prepareForScore(self, targets, prediction):
        return targets, prediction

Key methods to override

Method Purpose
define() Build model architecture, assign to self.model
prepareX(x) Reshape/cast input for model forward pass
prepareY(y) Reshape/cast ground truth for loss function
getLossFunction() Return loss function instance
mapOutputForLoss(output) Reshape model output to match loss expectations
prepareForScore(targets, pred) Reshape for metric computation

ModelManager

ModelManager is a static class that handles model lifecycle. It is used by the Training, Eval and Predict phase to load the model before training and save weights after each epoch.

from pyPhasesML import ModelManager

model = ModelManager.getModel() # load model defined by the config keys

ModelManager.validate(config) checks that required keys (modelName, modelPath, etc.) are present and raises an error with a clear message if they are missing.

The Training phase calls model.loadWeights(path) before the training loop begins.

Advanded use cases

The model has direct access to the training process, which allows the user defined model to intervene in the training loop. For example, you can implement custom validation logic by overriding the validate() method:

Method Purpose
validate(validationData: DataSet) where validation data is scored, should call self.trigger("validationEnd", self, scorer.results, scorer)
train(dataset: TrainingSetLoader) complete training rund, where dataset contains training and validation data
Note

WIP: more details and examples to come.

Next step

Train — configure and run the training loop