Ожидаемый объект типа torch.FloatTensor, но обнаружен тип torch.cuda.FloatTensor для аргумента № 2 «вес» - PullRequest
0 голосов
/ 05 ноября 2018

Во-первых, я использовал «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)

Ответы [ 2 ]

0 голосов
/ 01 декабря 2018

Где-то внизу трассировки стека Torch ожидает тензор процессора (torch.FloatTensor), но получает тензор GPU / CUDA (torch.cuda.FloatTensor).

Учитывая тензор tensor:

  • tensor.to('cpu') возвращает версию тензорного процессора
  • tensor.to('cuda') возвращает версию тензора в CUDA

Для написания аппаратно-независимого кода:

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

Тогда вы можете сделать:

tensor.to(device)

Для ОП это становится:

result = model.forward(b_x.to(device))
0 голосов
/ 05 ноября 2018

Вам необходимо присвоить b_x.cuda() обратно b_x:

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

Глядя на документацию .cuda():

Возвращает копию этого объекта в памяти CUDA.

Итак, b_x.cuda() возвращает копию из b_x и не влияет на b_x на месте .

...