Hello, I’m starting to use PyTorch and want to implement a simple working example of a binary classification. I have some data that is pre-processed with pandas, then transform the training and testing sets to tensors. I create a class with 2 hidden layers with ReLU activation functions, and then a single output (logit). I define the optimizer to be Adam with the model parameters, and the loss function BCEWithLogitLoss. When I create the instance the parameters are uniformly distributed, but when I do the training process the loss is not decreased, and all model parameters remain the same. There is no missing data on the tensors, and I made sure that with the untrained instance of the network the architecture would give a single output as expected.
I suspect the error comes from the loss.backward() or optimizer.step() steps, here is a sample of the data, and the code
# Define tensors to train the model
x_train_t = torch.tensor(x_train.values, dtype=torch.float)
x_test_t = torch.tensor(x_test.values, dtype=torch.float)
y_train_t = torch.tensor(y_train.values, dtype=torch.float)
y_test_t = torch.tensor(y_test.values, dtype=torch.float)
class NetClassifier(nn.Module):
def __init__(self,hidden1,hidden2):
super(NetClassifier,self).__init__()
self.model = nn.Sequential(
nn.Linear(13,hidden1),
nn.ReLU(),
nn.Linear(hidden1,hidden2),
nn.ReLU(),
nn.Linear(hidden2,1)
)
def forward(self,x):
x = self.model(x)
return x
# Create an instance of the class
net = NetClassifier(50,50)
print(net)
# Create DataSet and DataLoaders to train the neural network
EPOCHS = 5
BATCH_SIZE=32
LEARNING_RATE = 0.01
train_data_set = TensorDataset(x_train_t,y_train_t)
test_data_set = TensorDataset(x_test_t,y_test_t)
train_dataloader = DataLoader(train_data_set,batch_size = BATCH_SIZE)
test_dataloader = DataLoader(test_data_set,batch_size = BATCH_SIZE)
# Define optimizer and loss function
optimizer = optim.Adam(net.parameters(),lr=LEARNING_RATE)
loss_function = nn.BCEWithLogitsLoss()
for epoch in range(EPOCHS):
epoch_loss=0
epoch_acc=0
for xb,yb in train_dataloader:
# Zero gradients for training
optimizer.zero_grad()
# Use current model parameters to predict output
y_pred = net(xb)
# Turn probabilities into prediction
pred = torch.round(torch.sigmoid(torch.flatten(y_pred)))
# Calculate loss, use float type to calculate loss
loss = loss_function(yb,pred)
# Backpropagate
loss.backward()
# Step in the optimizer
optimizer.step()
epoch_loss+=loss.item()
epoch_acc+= (yb == pred).float().mean()
# Print epoch loss
print("Epoch {:>02d} | Loss {:.5f} | Acc {:.3f}".format(epoch,epoch_loss/len(train_dataloader),epoch_acc/len(train_dataloader)))