Hi All,
I’m having an issue getting started with training a neural network with a custom dataset. My code is included below:
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:>7f} [{current:>5d}/{size:>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):>1f}%, Avg Loss: {test_loss:>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")
The model is defined like so:
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
However, when I run, I get the following output and I cannot work out what to do. So would really appreciate any help:
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 <module>
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 <listcomp>
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 <class 'pandas.core.frame.DataFrame'>
Can anyone help?