为什么 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_connectedweightsfloat。当通过层馈送数据时,应用矩阵乘法,这种乘法要求两个矩阵具有相同的数据类型。

所以你有两个解决方案:

  • 您可以将输入转换为浮点数:

通过改变:

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 需要更多的计算能力。