RuntimeError: Expected object of scalar type Long but got scalar type Float for argument #2 'target'

I am using a VAE for non-image data. Pytorch is giving me a hard time Data Types. Any help is extremely appreciated! :slight_smile:

input_size = 16888 
representation_size = 2
batch_size = 16
class VAE(nn.Module):
    def __init__(self):
        super(VAE, self).__init__()
        self.en1 = nn.Linear(input_size, 512)
        self.en_mu = nn.Linear(512, representation_size)
        self.en_std = nn.Linear(512, representation_size)
        self.de1 = nn.Linear(representation_size, 512)
        self.de2 = nn.Linear(512, input_size)
        self.relu = nn.ReLU()
        self.sigmoid = nn.Sigmoid()
        
    def encode(self, x):
        """Encode a batch of samples, and return posterior parameters for each point."""
        h1 = self.relu(self.en1(x))
        return self.en_mu(h1), self.en_std(h1)
    
    def decode(self, z):
        """Decode a batch of latent variables"""
        
        h2 = self.relu(self.de1(z))
        return self.sigmoid(self.de2(h2))
    
    def reparam(self, mu, logvar):
        """Reparameterisation trick to sample z values. 
        This is stochastic during training,  and returns the mode during evaluation."""
        
        if self.training:
            std = logvar.mul(0.5).exp_()
            eps = Variable(std.data.new(std.size()).normal_())
            return eps.mul(std).add_(mu)
        else:
            return mu
            
    
    def forward(self, x):
        """Takes a batch of samples, encodes them, and then decodes them again to compare."""
        mu, logvar = self.encode(x.view(-1, input_size))
        z = self.reparam(mu, logvar)
        return self.decode(z), mu, logvar
    
    def loss(self, reconstruction, x, mu, logvar):
        """ELBO assuming entries of x are binary variables, with closed form KLD."""
        
        bce = torch.nn.functional.cross_entropy(reconstruction, x.view(-1, input_size))
        KLD = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())
        
        # Normalise by same number of elements as in reconstruction
        KLD /= x.view(-1, input_size).data.shape[0] * input_size

        return bce + KLD

    '''# Reconstruction + KL divergence losses summed over all elements and batch
    def loss(self, recon_x, x, mu, logvar):
        #binary cross-entropy
        BCE = torch.nn.functional.mse_loss(recon_x, x.view(-1, 17470))
        #Kullback-Leibler divergence
        KLD = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())

        return BCE + 0.1*KLD'''


    def get_z(self, x):
        """Encode a batch of data points, x, into their z representations."""
        
        mu, logvar = self.encode(x.view(-1, input_size))
        return self.reparam(mu, logvar)
model = VAE()
optimizer = torch.optim.Adam(model.parameters(), lr=0.005)
X.shape
(1062, 16888)
def train(epoch, batches_per_epoch = 124, log_interval=500):
    model.train()
    
    ind = np.arange(X.shape[0])
    for i in range(batches_per_epoch):
        data = torch.from_numpy(X[np.random.choice(ind, size=batch_size)]).float()
        print(data.shape)
        data = Variable(data, requires_grad=False)
        optimizer.zero_grad()
        recon_batch, mu, logvar = model(data)
        loss = model.loss(recon_batch, data, mu, logvar)
        loss.backward()
        #train_loss += loss.data[0]
        optimizer.step()
        #if (i % log_interval == 0) and (epoch % 5 ==0):
        #Print progress
        print('Train Epoch: {} [{}/{}]\tLoss: {:.6f}'.format(
            epoch, i * batch_size, batch_size*batches_per_epoch,
            loss.data / len(data)))

    print('====> Epoch: {} done!'.format(
          epoch))


def test(epoch, batches_per_epoch=1):
    model.eval()

    ind = np.arange(X.shape[0])
    for i in range(batches_per_epoch):
        
        data = torch.from_numpy(X[np.random.choice(ind, size=batch_size)]).float()
        data = Variable(data, requires_grad=False)
        recon_batch, mu, logvar = model(data)
        if i == 0:
            n = min(data.size(0), 2)
            print(data.view(batch_size, 2,2)[:n])
            print(recon_batch.view(batch_size, 2,2)[:n])
print_examples = False #Change to true if you want to see some examples at each step!
for epoch in range(1, 50):
    train(epoch)
    if print_examples:
        test(epoch)

ERROR:

RuntimeError                              Traceback (most recent call last)
<ipython-input-53-475f5b63fa8b> in <module>()
      1 print_examples = False #Change to true if you want to see some examples at each step!
      2 for epoch in range(1, 50):
----> 3     train(epoch)
      4     if print_examples:
      5         test(epoch)

<ipython-input-52-57a6478df61e> in train(epoch, batches_per_epoch, log_interval)
      9         optimizer.zero_grad()
     10         recon_batch, mu, logvar = model(data)
---> 11         loss = model.loss(recon_batch, data, mu, logvar)
     12         loss.backward()
     13         #train_loss += loss.data[0]

<ipython-input-43-3f9327bb329f> in loss(self, reconstruction, x, mu, logvar)
     42         """ELBO assuming entries of x are binary variables, with closed form KLD."""
     43 
---> 44         bce = torch.nn.functional.cross_entropy(reconstruction, x.view(-1, input_size))
     45         KLD = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())
     46 

/projects/sysbio/projects/czi/immune/anaconda2/envs/py36/lib/python3.6/site-packages/torch/nn/functional.py in cross_entropy(input, target, weight, size_average, ignore_index, reduce, reduction)
   1968     if size_average is not None or reduce is not None:
   1969         reduction = _Reduction.legacy_get_string(size_average, reduce)
-> 1970     return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)
   1971 
   1972 

/projects/sysbio/projects/czi/immune/anaconda2/envs/py36/lib/python3.6/site-packages/torch/nn/functional.py in nll_loss(input, target, weight, size_average, ignore_index, reduce, reduction)
   1788                          .format(input.size(0), target.size(0)))
   1789     if dim == 2:
-> 1790         ret = torch._C._nn.nll_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index)
   1791     elif dim == 4:
   1792         ret = torch._C._nn.nll_loss2d(input, target, weight, _Reduction.get_enum(reduction), ignore_index)

RuntimeError: Expected object of scalar type Long but got scalar type Float for argument #2 'target'

This line is acting up because the x tensor consists of float (decimal number) instead of a long (whole number).

A tensor can be converted to Long by tensor_name.type(torch.LongTensor).

Side note, If you are using the gpu to train the tensor needs to be put on the gpu with tensor_name.type(torch.cuda.LongTensor)