Reputation: 97
i am newbie in pytorch and deep learning
my data set 53502 x 58,
i have problem this my code
model = nn.Sequential(
nn.Linear(58,64),
nn.ReLU(),
nn.Linear(64,32),
nn.ReLU(),
nn.Linear(32,16),
nn.ReLU(),
nn.Linear(16,2),
nn.LogSoftmax(1)
)
criterion = nn.NLLLoss()
optimizer = optim.AdamW(model.parameters(), lr = 0.0001)
epoch = 500
train_cost, test_cost = [], []
for i in range(epoch):
model.train()
cost = 0
for feature, target in trainloader:
output = model(feature) #feedforward
loss = criterion(output, target) #loss
loss.backward() #backprop
optimizer.step() #update weight
optimizer.zero_grad() #zero grad
cost += loss.item() * feature.shape[0]
train_cost.append(cost / len(train_set))
with torch.no_grad():
model.eval()
cost = 0
for feature, target in testloader:
output = model(feature) #feedforward
loss = criterion(output, target) #loss
cost += loss.item() * feature.shape
test_cost.append(cost / len(test_set))
print(f'\repoch {i+1}/{epoch} | train_cost: {train_cost[-1]} | test_cost : {test_cost[-1]}', end = "")
and then i get problem like this
2262 .format(input.size(0), target.size(0)))
2263 if dim == 2:
-> 2264 ret = torch._C._nn.nll_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index)
2265 elif dim == 4:
2266 ret = torch._C._nn.nll_loss2d(input, target, weight, _Reduction.get_enum(reduction), ignore_index)
RuntimeError: 1D target tensor expected, multi-target not supported
whats wrong? how to solve this problem? why this happend?
Thank you very much in advance!
Upvotes: 4
Views: 8692
Reputation: 9786
I got the same error message and the reason is that the targets
are like multi-D tensor more than 1D:
tensor([[0],
[0],
[0],
...,
[9],
[9],
[9]], dtype=torch.int32)
and using torch.flatten(targets)
solved my problem. The target now has 1D tensor shape:
tensor([0, 0, 0, ..., 9, 9, 9], dtype=torch.int32)
Upvotes: 2
Reputation: 3496
When using NLLLoss
the target tensor must contain the index representation of the labels and not one-hot. So for example:
I guess this is what your target looks like:
target = [0, 0, 1, 0]
Just convert it to just the number which is the index of the 1
:
[0, 0, 1, 0] -> [2]
[1, 0, 0, 0] -> [0]
[0, 0, 0, 1] -> [3]
And then convert it to long tensor, ie:
target = [2]
target = torch.Tensor(target).type(torch.LongTensor)
It might be confusing, that your output is a tensor with the length of classes and your target is an number but that how it is.
You can check it out yourself here.
Upvotes: 7