Getting Started with Custom Neural Network, Help Needed

Mhtsf: <p>Hi All,</p>
<p>I’m having an issue getting started with training a neural network with a custom dataset. My code is included below:</p>
<pre><code class="lang-auto">import torch
from torch import nn
from torch.utils.data import Dataset, DataLoader, random_split
import os
import pandas as pd
from NNModel import NeuralNetwork

# Define Custom Dataset to contain all the training data
class CustomDataLoader(Dataset):
    def __init__(self, annotations_file, data_dir):
        self.labels = pd.read_csv(annotations_file)
        self.data_dir = data_dir

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

    def __getitem__(self, idx):
        data_path = os.path.join(self.data_dir, self.labels.iloc[idx,0])
        data = pd.read_csv(data_path)
        mu = self.labels.iloc[idx,1]
        sigma = self.labels.iloc[idx,2]
        return data, mu, sigma

# Parameters for taking a random sample of the data for validation
dataset = CustomDataLoader("data/labels.csv", "data")
batch_size = 100
validation_split = 0.25
random_seed = 42

# Split data into Training data and Validation data
train_set, valid_set = random_split(dataset, [1 - validation_split, validation_split], generator=torch.Generator().manual_seed(random_seed))

# Ensure GPU is available
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Device being utilized: {device}")

# Load DataLoaders
train_loader = DataLoader(train_set.dataset, batch_size=batch_size, shuffle=True, pin_memory_device=device, pin_memory=True)
valid_loader = DataLoader(valid_set.dataset, batch_size=batch_size, shuffle=True, pin_memory_device=device, pin_memory=True)

# Create NN model to train
model = NeuralNetwork().to(device)
print(f"{model}\n")

# Define model loss function and optimizer
loss_fn = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)

# Define the training method for the NN
def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)
    model.train()
    for batch, (X, mu, sigma) in enumerate(dataloader):
        X, mu, sigma = X.to(device), mu.to(device), sigma.to(device)

        # Compute prediction error
        pred = model(X)
        target = torch.column_stack((mu,sigma)).to(torch.float32).to(device)
        loss = loss_fn(pred, target)

        # Backpropagation
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if batch % 10 == 0:
            loss, current = loss.item(), batch * len(X)
            print(f"loss: {loss:&gt;7f} [{current:&gt;5d}/{size:&gt;5d}]")

# Define the testing methodfor the NN
def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    model.eval()
    test_loss, correct = 0, 0
    with torch.no_grad():
        for X, mu, sigma in dataloader:
            X, mu, sigma = X.to(device), mu.to(device), sigma.to(device)
            pred = model(X)
            target = torch.column_stack((mu,sigma)).to(torch.float32).to(device)
            test_loss += loss_fn(pred, target).item()
            correct += (pred == target).sum().item()
    test_loss /= num_batches
    correct /= size
    print(f"Test Error: \n Accuracy: {(100*correct):&gt;1f}%, Avg Loss: {test_loss:&gt;8f} \n")

if __name__ == '__main__':
    # Train the Model
    epochs = 5
    for t in range(epochs):
        print(f"Epoch {t+1}\n----------------------------------------")
        train(train_loader, model, loss_fn, optimizer)
        test(valid_loader, model, loss_fn)
    print("Done!")

    torch.save(model.state_dict(), "model.pth")
    print("Saved PyTorch Model State to model.pth")
</code></pre>
<p>The model is defined like so:</p>
<pre><code class="lang-auto">import torch
from torch import nn

class NeuralNetwork(nn.Module):
    def __init__(self):
        super().__init__()
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(2400, 1200),
            nn.ReLU(),
            nn.Linear(1200, 600),
            nn.ReLU(),
            nn.Linear(600, 300),
            nn.ReLU(),
            nn.Linear(300, 150),
            nn.ReLU(),
            nn.Linear(150, 75),
            nn.ReLU(),
            nn.Linear(75, 38),
            nn.ReLU(),
            nn.Linear(38, 19),
            nn.ReLU(),
            nn.Linear(19, 10),
            nn.ReLU(),
            nn.Linear(10, 5),
            nn.ReLU(),
            nn.Linear(5,2)
        )

    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits
</code></pre>
<p>However, when I run, I get the following output and I cannot work out what to do. So would really appreciate any help:</p>
<pre><code class="lang-auto">Device being utilized: cuda
NeuralNetwork(
  (flatten): Flatten(start_dim=1, end_dim=-1)
  (linear_relu_stack): Sequential(
    (0): Linear(in_features=2400, out_features=1200, bias=True)
    (1): ReLU()
    (2): Linear(in_features=1200, out_features=600, bias=True)
    (3): ReLU()
    (4): Linear(in_features=600, out_features=300, bias=True)
    (5): ReLU()
    (6): Linear(in_features=300, out_features=150, bias=True)
    (7): ReLU()
    (8): Linear(in_features=150, out_features=75, bias=True)
    (9): ReLU()
    (10): Linear(in_features=75, out_features=38, bias=True)
    (11): ReLU()
    (12): Linear(in_features=38, out_features=19, bias=True)
    (13): ReLU()
    (14): Linear(in_features=19, out_features=10, bias=True)
    (15): ReLU()
    (16): Linear(in_features=10, out_features=5, bias=True)
    (17): ReLU()
    (18): Linear(in_features=5, out_features=2, bias=True)
  )
)

