PyTorch 运行时错误:期望的标量类型为 Double,但实际得到的是 Float。

21
我正在尝试为我的神经网络实现一个自定义数据集。但在运行前向函数时出现了这个错误。代码如下。
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import Dataset, DataLoader
import numpy as np

class ParamData(Dataset):
    def __init__(self,file_name):
        self.data = torch.Tensor(np.loadtxt(file_name,delimiter = ','))    #first place
    def __len__(self):
        return self.data.size()[0]
    def __getitem__(self,i):
        return self.data[i]

class Net(nn.Module):
    def __init__(self,in_size,out_size,layer_size=200):
        super(Net,self).__init__()
        self.layer = nn.Linear(in_size,layer_size)
        self.out_layer = nn.Linear(layer_size,out_size)

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

datafile = 'data1.txt'

net = Net(100,1)
dataset = ParamData(datafile)
n_samples = len(dataset)

#dataset = torch.Tensor(dataset,dtype=torch.double)   #second place
#net.float()                                          #thrid place

net.forward(dataset[0])         #fourth place
在文件 data1.txt 中,包含一些数字的 csv 格式文本文件,每个 dataset[i] 是一个大小为100x1的torch.Tensor对象,数据类型为torch.float64。错误信息如下:
Traceback (most recent call last):
  File "Z:\Wrong.py", line 33, in <module>
    net.forward(dataset[0])
  File "Z:\Wrong.py", line 23, in forward
    x = F.relu(self.layer(x))
  File "E:\Python38\lib\site-packages\torch\nn\modules\module.py", line 532, in __call__
    result = self.forward(*input, **kwargs)
  File "E:\Python38\lib\site-packages\torch\nn\modules\linear.py", line 87, in forward
    return F.linear(input, self.weight, self.bias)
  File "E:\Python38\lib\site-packages\torch\nn\functional.py", line 1372, in linear
    output = input.matmul(weight.t())
RuntimeError: Expected object of scalar type Double but got scalar type Float for argument #2 'mat2' in call to _th_mm

看起来我应该将dataset中的数字的dtype更改为torch.double。我尝试过以下操作:

  • 将第一处的代码更改为self.data = torch.tensor(np.loadtxt(file_name,delimiter = ','),dtype=torch.double)

  • 将第四处的代码更改为net.forward(dataset[0].double())

  • 取消注释第二或第三处的其中一行

我认为这些是我从类似问题中看到的解决方案,但它们要么会产生新的错误,要么什么都不做。我该怎么办?


更新:所以我通过将第一处更改为以下内容使其工作:

self.data = torch.from_numpy(np.loadtxt(file_name,delimiter = ',')).float()

这很奇怪,因为它恰恰相反于错误提示。这是一个bug吗?我仍然希望有些解释。


4
在将输入转换为torch张量后,对其使用.float()也适用于我。 - tejasvi88
3
也对我有用...我因为类似的原因感到困惑。 - senior_mle
3个回答

19

简而言之:您的数据类型为double,但是您的模型类型为float。在 PyTorch 中,只有相同数据类型的数据可以被输入到模型中。

详细解释

该问题与 PyTorch 和 Numpy 的默认数据类型相关。首先我将解释为什么会出现此错误,然后提供一些解决方案(但是一旦您理解了原则,就不需要我的解决方案)。

  1. torch.float32(也称为 torch.float
  2. torch.float64(也称为 torch.double
  • 了解 PyTorch 张量的默认数据类型非常重要,它是 torch.float32(也称为 torch.float)。这意味着当您创建一个张量时,其默认数据类型是 torch.float32。例如:torch.ones(1).dtype,这将以默认情况下打印 torch.float32。模型参数默认也是这个数据类型。

  • 在您的情况下,net = Net(100,1) 将创建一个其参数数据类型为 torch.float32 的模型。

接下来我们需要谈论 Numpy:

  • Numpy ndarray的默认dtype是numpy.float64。这意味着当您创建一个numpy数组时,它的默认dtype是numpy.float64。尝试:np.ones(1).dtype。这将在默认情况下打印出dtype('float64')

  • 在您的情况中,您的数据来自通过np.loadtxt加载的本地文件,因此数据首先被加载为dtype('float64')(作为numpy数组),然后转换为dtype为torch.float64(又名torch.double)的torch张量。当您将numpy数组转换为torch张量时,它们将具有相应的dtype。

我认为现在问题已经很清楚了,您的模型参数为torch.float32(又名torch.float),但尝试在torch.float64(又名torch.double)的数据上运行它。这也是错误消息试图表达的:Expected object of scalar type Double but got scalar type Float for argument

解决方法:

  1. 您已经找到一种:通过调用tensor.float()将数据转换为torch.float32
  2. 您还可以在加载数据时指定dtype:np.loadtxt(file_name,delimiter = ',',dtype="float32")

10

现在我对pytorch有更多的经验,我想我可以解释这个错误信息。看起来是这一行代码:

RuntimeError: Expected object of scalar type Double but got scalar type Float for argument #2 'mat2' in call to _th_mm

实际上是指当调用矩阵乘法时,线性层的权重。由于输入是double,而权重是float,因此该行代码是合理的。

output = input.matmul(weight.t())

期望权重为double


1

在PyTorch中训练UNet时,我遇到了这个错误。训练和测试数据是由numpy数组创建的。只需在从numpy数组创建张量时指定数据类型即可解决错误。

X_train, y_train = //read data files

train_x = torch.tensor(X_train, dtype=torch.float32) 

train_y = torch.tensor(y_train, dtype=torch.float32)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接