pytorch 运行时错误:标量类型为 Double 的预期对象,但获得标量类型 Float



我正在尝试为我的神经网络实现一个自定义数据集。但是在运行转发函数时出现此错误。代码如下。

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]都是 dtypetorch.float64的 100 x 1torch.Tensor对象的大小。错误消息如下:

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:Python38libsite-packagestorchnnmodulesmodule.py", line 532, in __call__
result = self.forward(*input, **kwargs)
File "E:Python38libsite-packagestorchnnmoduleslinear.py", line 87, in forward
return F.linear(input, self.weight, self.bias)
File "E:Python38libsite-packagestorchnnfunctional.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()

这很奇怪,因为它与错误消息完全相反。这是一个错误吗?我仍然想要一些解释。

简而言之:您的数据具有双精度类型,但您的模型具有浮点型,这在 pytorch 中是不允许的,因为只有具有相同 dtype 的数据才能输入模型。

在长:此问题与 PyTorch 和 Numpy 的默认 dtype 有关。我将首先解释为什么会发生此错误,然后提出一些解决方案(但我认为一旦您了解原理,您将不需要我的解决方案。

  • PyTorch有几个dtype https://pytorch.org/docs/stable/tensors.html。其中两个与您遇到的问题密切相关:
  1. torch.float32(又名torch.float(
  2. torch.float64(又名torch.double(
  • 重要的是要知道 PyTorch 张量的默认 dtype 是torch.float32(又名torch.float(。这意味着当您创建张量时,其默认 dtype 为torch.float32.try:torch.ones(1).dtype。这将默认打印torch.float32。默认情况下,模型的参数也是此 dtype。

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

然后我们需要谈谈 Numpy:

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

  • 在您的情况下,您的数据来自np.loadtxt加载的本地文件,因此数据首先作为dtype('float64')加载(作为 numpy 数组(,然后转换为 dtypetorch.float64(又名torch.double(的火炬张量。当您将 numpy 数组转换为火炬张量时,就会发生这种情况:它们将具有相应的 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")

现在我对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.

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

相关内容

最新更新