Unexpected data types when trying to train a pytorch model
I'm putting together a basic neural network to learn pytorch. Attempting to train it always fails with the message "Expected object of scalar type Float but got scalar type Double for argument #4 'mat1'". I suspect I'm doing something wrong with putting the data together, but I don't know what. 

The data in question is a couple of one-dimensional lists of numbers that I've generated, which should be linearly separable. 

I've pasted my code below. 

class MyDataset(Dataset):
    def __init__(self, xs, ys):
        assert len(xs) == len(ys), "Input and output tensors must be the same length"
        self.xs = np.array(xs, dtype=np.double)
        self.ys = np.array(ys, dtype=np.double)

    def __getitem__(self, idx):
        return (self.xs[idx], self.ys[idx])

    def __len__(self):
        return len(self.xs)

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.layer1 = nn.Linear(1, 1)

    def forward(self, x):
        x = F.relu(self.layer1(x))
        return x

def train(data, validation, net, epochs=100):
    learning_rate = 0.01
    optimizer = optim.SGD(net.parameters(), lr=learning_rate)
    criterion = nn.MSELoss()

    for epoch in range(0, epochs):
        print('Beginning epoch ', epoch+1)
        training_losses = []
        validation_losses = []
        for x_batch, y_batch in data: 
            optimizer.zero_grad()
            yhat = net(x_batch)
            loss = criterion(y_batch, yhat)
            loss.backward()
            optimizer.step()
            optimizer.zero_grad()
            training_losses.append(loss)

        with torch.no_grad():
            for x_batch, y_batch in validation:
                net.eval()
                yhat = net(x_batch)
                loss = criterion(y_batch, yhat)
                validation_losses.append(loss)

        print('Ending epoch ', epoch+1, 'Training loss: ', np.mean(training_losses), 'Validation loss: ', np.mean(validation_losses))




And this is how I'm generating the data and attempting to train it:

num_samples = 10000
foos = [100 + np.random.normal(scale=20) for x in range(0, num_samples)]
bars = [200 + np.random.normal(scale=20) for x in range(0, num_samples)]

xs = foos + bars
xs = torch.tensor([[x] for x in xs])
ys = np.concatenate([np.zeros(num_samples), np.ones(num_samples)])
ys = torch.tensor([[y] for y in ys])

dataset = MyDataset(xs, ys)

train_dataset, val_dataset = random_split(dataset, [16000, 4000])

train_loader = DataLoader(dataset=train_dataset, batch_size=16)
val_loader = DataLoader(dataset=val_dataset, batch_size=20)

net = Net()
train(train_loader, val_loader, net)



Finally, here's the stack trace:

&lt;ipython-input-114-ab674ae015a5&gt; in train(data, validation, net, epochs)
     13             print('x_batch: ', type(x_batch[0].item()))
     14             print('y_batch: ', type(y_batch[0].item()))
---&gt; 15             yhat = net(x_batch)
     16             loss = criterion(y_batch, yhat)
     17             loss.backward()

/usr/local/lib/python3.6/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    487             result = self._slow_forward(*input, **kwargs)
    488         else:
--&gt; 489             result = self.forward(*input, **kwargs)
    490         for hook in self._forward_hooks.values():
    491             hook_result = hook(self, input, result)

&lt;ipython-input-58-ec2e6d981760&gt; in forward(self, x)
      5 
      6     def forward(self, x):
----&gt; 7         x = F.relu(self.layer1(x))
      8         return x

/usr/local/lib/python3.6/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    487             result = self._slow_forward(*input, **kwargs)
    488         else:
--&gt; 489             result = self.forward(*input, **kwargs)
    490         for hook in self._forward_hooks.values():
    491             hook_result = hook(self, input, result)

/usr/local/lib/python3.6/site-packages/torch/nn/modules/linear.py in forward(self, input)
     65     @weak_script_method
     66     def forward(self, input):
---&gt; 67         return F.linear(input, self.weight, self.bias)
     68 
     69     def extra_repr(self):

/usr/local/lib/python3.6/site-packages/torch/nn/functional.py in linear(input, weight, bias)
   1350     if input.dim() == 2 and bias is not None:
   1351         # fused op is marginally faster
-&gt; 1352         ret = torch.addmm(torch.jit._unwrap_optional(bias), input, weight.t())
   1353     else:
   1354         output = input.matmul(weight.t())

RuntimeError: Expected object of scalar type Float but got scalar type Double for argument #4 'mat1'


I've attempted to debug by logging the types of x_batch and y_batch from within the train method, but they're both showing as float, so I'm stumped as to where the Double is coming from.

Any suggestions?

PyTorch uses single-precision floats by default.

In the lines:

        self.xs = np.array(xs, dtype=np.double)
        self.ys = np.array(ys, dtype=np.double)


Replace np.double with np.float32.
