Reputation: 87
I am writing this Image Classifier and I have defined the loaders but getting this mistake and I have no clue about it.
I have defined the train loader, for a better explanation I tried this
for ina,lab in train_loader:
print(type(ina))
print(type(lab))
and I got
<class 'torch.Tensor'>
<class 'tuple'>
Now, For training of the model, I did
def train_model(model,optimizer,n_epochs,criterion):
start_time = time.time()
for epoch in range(1,n_epochs-1):
epoch_time = time.time()
epoch_loss = 0
correct = 0
total = 0
print( "Epoch {}/{}".format(epoch,n_epochs))
model.train()
for inputs,labels in train_loader:
inputs = inputs.to(device)
labels = labels.to(device)
optimizer.zero_grad()
output = model(inputs)
loss = criterion(output,labels)
loss.backward()
optimizer.step()
epoch_loss +=loss.item()
_,pred =torch.max(output,1)
correct += (pred.cpu()==label.cpu()).sum().item()
total +=labels.shape[0]
acc = correct/total
and I got the error:
Epoch 1/15
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-36-fea243b3636a> in <module>
----> 1 train_model(model=arch, optimizer=optim, n_epochs=15, criterion=criterion)
<ipython-input-34-b53149a4bac0> in train_model(model, optimizer, n_epochs, criterion)
12 for inputs,labels in train_loader:
13 inputs = inputs.to(device)
---> 14 labels = labels.to(device)
15 optimizer.zero_grad()
16 output = model(inputs)
AttributeError: 'tuple' object has no attribute 'to'
If you want anything more, please tell me! Thanks
Edit: The label looks like this. This was an Image Classification between Bee and Wasp. It also contains insects and non insects
('wasp', 'wasp', 'insect', 'insect', 'wasp', 'insect', 'insect', 'wasp', 'wasp', 'bee', 'insect', 'insect', 'other', 'bee', 'other', 'wasp', 'other', 'wasp', 'bee', 'bee', 'wasp', 'wasp', 'wasp', 'wasp', 'bee', 'wasp', 'wasp', 'other', 'bee', 'wasp', 'bee', 'bee') ('wasp', 'wasp', 'insect', 'bee', 'other', 'wasp', 'insect', 'wasp', 'insect', 'insect', 'insect', 'wasp', 'wasp', 'insect', 'wasp', 'wasp', 'wasp', 'bee', 'wasp', 'wasp', 'insect', 'insect', 'wasp', 'wasp', 'bee', 'wasp', 'insect', 'bee', 'bee', 'insect', 'insect', 'other')
Upvotes: 2
Views: 10580
Reputation: 453
I also got the same error when I was training an Image classification model with a reference-style image dataset. Here I implemented a Custom Dataset Class by extending from torch.utils.data import Dataset
class. Same as you I haven't encoded my target labels and they are just a tuple of class names(strings). Since PyTorch tensors don't accept string data directly, I had to convert these labels into integer-encoded tensors before using them in model training.
Upvotes: 0
Reputation: 3450
It literally means that the the tuple class in Python doesn't have a method called to
. Since you're trying to put your labels onto your device, just do labels = torch.tensor(labels).to(device)
.
If you don't want to do this, you can change the way the DataLoader works by making it return your labels as a PyTorch tensor rather than a tuple.
Since the labels seem to be strings, I would convert them to one-hot encoded vectors first:
>>> import torch
>>> labels_unique = set(labels)
>>> keys = {key: value for key, value in zip(labels_unique, range(len(labels_unique)))}
>>> labels_onehot = torch.zeros(size=(len(labels), len(keys)))
>>> for idx, label in enumerate(labels_onehot):
... labels_onehot[idx][keys[label]] = 1
...
>>> labels_onehot = labels.to(device)
I'm shooting a bit in the dark here because I don't know the details exactly, but yeah strings won't work with tensors.
Upvotes: 4