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.