Here is the working solution-
train_iterator = torch.utils.data.TensorDataset(x_train, y_train.reshape(-1).long())
train_data = torch.utils.data.DataLoader(train_iterator, batch_size = 64, shuffle = True)

for x, y in train_data:
    break
print(x.shape, y.shape) # will print (64, 1, 100), (64,)

criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters())

epochs = 20
batches = len(train_data)
# number of batches in your dataset (where each batch contains 64 examples from your training data)

for epoch in range(epochs):
    epoch_loss = 0.0
    epoch_accuracy = 0.0
    for features, labels in train_data:
        outputs = model(features)
        loss = criterion(outputs, labels)

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

        epoch_loss += loss.item() # here we are accumulating loss for each training batch.
        epoch_accuracy += (outputs.argmax(1) == labels).float().mean()

    print(f'Epoch: {epoch} -> Loss: {(epoch_loss/batches):.8f}, Accuracy: {(epoch_accuracy/batches):.8f}')
    # dividing epoch_loss by number of batches in our train_data to get mean epoch_loss
    # and printing epoch loss round of to 8 decimals.... same for epoch_accuracy