尝试训练pytorch模型时出现意外的数据类型

时间:2019-05-24 17:56:32

标签: pytorch

我正在建立一个基本的神经网络来学习pytorch。尝试训练它总是失败,并显示消息“标量类型为Float的预期对象,但参数#4'mat1'的标量类型为Double”。我怀疑将数据放在一起时做错了事,但我不知道该怎么办。

有问题的数据是我生成的几个一维数字列表,应该是线性可分离的。

我在下面粘贴了我的代码。

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))


这就是我生成数据并尝试对其进行训练的方式:

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)

最后,这是堆栈跟踪:

<ipython-input-114-ab674ae015a5> in train(data, validation, net, epochs)
     13             print('x_batch: ', type(x_batch[0].item()))
     14             print('y_batch: ', type(y_batch[0].item()))
---> 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:
--> 489             result = self.forward(*input, **kwargs)
    490         for hook in self._forward_hooks.values():
    491             hook_result = hook(self, input, result)

<ipython-input-58-ec2e6d981760> in forward(self, x)
      5 
      6     def forward(self, x):
----> 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:
--> 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):
---> 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
-> 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'

我试图通过在train方法中记录x_batch和y_batch的类型来进行调试,但是它们都显示为float,因此我对Double的来源感到困惑。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

PyTorch默认使用单精度浮点数。

在行中:

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

np.double替换为np.float32