【问题标题】:Expected object of type torch.FloatTensor but found type torch.cuda.FloatTensor for argument #2 'weight'预期为 torch.FloatTensor 类型的对象,但为参数 #2 'weight' 找到了类型 torch.cuda.FloatTensor
【发布时间】:2018-12-01 19:18:51
【问题描述】:

首先,我使用了“model.cuda()”之类的方法将模型和数据转换为 cuda。但它仍然存在这样的问题。我调试模型的每一层,每个模块的权重都有 iscuda=True。那么有人知道为什么会出现这样的问题吗?

我有两个模型,一个是 resnet50,另一个包含第一个作为主干。

class FC_Resnet(nn.Module):
    def __init__(self, model, num_classes):
        super(FC_Resnet, self).__init__()

        # feature encoding
        self.features = nn.Sequential(
            model.conv1,
            model.bn1,
            model.relu,
            model.maxpool,
            model.layer1,
            model.layer2,
            model.layer3,
            model.layer4)

        # classifier
        num_features = model.layer4[1].conv1.in_channels
        self.classifier = nn.Sequential(
            nn.Conv2d(num_features, num_classes, kernel_size=1, bias=True))

    def forward(self, x):
        # children=self.features.children()
        # for child in children:
        #     if child.weight is not None:
        #         print(child.weight.device)
        x = self.features(x)
        x = self.classifier(x)
        return x

def fc_resnet50(num_classes=20, pre_trained=True):
    model = FC_Resnet(models.resnet50(pre_trained), num_classes)

    return model

还有一个:

class PeakResponseMapping(nn.Sequential):
    def __init__(self, *args, **kargs):
        super(PeakResponseMapping, self).__init__(*args)
        ...

    def forward(self, input, class_threshold=0, peak_threshold=30, retrieval_cfg=None):
        assert input.dim() == 4
        if self.inferencing:
            input.requires_grad_()

        class_response_maps = super(PeakResponseMapping, self).forward(input)

        return class_response_maps

而且主要的很简单:

def main():
    dataset = VOC(img_transform=image_transform())
    dataloader = DataLoader(dataset, batch_size=BATCH_SIZE, shuffle=True)

    model = peak_response_mapping(fc_resnet50(), win_size=3, sub_pixel_locating_factor=8, enable_peak_stimulation=True)
    model=model.cuda()

    for step, (b_x, b_y) in enumerate(dataloader):
        b_x.cuda()
        b_y.cuda()

        result = model.forward(b_x)

【问题讨论】:

    标签: python deep-learning pytorch


    【解决方案1】:

    在堆栈跟踪中的某个位置,Torch 期待一个 CPU 张量 (torch.FloatTensor),但得到一个 GPU / CUDA 张量 (torch.cuda.FloatTensor)。

    给定一个张量tensor

    • tensor.to('cpu') 返回张量的 CPU 版本
    • tensor.to('cuda') 返回张量的 CUDA 版本

    要编写与硬件无关的代码:

    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    

    那么你可以这样做:

    tensor.to(device)
    

    对于 OP,这变成:

    result = model.forward(b_x.to(device))
    

    【讨论】:

      【解决方案2】:

      您需要将b_x.cuda() 分配回b_x

      b_x = b_x.cuda()
      b_y = b_y.cuda()
      

      .cuda()的文档:

      在 CUDA 内存中返回此对象的副本。

      所以,b_x.cuda() 返回b_x副本,并且不会以就地 方式影响b_x

      【讨论】:

        猜你喜欢
        • 2018-12-07
        • 2018-08-30
        • 1970-01-01
        • 2018-12-29
        • 1970-01-01
        • 2019-01-11
        • 2023-04-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多