My binary separating learning algorithm didn't work well

Hi everyone. I am in struggle as a beginner for machine learning, so any helps will be appreciated.

I feature is [1000, 500, 100] array that is about neural spiking network. (actually [:, :100, :] is input layer, so i will delete them during training)
my goal is building a model that predicts what type of signal has been input. so my model’s brief version goes like this.

[:, 100:500, 100] array → my model → [?, ?, ?, ?, ?]
? is 0 or 1, the binary separating results.

I built a model and tested them, but output is such a mess.

I used DNN and sigmoid to seperate by the posibility distribution.

Could anyone help me? Even ChatGPT isn’t helpful :frowning:

import torch
import torch.nn as nn
 import torch.nn.functional as F
 from torch.utils.data import Dataset, DataLoader, random_split

load data

 x_features = np.load('/content/drive/MyDrive/features.npy')
 y_labels = np.load('/content/drive/MyDrive/labels.npy')

define the custom dataset class

class SpikeDataset(Dataset):

    def __init__(self, features, labels):
         self.features = torch.tensor(features[:, 100:500, :], dtype=torch.float32)
         self.binary_labels = self.process_labels(labels)

    def process_labels(self, labels):
        binary_labels = []
        for label in labels:
            binary_labels.append([0 if x == 'none' else 1 for x in label])
        return binary_labels

    def __len__(self):
        return len(self.features)

    def __getitem__(self, idx):
        features = self.features[idx]
        binary_labels = self.binary_labels[idx]
        return features, torch.tensor(binary_labels, dtype=torch.float32)

split the dataset

dataset = SpikeDataset(x_features, y_labels)
train_size = int(0.7 * len(dataset)) 
val_size = int(0.1 * len(dataset))
test_size = len(dataset) - train_size - val_size

train_dataset, val_dataset, test_dataset = random_split(dataset, [train_size, val_size, test_size])

train_dataloader = DataLoader(train_dataset, batch_size=32, shuffle=True)
val_dataloader = DataLoader(val_dataset, batch_size=32, shuffle=False)
test_dataloader = DataLoader(test_dataset, batch_size=32, shuffle=False)

define the simple DNN model

class SimpleBinarySpikeNet(nn.Module):
    def __init__(self):
        super(SimpleBinarySpikeNet, self).__init__()
        self.fc1 = nn.Linear(40000, 64)
        self.fc2 = nn.Linear(64, 32)
        self.fc3_binary = nn.Linear(32, 5)

     def forward(self, x):
         x = x.view(x.size(0), -1)
         x = F.relu(self.fc1(x))
         x = F.relu(self.fc2(x))
         binary_out = torch.sigmoid(self.fc3_binary(x))
         return binary_out

 model = SimpleBinarySpikeNet()
 optimizer = torch.optim.Adam(model.parameters(), lr=0.1, weight_decay = 0.001)

define the loss function

 criterion_binary = nn.BCELoss()

training loop

 num_epochs = 10
 for epoch in range(num_epochs):
     model.train()
     running_loss = 0.0
     for features, binary_labels in train_dataloader:
         optimizer.zero_grad()
         binary_out = model(features)
         loss = criterion_binary(binary_out, binary_labels)
         loss.backward()
         optimizer.step()
         running_loss += loss.item()

     val_loss = 0.0
     model.eval()
     with torch.no_grad():
         for features, binary_labels in val_dataloader:
             binary_out = model(features)
             loss = criterion_binary(binary_out, binary_labels)
             val_loss += loss.item()
     print(f"Epoch {epoch+1}/{num_epochs}, Train Loss: {running_loss/len(train_dataloader)}, Val Loss: {val_loss/len(val_dataloader)}")

model testing and resulting

 model.eval()
 all_preds_binary = []
 all_labels_binary = []

 with torch.no_grad():
     for features, binary_labels in test_dataloader:
         binary_out = model(features)
         all_preds_binary.extend(torch.sigmoid(binary_out).cpu().numpy())
         all_labels_binary.extend(binary_labels.cpu().numpy())

printing the labels and predicted outputs

 all_preds_binary = np.array(all_preds_binary)
 all_labels_binary = np.array(all_labels_binary)

 results_binary = pd.DataFrame({
     'Predicted Binary': [list(map(int, pred > 0.5)) for pred in all_preds_binary],
     'Actual Binary': [list(map(int, label)) for label in all_labels_binary]
 })

 print(results_binary.head(10))