为什么 Pytorch 需要 DoubleTensor 而不是 FloatTensor?
Why does Pytorch expect a DoubleTensor instead of a FloatTensor?
从我在网上看到的所有内容来看,FloatTensors
是 Pytorch 的默认设置,当我创建一个张量传递给我的生成器模块时,它是 FloatTensor
,但是当我尝试 运行 它通过一个线性层抱怨它想要一个 DoubleTensor
。
class Generator(nn.Module):
def __init__(self):
super(Generator, self).__init__()
self.fully_connected = nn.Linear(100, 1024*4*4, bias=False)
def forward(self, zvec):
print(zvec.size())
fc = self.fully_connected(zvec)
return(fc.size())
gen = Generator();
gen(torch.from_numpy(np.random.normal(size=100)))
产生
RuntimeError: Expected object of type torch.DoubleTensor but found type torch.FloatTensor for argument #2 'mat2'
Numpy returns 一个 64 位浮点数,在调用 .from_numpy()
时被转换为 DoubleTensor
。令人困惑的部分是,如果你 运行 print(type(zvec))
它 returns torch.Tensor
它是浮点数还是双精度数。
这里的问题是您的 numpy 输入使用 double
作为数据类型,相同的数据类型也应用于生成的张量。
另一方面,您的图层 self.fully_connected
的 weights
是 float
。当通过层馈送数据时,应用矩阵乘法,这种乘法要求两个矩阵具有相同的数据类型。
所以你有两个解决方案:
- 您可以将输入转换为浮点数:
通过改变:
gen(torch.from_numpy(np.random.normal(size=100)))
收件人:
gen(torch.from_numpy(np.random.normal(size=100)).float())
输入 gen
的输入将被转换为 float
。
转换输入的完整工作代码:
from torch import nn
import torch
import numpy as np
class Generator(nn.Module):
def __init__(self):
super(Generator, self).__init__()
self.fully_connected = nn.Linear(100, 1024*4*4, bias=False)
def forward(self, zvec):
print(zvec.size())
fc = self.fully_connected(zvec)
return(fc.size())
gen = Generator();
gen(torch.from_numpy(np.random.normal(size=100)).float()) # converting network input to float
- 或者您可以将图层权重转换为双倍权重:
如果您需要 双精度,您还可以将 weights
转换为 double
。
更改此行:
self.fully_connected = nn.Linear(100, 1024*4*4, bias=False)
刚到:
self.fully_connected = nn.Linear(100, 1024*4*4, bias=False).double()
转换权重的完整工作代码:
from torch import nn
import torch
import numpy as np
class Generator(nn.Module):
def __init__(self):
super(Generator, self).__init__()
self.fully_connected = nn.Linear(100, 1024*4*4, bias=False).double() # converting layer weights to double()
def forward(self, zvec):
print(zvec.size())
fc = self.fully_connected(zvec)
return(fc.size())
gen = Generator();
gen(torch.from_numpy(np.random.normal(size=100)))
所以这两种方法都适合您,但是如果您不需要 double
的额外精度,您应该使用 float
,因为 double
需要更多的计算能力。
从我在网上看到的所有内容来看,FloatTensors
是 Pytorch 的默认设置,当我创建一个张量传递给我的生成器模块时,它是 FloatTensor
,但是当我尝试 运行 它通过一个线性层抱怨它想要一个 DoubleTensor
。
class Generator(nn.Module):
def __init__(self):
super(Generator, self).__init__()
self.fully_connected = nn.Linear(100, 1024*4*4, bias=False)
def forward(self, zvec):
print(zvec.size())
fc = self.fully_connected(zvec)
return(fc.size())
gen = Generator();
gen(torch.from_numpy(np.random.normal(size=100)))
产生
RuntimeError: Expected object of type torch.DoubleTensor but found type torch.FloatTensor for argument #2 'mat2'
Numpy returns 一个 64 位浮点数,在调用 .from_numpy()
时被转换为 DoubleTensor
。令人困惑的部分是,如果你 运行 print(type(zvec))
它 returns torch.Tensor
它是浮点数还是双精度数。
这里的问题是您的 numpy 输入使用 double
作为数据类型,相同的数据类型也应用于生成的张量。
另一方面,您的图层 self.fully_connected
的 weights
是 float
。当通过层馈送数据时,应用矩阵乘法,这种乘法要求两个矩阵具有相同的数据类型。
所以你有两个解决方案:
- 您可以将输入转换为浮点数:
通过改变:
gen(torch.from_numpy(np.random.normal(size=100)))
收件人:
gen(torch.from_numpy(np.random.normal(size=100)).float())
输入 gen
的输入将被转换为 float
。
转换输入的完整工作代码:
from torch import nn
import torch
import numpy as np
class Generator(nn.Module):
def __init__(self):
super(Generator, self).__init__()
self.fully_connected = nn.Linear(100, 1024*4*4, bias=False)
def forward(self, zvec):
print(zvec.size())
fc = self.fully_connected(zvec)
return(fc.size())
gen = Generator();
gen(torch.from_numpy(np.random.normal(size=100)).float()) # converting network input to float
- 或者您可以将图层权重转换为双倍权重:
如果您需要 双精度,您还可以将 weights
转换为 double
。
更改此行:
self.fully_connected = nn.Linear(100, 1024*4*4, bias=False)
刚到:
self.fully_connected = nn.Linear(100, 1024*4*4, bias=False).double()
转换权重的完整工作代码:
from torch import nn
import torch
import numpy as np
class Generator(nn.Module):
def __init__(self):
super(Generator, self).__init__()
self.fully_connected = nn.Linear(100, 1024*4*4, bias=False).double() # converting layer weights to double()
def forward(self, zvec):
print(zvec.size())
fc = self.fully_connected(zvec)
return(fc.size())
gen = Generator();
gen(torch.from_numpy(np.random.normal(size=100)))
所以这两种方法都适合您,但是如果您不需要 double
的额外精度,您应该使用 float
,因为 double
需要更多的计算能力。