Reputation: 1839
I'm attempting to write a simple NN module, with 2 layers, first layer ReLU activation, output softmax with 3 classes (one-hot encoded). It seems theres something wrong with the way I'm using the softmax function, but I'm not sure what's going on.
X is 178x13 Y is 178x3
Dataset I'm using is fairly simple, and can be found here.
I keep getting the error:
RuntimeError: dimension out of range (expected to be in range of [-2, 1], but got 3) .
.
import pandas as pd
import numpy as np
import torch
from torch.autograd import Variable
from sklearn.preprocessing import LabelBinarizer
# Read in dataset, specifying that this set didn't come with column headers
x = pd.read_csv('Datasets/wine.data', header=None)
# Rename columns
x.columns = ['Class', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10', 'A11', 'A12', 'A13']
y = x[['Class']].values
#turn class labels into one-hot encoding
one_hot = LabelBinarizer()
y = Variable(torch.from_numpy(one_hot.fit_transform(y)), )
x = Variable(torch.from_numpy(x.iloc[:, 1:14].values).float())
N, D_in, H, D_out = y.shape[0], x.shape[1], 20, 3
# Implement neural net with nn module
model = torch.nn.Sequential(
torch.nn.Linear(D_in, H),
torch.nn.ReLU(),
torch.nn.Linear(H, D_out),
torch.nn.LogSoftmax(dim=3)
)
loss_fn = torch.nn.NLLLoss
learning_rate = 1e-4
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
for t in range(500):
y_pred = model(x)
loss = loss_fn(y_pred, y)
print("Iteration: %d | Loss: %.3f" % (t, loss))
optimizer.zero_grad()
loss.backward()
optimizer.step()
Upvotes: 2
Views: 4591
Reputation: 1839
This was a problem because for NLLLoss:
The target that this loss expects is a class index (0 to N-1, where N = number of classes)
And I had been trying to give it the one-hot encoded vector. I solved my issue by doing:
loss = loss_fn(y_pred, torch.max(y, 1)[1])
Where torch.max found the maximum values and their respective index.
Upvotes: 1
Reputation: 7691
It looks to me like you have misunderstood the argument dim
of LogSoftmax
. From the documentation,
dim (int) – A dimension along which Softmax will be computed (so every slice along dim will sum to 1).
Now, after you pass your input through your two linear layers, the tensor you get and to which you apply LogSoftmax
has dimensions 178 x 3
. Clearly, dim = 3
is not available as your tensor only has two dimensions. Instead, try dim=1
for summing across columns.
Upvotes: 1