My binary separating learning algorithm didn't work well

gyumin_park: <p>Hi everyone. I am in struggle as a beginner for machine learning, so any helps will be appreciated.</p>
<p>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)<br>
my goal is building a model that predicts what type of signal has been input. so my model’s brief version goes like this.</p>
<p>[:, 100:500, 100] array → my model → [?, ?, ?, ?, ?]<br>
? is 0 or 1, the binary separating results.</p>
<p>I built a model and tested them, but output is such a mess.</p>
<p>I used DNN and sigmoid to seperate by the posibility distribution.</p>
<p>Could anyone help me? Even ChatGPT isn’t helpful <img src="https://discuss.pytorch.org/images/emoji/apple/frowning.png?v=12" title=":frowning:" class="emoji" alt=":frowning:" loading="lazy" width="20" height="20"></p>
<pre><code>import torch
import torch.nn as nn
 import torch.nn.functional as F
 from torch.utils.data import Dataset, DataLoader, random_split
</code></pre>
<h1><a name="load-data-1" class="anchor" href="#load-data-1"></a>load data</h1>
<pre><code> x_features = np.load('/content/drive/MyDrive/features.npy')
 y_labels = np.load('/content/drive/MyDrive/labels.npy')
</code></pre>
<h1><a name="define-the-custom-dataset-class-2" class="anchor" href="#define-the-custom-dataset-class-2"></a>define the custom dataset class</h1>
<pre><code>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)
</code></pre>
<h1><a name="split-the-dataset-3" class="anchor" href="#split-the-dataset-3"></a>split the dataset</h1>
<pre><code>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)
</code></pre>
<h1><a name="define-the-simple-dnn-model-4" class="anchor" href="#define-the-simple-dnn-model-4"></a>define the simple DNN model</h1>
<pre><code>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)
</code></pre>
<h1><a name="define-the-loss-function-5" class="anchor" href="#define-the-loss-function-5"></a>define the loss function</h1>
<pre><code> criterion_binary = nn.BCELoss()
</code></pre>
<h1><a name="training-loop-6" class="anchor" href="#training-loop-6"></a>training loop</h1>
<pre><code> 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)}")
</code></pre>
<h1><a name="model-testing-and-resulting-7" class="anchor" href="#model-testing-and-resulting-7"></a>model testing and resulting</h1>
<pre><code> 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())
</code></pre>
<h1><a name="printing-the-labels-and-predicted-outputs-8" class="anchor" href="#printing-the-labels-and-predicted-outputs-8"></a>printing the labels and predicted outputs</h1>
<pre><code> 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 &gt; 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))
</code></pre>