moment-timeseries-foundation-model / moment

MOMENT: A Family of Open Time-series Foundation Models
https://moment-timeseries-foundation-model.github.io/
MIT License
197 stars 24 forks source link

Multivariate classification training error #18

Open tomer92808888 opened 1 month ago

tomer92808888 commented 1 month ago

Hi, I'm trying to use the following model:

model = MOMENTPipeline.from_pretrained(
    "AutonLab/MOMENT-1-large", 
    model_kwargs={
        'task_name': 'classification',
        'n_channels': 8,
        'num_class': 2
    }
)

And then train it:

import torch
import numpy as np
from tqdm import tqdm
from torch.optim.lr_scheduler import OneCycleLR
from momentfm import MOMENTPipeline
from sklearn.metrics import accuracy_score

# Load the MOMENT model
model = MOMENTPipeline.from_pretrained(
    "AutonLab/MOMENT-1-large", 
    model_kwargs={
        'task_name': 'classification',
        'n_channels': 8,
        'num_class': 2
    }
)

criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)

# Check if MPS is available and set the device accordingly
device = torch.device("mps" if torch.backends.mps.is_available() else "cpu")

cur_epoch = 0
max_epoch = 1

# Move the model to the device
model = model.to(device)

# Enable mixed precision training
scaler = torch.cuda.amp.GradScaler() if device.type == 'cuda' else None

# Create a OneCycleLR scheduler
max_lr = 1e-4
total_steps = len(train_dataloader) * max_epoch
scheduler = OneCycleLR(optimizer, max_lr=max_lr, total_steps=total_steps, pct_start=0.3)

# Gradient clipping value
max_norm = 5.0

while cur_epoch < max_epoch:
    losses = []
    model.train()
    for data, input_mask, labels in tqdm(train_dataloader, total=len(train_dataloader)):
        # Move the data to the device
        data = data.float().to(device)
        input_mask = input_mask.to(device)
        labels = labels.long().to(device)

        with torch.cuda.amp.autocast(enabled=device.type == 'cuda'):
            outputs = model(data, input_mask)

        loss = criterion(outputs, labels)

        if scaler:
            # Scales the loss for mixed precision training
            scaler.scale(loss).backward()
            # Clip gradients
            scaler.unscale_(optimizer)
            torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm)
            scaler.step(optimizer)
            scaler.update()
        else:
            loss.backward()
            torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm)
            optimizer.step()

        optimizer.zero_grad(set_to_none=True)
        losses.append(loss.item())

    losses = np.array(losses)
    average_loss = np.average(losses)
    print(f"Epoch {cur_epoch}: Train loss: {average_loss:.3f}")

    # Step the learning rate scheduler
    scheduler.step()
    cur_epoch += 1

But outputs is a TimeseriesOutputs and the logits are None.

Why they are None? And how can I fix it? I'm trying to use MOMENT classification model on a dataset with 8 channels and a binary label for each file. And we have the mask for each file. The type of data is signals data.

mumiao2000 commented 3 weeks ago

The same problem. And changing 'n_channels': 8, to 'n_channels': 1, might fix this. But it may bring about by-effect.