Hi all,
I currently have a set of over 10000 1-D images, each with 3832 pixels. I’d like to create a neural network that will categorize them into one of 136 classes. I have created a CNN model and training loop. I have selected Cross Entropy for my loss, and since my labels are one hot encoded, I put in a function one_hot_ce_loss that turns the one hot encoded labels into a proper input format for CrossEntropyLoss. When I run this, my loss does not decrease. I also calculate accuracy at the end of the code snippet, and that stays at 0%. Any suggestions on what might be going wrong would be appreciated!
class CNN(nn.Module):
def __init__(self):
super().__init__()
self.act1 = nn.ReLU()
self.pool1 = nn.MaxPool1d(kernel_size=5)
self.conv2 = nn.Conv1d(3832, 766, kernel_size=5, stride=1, padding=1)
self.act2 = nn.ReLU()
self.pool2 = nn.MaxPool1d(kernel_size=5)
self.flat = nn.Flatten(0,1)
self.fc3 = nn.Linear(116432, 136)
self.act3 = nn.ReLU()
self.fc4 = nn.Linear(136, 136)
self.act4 = nn.ReLU()
def forward(self, x):
x = self.act1(nn.Conv1d(x.size()[0], 3832, kernel_size=5, stride=1, padding=1)(x))
x = self.pool1(x)
x = self.act2(self.conv2(x))
x = self.pool2(x)
x = self.flat(x)
x = self.act3(self.fc3(x))
x = self.act4(self.fc4(x))
return x
model = CNN()
param = model.parameters()
def one_hot_ce_loss(outputs, targets):
criterion = nn.CrossEntropyLoss()
_, labels = torch.max(targets, dim=0)
return criterion(outputs, labels)
loss_fn = one_hot_ce_loss
optimizer = torch.optim.SGD(param, lr=0.01, momentum=0.9)
device = "cuda" if torch.cuda.is_available() else "cpu"
next(model.parameters()).device
model.to(device)
train_size = int(0.8 * len(full_dataset)) #80% training data
test_size = len(full_dataset) - train_size
trainset, testset = torch.utils.data.random_split(full_dataset, [train_size, test_size])
batch_size = 1024
trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=True)
testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size, shuffle=True)
n_epochs = 500
epoch_count = []
train_loss_values = []
test_loss_values = []
acc_values = []
for epoch in range(n_epochs):
model.train()
for inputs, labels in trainloader:
# forward, backward, and then weight update
y_pred = model(inputs)
loss = loss_fn(y_pred, labels[0])
optimizer.zero_grad()
loss.backward()
optimizer.step()
model.eval()
acc = 0
count = 0
for inputs, labels in testloader:
test_pred = model(inputs)
test_loss = loss_fn(test_pred, labels[0])
acc += (torch.argmax(nn.LogSoftmax(test_pred).dim) == torch.argmax(labels[0])).float()
count += len(labels[0])
acc /= count
if epoch % 10 == 0:
print(f"Epoch: {epoch} | Train loss: {loss} | Test loss: {test_loss}")
print("Epoch %d: model accuracy %.2f%%" % (epoch, acc*100))
train_loss_values.append(loss.detach().numpy())
test_loss_values.append(test_loss.detach().numpy())
epoch_count.append(epoch)
acc_values.append(acc)