Is_same_size error

This problem has tortured me for days. I’m using PyTorch to build a binary classifier to predict positive/negative comments on movies from IMDB. Each review contains the indexes of 10,000 words referenced to a dictionary. The code is as follows.

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.utils.data as data_utils
from torch.autograd import Variable

# hpyerparameter
N, d_in, h1, h2, d_out = 512, 10000, 16, 16, 1
learning_rate = 0.01
num_epochs = 5

# load data
raw = np.load('imdb.npz')
x_test = raw['x_test']
x_train = raw['x_train']
y_test = raw['y_test']
y_train = raw['y_train']

# remove the top 20 and any words ranked after 10,000 from each review
# Encoding the integer sequences into a binary matrix
def vectorize_sequences(sequences, dimension=10000, rank_lb=20, rank_hb=10000):
	results = np.zeros((len(sequences), dimension))
	# create an all-zero matrix of shape (len(sequences), dimension)
	for i, sequence in enumerate(sequences):
		new_seq = [x-1 for x in sequence if x > rank_lb and x <= rank_hb]
		results[i, new_seq] = 1. # set specific indices of results[i] to 1s
	return results

# our vectorized training data
x_train = vectorize_sequences(x_train)
# our vectorized test data
x_test = vectorize_sequences(x_test)

# Encoding the labels
y_train = np.asarray(y_train)
y_test = np.asarray(y_test)

# pack processed data back into dataset
train_new = data_utils.TensorDataset(
	torch.from_numpy(x_train).float(), 
	torch.from_numpy(y_train).long())
test_new = data_utils.TensorDataset(
	torch.from_numpy(x_test).float(),
	torch.from_numpy(y_test).long())

# Data Loader (Input Pipeline)
train_loader = data_utils.DataLoader(
	dataset=train_new, 
	batch_size=N,
	shuffle=True)

test_loader = data_utils.DataLoader(
	dataset=test_new, 
	batch_size=N, 
	shuffle=False)

# Use the nn package to define our model
class Net(nn.Module):
	def __init__(self, d_in, h1, h2, d_out):
		super(Net, self).__init__()
		self.fc1 = nn.Linear(d_in, h1)
		self.fc2 = nn.Linear(h1, h2)
		self.fc3 = nn.Linear(h2, d_out)
		# self.relu = nn.ReLU()
		# self.sigmoid = nn.Sigmoid()

	def forward(self, x):
		x = F.relu(self.fc1(x))
		x = F.relu(self.fc2(x))
		return self.fc3(x)

# instantiate a network
net = Net(d_in, h1, h2, d_out)
# net.cuda()

# optimization and metric
loss_fn = nn.BCEWithLogitsLoss()
optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate)

for epoch in range(1, num_epochs):
	#net.train()
	for batch_idx, (data, target) in enumerate(train_loader):
		# data, target = data.cuda(), target.cuda()
		data, target = Variable(data), Variable(target)
		optimizer.zero_grad()
		output = net(data)
		loss = loss_fn(output, target)
		loss.backward()
		optimizer.step()

		if batch_idx % 100 == 0:
			print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
				epoch, batch_idx * len(data), len(train_loader.dataset),
				100. * batch_idx / len(train_loader), loss.data[0]))

	#net.eval()
	test_loss, correct = 0, 0
	for data, target in test_loader:
		# data, target = data.cuda(), target.cuda()
		data, target = Variable(data, volatile=True), Variable(target)	
		output = net(data)
		test_loss += loss_fn(output, target, size_average=False).data[0]
		pred = output.data.ge(0.5)
		correct += (pred == target).sum()

	test_loss /= len(test_loader.dataset)
	print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
		test_loss, correct, len(test_loader.dataset),
		100. * correct / len(test_loader.dataset)))	

When I run the code, I keep getting the error message:

TypeError                                 Traceback (most recent call last)
<ipython-input-17-935caa0cc91e> in <module>()
     86                 optimizer.zero_grad()
     87                 output = net(data)
---> 88                 loss = loss_fn(output, target)
     89                 loss.backward()
     90                 optimizer.step()

~/miniconda3/envs/pytorch/lib/python3.6/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    222         for hook in self._forward_pre_hooks.values():
    223             hook(self, input)
--> 224         result = self.forward(*input, **kwargs)
    225         for hook in self._forward_hooks.values():
    226             hook_result = hook(self, input, result)

~/miniconda3/envs/pytorch/lib/python3.6/site-packages/torch/nn/modules/loss.py in forward(self, input, target)
    331             return F.binary_cross_entropy_with_logits(input, target, Variable(self.weight), self.size_average)
    332         else:
--> 333             return F.binary_cross_entropy_with_logits(input, target, size_average=self.size_average)
    334 
    335 

~/miniconda3/envs/pytorch/lib/python3.6/site-packages/torch/nn/functional.py in binary_cross_entropy_with_logits(input, target, weight, size_average)
    793                 for each minibatch.
    794     """
--> 795     if not target.is_same_size(input):
    796         raise ValueError("Target size ({}) must be the same as input size ({})".format(target.size(), input.size()))
    797 

~/miniconda3/envs/pytorch/lib/python3.6/site-packages/torch/autograd/variable.py in is_same_size(self, other_var)
    307 
    308     def is_same_size(self, other_var):
--> 309         return self.data.is_same_size(other_var.data)
    310 
    311     def _add(self, other, inplace):

TypeError: is_same_size received an invalid combination of arguments - got (torch.FloatTensor), but expected (torch.LongTensor other)

The type of output and target are torch.FloatTensor and torch.LongTensor, and their sizes are torch.Size([512, 1]) and torch.Size([512]). Even I reshape label data to make it match that of output, the error still exists.

Any ideas? Thanks a lot in advance.

2 Likes

Hi Folks, I am encountering the same issue. It would be very helpful if we could get some help in regards to the reported issue.

Ciao.

The error was avoided by making sure:

  1. targets are float
  2. the network outputs one value per sample
  3. The output is flattened using view
    For example:

Blockquote
loss_fn = nn.BCEWithLogitsLoss()
output = net(data)
loss = loss_fn(output.view(-1), target.float())

Hope this helps

1 Like