Epoch 1
----------------------------------------
Traceback (most recent call last):
  File ".\NNTrain.py", line 92, in &lt;module&gt;
    train(train_loader, model, loss_fn, optimizer)
  File ".\NNTrain.py", line 53, in train
    for batch, (X, mu, sigma) in enumerate(dataloader):
  File ".\AppData\Roaming\Python\Python310\site-packages\torch\utils\data\dataloader.py", line 628, in __next__
    data = self._next_data()
  File ".\AppData\Roaming\Python\Python310\site-packages\torch\utils\data\dataloader.py", line 671, in _next_data
    data = self._dataset_fetcher.fetch(index)  # may raise StopIteration
  File ".\AppData\Roaming\Python\Python310\site-packages\torch\utils\data\_utils\fetch.py", line 61, in fetch
    return self.collate_fn(data)
  File ".\AppData\Roaming\Python\Python310\site-packages\torch\utils\data\_utils\collate.py", line 265, in default_collate
    return collate(batch, collate_fn_map=default_collate_fn_map)
  File ".\AppData\Roaming\Python\Python310\site-packages\torch\utils\data\_utils\collate.py", line 143, in collate
    return [collate(samples, collate_fn_map=collate_fn_map) for samples in transposed]  # Backwards compatibility.
  File ".\AppData\Roaming\Python\Python310\site-packages\torch\utils\data\_utils\collate.py", line 143, in &lt;listcomp&gt;
    return [collate(samples, collate_fn_map=collate_fn_map) for samples in transposed]  # Backwards compatibility.
  File ".\AppData\Roaming\Python\Python310\site-packages\torch\utils\data\_utils\collate.py", line 151, in collate
    raise TypeError(default_collate_err_msg_format.format(elem_type))
TypeError: default_collate: batch must contain tensors, numpy arrays, numbers, dicts or lists; found &lt;class 'pandas.core.frame.DataFrame'&gt;
</code></pre>
<p>Can anyone help?</p>

J_Johnson: <p>Your dataloader is giving Pandas objects out. Need to convert them to Numpy or Torch tensors before sending to the model.</p>

Mdhvince: <p>Hello,</p>
<p>Could you try returning tensors instead in <code>CustomDataloader</code> class ?</p>
<pre><code class="lang-python">def __getitem__(self, idx):
        data_path = os.path.join(self.data_dir, self.labels.iloc[idx,0])
        data = pd.read_csv(data_path)
        mu = self.labels.iloc[idx,1]
        sigma = self.labels.iloc[idx,2]
        return torch.from_numpy(data.values).float(), torch.from_numpy(mu.values).float(), torch.from_numpy(sigma.values).float() 
</code></pre>
<p>Medhy</p>

Mhtsf: <p>Thanks so much for your help! This has resolved the current issue.<br>
Now just have to work out a better way of quantifying the “correctness” of the prediction.</p>

Mhtsf: <p>I have now been able to train my model. I am now attempting to use the model to make predictions, however, once I pass the data tensor to the model:</p>
<pre><code class="lang-auto">import torch
from NNModel import NeuralNetwork
import numpy as np
from numpy import genfromtxt

model = NeuralNetwork()
model.load_state_dict(torch.load("model_100Epoch.pth"))

print(model)

data_path = "5.csv"
g = genfromtxt(data_path, delimiter=',')
g = g[:,1]
window_size = 10
window = np.divide(np.ones(window_size), window_size)
g_s = np.convolve(g, window, mode='valid')
g_s = np.multiply(g_s, -1)
g_s = np.divide(np.subtract(g_s, np.min(g_s)), np.max(g_s))
idx = np.argmax(g_s)
g_c = torch.from_numpy(g_s[(idx - 1200):(idx + 1200)]).to(torch.float32)

model.eval()
results = model(g_c)
</code></pre>
<p>I get the following error:</p>
<pre><code class="lang-auto">NeuralNetwork(
  (flatten): Flatten(start_dim=1, end_dim=-1)
  (tanhshrink_stack): Sequential(
    (0): Linear(in_features=2400, out_features=1200, bias=True)
    (1): Linear(in_features=1200, out_features=600, bias=True)
    (2): Linear(in_features=600, out_features=300, bias=True)
    (3): Linear(in_features=300, out_features=150, bias=True)
    (4): Linear(in_features=150, out_features=75, bias=True)
    (5): Linear(in_features=75, out_features=38, bias=True)
    (6): Linear(in_features=38, out_features=19, bias=True)
    (7): Linear(in_features=19, out_features=10, bias=True)
    (8): Linear(in_features=10, out_features=5, bias=True)
    (9): Linear(in_features=5, out_features=2, bias=True)
  )
)
Traceback (most recent call last):
  File ".\Measure.py", line 23, in &lt;module&gt;
    results = model(g_c)
  .\AppData\Roaming\Python\Python310\site-packages\torch\nn\modules\module.py", line 1190, in _call_impl
    return forward_call(*input, **kwargs)
  File ".\NNModel.py", line 22, in forward
    x = self.flatten(x)
  .\AppData\Roaming\Python\Python310\site-packages\torch\nn\modules\module.py", line 1190, in _call_impl
    return forward_call(*input, **kwargs)
  .\AppData\Roaming\Python\Python310\site-packages\torch\nn\modules\flatten.py", line 46, in forward
    return input.flatten(self.start_dim, self.end_dim)
IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1)
</code></pre>
<p>What does this error mean? Am I passing the data to the model incorrectly?</p>