Pytorch Multiclass Logistic Regression Type Errors
I'm new to ML and even more naive with Pytorch. Here's the problem. (I've skipped certain parts like the random_split() which seem to work just fine)

I've to predict wine quality (red) which from the dataset is the last column with 6 classes

That's what my dataset looks like

The link to the dataset (winequality-red.csv)

features = df.drop(['quality'], axis = 1)
targets = df.iloc[:, -1] # theres 6 classes

dataset = TensorDataset(torch.Tensor(np.array(features)).float(), torch.Tensor(targets).float())
# here's where I think the error might be, but I might be wrong

batch_size = 8
# Dataloader

train_loader = DataLoader(train_ds, batch_size, shuffle = True)
val_loader = DataLoader(val_ds, batch_size)
test_ds = DataLoader(test_ds, batch_size)

input_size = len(df.columns) - 1
output_size = 6
threshold = .5

class WineModel(nn.Module):

  def __init__(self):
    super().__init__()
    self.linear = nn.Linear(input_size, output_size)

  def forward(self, xb):
    out = self.linear(xb)
    return out

model = WineModel()
n_iters = 2000
num_epochs = n_iters / (len(train_ds) / batch_size)
num_epochs = int(num_epochs)

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=1e-2)

# the part below returns the error on running
iter = 0 
for epoch in range(num_epochs):
  for i, (x, y) in enumerate(train_loader):
    optimizer.zero_grad()
    outputs = model(x)
    loss = criterion(outputs, y)
    loss.backward()
    optimizer.step()


RuntimeError: expected scalar type Long but found Float

Hopefully that is sufficient info

The targets for nn.CrossEntropyLoss are given as the class indices, which are required to be integers, to be precise they need to be of type torch.long, which is equivalent to torch.int64.

You converted the targets to floats, but you should convert them to longs:

dataset = TensorDataset(torch.Tensor(np.array(features)).float(), torch.Tensor(targets).long())


Since the targets are the indices of the classes, they must be in range [0, num_classes - 1]. As you have 6 classes that would be in range [0, 5]. Having a quick look at your data, the quality uses values in range [3, 8]. Even though you have 6 classes, the values cannot be used directly as the classes. If you list the classes as classes = [3, 4, 5, 6, 7, 8], you can see that the first class is 3, classes[0] == 3, up to the last class being classes[5] == 8.

You need to replace the class values with the indices, just like you would for named classes (e.g. if you had the classes dog and cat, dog would be 0 and cat would be 1), but you can avoid having to look them up, since the values are simply shifted by 3, i.e. index = classes[index] - 3. Therefore you can subtract 3 from the entire target tensor:

torch.Tensor(targets).long() - 3

