Pytorch - TypeError: 'torch.Size' object cannot be interpreted as an integer

Hi I am training a PyTorch model and occurred this error:

----> 5 for i, data in enumerate(trainloader, 0):

TypeError: 'torch.Size' object cannot be interpreted as an integer

Not sure what this error means.

You can find my code here :

model.train() for epoch in range(10): running_loss = 0 for i, data in enumerate(trainloader, 0): inputs, labels = data optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() if i % 2000 == 0: print (loss.item()) running_loss += loss.item() if i % 1000 == 0: print ('[%d, %5d] loss: %.3f' % (epoch, i, running_loss/ 1000)) running_loss = 0 torch.save(model, 'FeatureNet.pkl') 

Update

This is the codeblock for DataLoader. I am using a customized dataloader and datasets, which x are pictures with size (1025, 16) and y are one-hot encoded vectors for classification.

x_train.shape = (1100, 1025, 16)

y_train.shape = (1100, 10)

clean_dir = '/home/tk/Documents/clean/' mix_dir = '/home/tk/Documents/mix/' clean_label_dir = '/home/tk/Documents/clean_labels/' mix_label_dir = '/home/tk/Documents/mix_labels/' class MSourceDataSet(Dataset): def __init__(self, clean_dir, mix_dir, clean_label_dir, mix_label_dir): with open(clean_dir + 'clean0.json') as f: clean0 = torch.Tensor(json.load(f)) with open(mix_dir + 'mix0.json') as f: mix0 = torch.Tensor(json.load(f)) with open(clean_label_dir + 'clean_label0.json') as f: clean_label0 = torch.Tensor(json.load(f)) with open(mix_label_dir + 'mix_label0.json') as f: mix_label0 = torch.Tensor(json.load(f)) self.spec = torch.cat([clean0, mix0], 0) self.label = torch.cat([clean_label0, mix_label0], 0) def __len__(self): return self.spec.shape def __getitem__(self, index): spec = self.spec[index] label = self.label[index] return spec, label 

getitem

a, b = trainset.__getitem__(1000) print (a.shape) print (b.shape) 

a.shape = torch.Size([1025, 16]); b.shape = torch.Size([10])

Error message

--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-9-3bd71e5c00e1> in <module>() 3 running_loss = 0 4 ----> 5 for i, data in enumerate(trainloader, 0): 6 7 inputs, labels = data ~/anaconda3/lib/python3.7/site-packages/torch/utils/data/dataloader.py in __next__(self) 311 def __next__(self): 312 if self.num_workers == 0: # same-process loading --> 313 indices = next(self.sample_iter) # may raise StopIteration 314 batch = self.collate_fn([self.dataset[i] for i in indices]) 315 if self.pin_memory: ~/anaconda3/lib/python3.7/site-packages/torch/utils/data/sampler.py in __iter__(self) 136 def __iter__(self): 137 batch = [] --> 138 for idx in self.sampler: 139 batch.append(idx) 140 if len(batch) == self.batch_size: ~/anaconda3/lib/python3.7/site-packages/torch/utils/data/sampler.py in __iter__(self) 32 33 def __iter__(self): ---> 34 return iter(range(len(self.data_source))) 35 36 def __len__(self): TypeError: 'torch.Size' object cannot be interpreted as an integer 
0

1 Answer

Your problem is the __len__ function. You cannot use the shape as return value.

Here is an example for illustration:

import torch class Foo: def __init__(self, data): self.data = data def __len__(self): return self.data.shape myFoo = Foo(data=torch.rand(10, 20)) print(len(myFoo)) 

Will raise exactly the same error:

--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-285-e97aace2f622> in <module> 7 8 myFoo = Foo(data=torch.rand(10, 20)) ----> 9 print(len(myFoo)) TypeError: 'torch.Size' object cannot be interpreted as an integer 

Since shape represents a torch.Size tuple:

print(myFoo.data.shape) 

Output:

torch.Size([10, 20]) 

So you have to decide which dimension you want to hand over to __len__, for example the first dimension:

import torch class Foo: def __init__(self, data): self.data = data def __len__(self): return self.data.shape[0] # choosing first dimension for len myFoo = Foo(data=torch.rand(10, 20)) print(len(myFoo)) # prints 10 

Works fine and returns 10. Of course you can also choose any other dimension of your input, but you have to choose one.

So in your code of your MSourceDataSet you have to change your __len__ function to for example:

def __len__(self): return self.spec.shape[0] # as said of course you can also choose other dimensions 

This should solve your problem.

0

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like