Целевой размер (torch.Size ([12])) должен совпадать с входным размером (torch.Size ([12, 1000])) - PullRequest
0 голосов
/ 30 апреля 2020

Я использую models.vgg16(pretrained=True) модель для классификации изображений, где количество классов = 3.

Размер партии равен 12 trainloader = torch.utils.data.DataLoader(train_data, batch_size=12, shuffle=True), поскольку ошибка говорит Target size (torch.Size([12])) must be the same as input size (torch.Size([12, 1000]))

Я изменился последним f c параметры слоя и полученный последний слой F C как Linear(in_features=1000, out_features=3, bias=True)

Функция потери равна BCEWithLogitsLoss()

criterion = nn.BCEWithLogitsLoss()
optimizer = optim.SGD(vgg16.parameters(), lr=0.001, momentum=0.9)

Код обучения:

        # zero the parameter gradients
        optimizer.zero_grad()
        outputs = vgg16(inputs)               #----> forward pass
        loss = criterion(outputs, labels)   #----> compute loss #error occurs here
        loss.backward()                     #----> backward pass
        optimizer.step()                    #----> weights update

При вычислении потерь я получаю эту ошибку Target size (torch.Size([12])) must be the same as input size (torch.Size([12, 1000]))

код доступен по адресу: код

Ответы [ 2 ]

1 голос
/ 30 апреля 2020

поделитесь кодом вашей модели, и это будет легко отладить. Проблема, безусловно, в вашем последнем полностью связанном слое. Несовпадение размеров ясно говорит о том, что вы получаете 1000 объектов для каждого из 12 изображений (размер пакета), но затем у вас есть 12 объектов для сравнения.

Ясно, что полностью подключенный слой имеет проблему.

Используйте это, и вы решите проблему -

vgg16 = models.vgg16(pretrained=True)

vgg16.classifier[6]= nn.Linear(4096, 3)

if __name__ == "__main__":
    from torchsummary import summary
    model = vgg16
    model = model.cuda()
    print(model)
    summary(model, input_size = (3,120,120))


----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Conv2d-1         [-1, 64, 120, 120]           1,792
              ReLU-2         [-1, 64, 120, 120]               0
            Conv2d-3         [-1, 64, 120, 120]          36,928
              ReLU-4         [-1, 64, 120, 120]               0
         MaxPool2d-5           [-1, 64, 60, 60]               0
            Conv2d-6          [-1, 128, 60, 60]          73,856
              ReLU-7          [-1, 128, 60, 60]               0
            Conv2d-8          [-1, 128, 60, 60]         147,584
              ReLU-9          [-1, 128, 60, 60]               0
        MaxPool2d-10          [-1, 128, 30, 30]               0
           Conv2d-11          [-1, 256, 30, 30]         295,168
             ReLU-12          [-1, 256, 30, 30]               0
           Conv2d-13          [-1, 256, 30, 30]         590,080
             ReLU-14          [-1, 256, 30, 30]               0
           Conv2d-15          [-1, 256, 30, 30]         590,080
             ReLU-16          [-1, 256, 30, 30]               0
        MaxPool2d-17          [-1, 256, 15, 15]               0
           Conv2d-18          [-1, 512, 15, 15]       1,180,160
             ReLU-19          [-1, 512, 15, 15]               0
           Conv2d-20          [-1, 512, 15, 15]       2,359,808
             ReLU-21          [-1, 512, 15, 15]               0
           Conv2d-22          [-1, 512, 15, 15]       2,359,808
             ReLU-23          [-1, 512, 15, 15]               0
        MaxPool2d-24            [-1, 512, 7, 7]               0
           Conv2d-25            [-1, 512, 7, 7]       2,359,808
             ReLU-26            [-1, 512, 7, 7]               0
           Conv2d-27            [-1, 512, 7, 7]       2,359,808
             ReLU-28            [-1, 512, 7, 7]               0
           Conv2d-29            [-1, 512, 7, 7]       2,359,808
             ReLU-30            [-1, 512, 7, 7]               0
        MaxPool2d-31            [-1, 512, 3, 3]               0
AdaptiveAvgPool2d-32            [-1, 512, 7, 7]               0
           Linear-33                 [-1, 4096]     102,764,544
             ReLU-34                 [-1, 4096]               0
          Dropout-35                 [-1, 4096]               0
           Linear-36                 [-1, 4096]      16,781,312
             ReLU-37                 [-1, 4096]               0
          Dropout-38                 [-1, 4096]               0
           Linear-39                    [-1, 3]          12,291
================================================================
Total params: 134,272,835
Trainable params: 134,272,835
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.16
Forward/backward pass size (MB): 62.84
Params size (MB): 512.21
Estimated Total Size (MB): 575.21
1 голос
/ 30 апреля 2020

Попробуйте дважды проверить, как вы изменили линейный слой. Кажется, что модель каким-то образом не пропускает проход через нее.

Выход вашей модели имеет 1000 выходных размеров для каждой выборки, в то время как он должен иметь 3. Это причина, по которой вы не можете оценить потери, так как вы пытаетесь сравнить От 1000 классов до 3. У вас должно быть 3 выхода в вашем последнем слое, и это должно работать.

РЕДАКТИРОВАТЬ

Из кода, которым вы поделились здесь: ссылка , я думаю, что есть две проблемы.

Во-первых, вы модифицировали свою модель следующим образом:

# Load the pretrained model from pytorch
vgg16 = models.vgg16(pretrained=True)

vgg16.classifier[6].in_features = 1000
vgg16.classifier[6].out_features = 3

, в то время как вы здесь добавили слой как Атрибут для вашей сети, вы также должны изменить функцию forward() вашей модели. Добавление слоя в качестве атрибута в список не применяет слой при прямой передаче ввода.

Обычно для правильного выполнения этой процедуры необходимо определить новый класс, который наследуется от модели, которую вы хотите реализовать - class myvgg16(models.vgg16) или более обычно class myvgg(nn.Module). Вы можете найти дальнейшие объяснения в следующей ссылке

Если это не удастся, попробуйте unsqueeze(1) размер ваших целей (т.е. переменная lables). Это менее вероятно, чтобы быть причиной ошибки, но стоит попробовать.

РЕДАКТИРОВАТЬ

Дайте еще одну попытку преобразования вашего целевого тензора в один горячий векторов. И измените тип тензора на Float, когда BCELoss получает float.

...