【问题标题】:Target size (torch.Size([12])) must be the same as input size (torch.Size([12, 1000]))目标尺寸 (torch.Size([12])) 必须与输入尺寸 (torch.Size([12, 1000])) 相同
【发布时间】:2020-04-30 07:38:35
【问题描述】:

我正在使用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]))

我已经更改了最后一个 fc 层参数,并将最后一个 FC 层设置为 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]))

代码位于:code

【问题讨论】:

  • 请不要包含图片,而是直接将相关代码复制到您的问题中。

标签: deep-learning pytorch conv-neural-network vgg-net


【解决方案1】:

尝试仔细检查您是如何修改线性图层的。似乎模型不知何故没有通过它。

您的模型输出对于每个样本有 1000 个输出大小,而它应该有 3 个。这就是您无法评估损失的原因,因为您尝试将 1000 个类与 3 个类进行比较。您的最后一层应该有 3 个输出,并且应该可以的。

编辑

从你在这里分享的代码:link,我认为有两个问题。

首先,您以这种方式修改了模型:

# 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)。您可以在以下link

中找到进一步的解释

如果失败,请尝试unsqueeze(1) 您的目标大小(即标签变量)。这不太可能是错误的原因,但值得一试。

编辑

再次尝试将您的目标张量转换为一个热向量。并在 BCELoss 接收浮点数时将张量类型更改为浮点数。

【讨论】:

  • 代码在 github.com/irfanumar1994/vgg/blob/master/code.ipynb 共享,您可以在那里查看模型架构
【解决方案2】:

分享您的模型的代码,它会很容易调试。问题肯定出在你的最后一个全连接层。大小不匹配清楚地表明,对于 12 幅图像(批量大小),您将获得 1000 个特征,但随后您有 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

【讨论】:

  • 我检查了你的代码。错误是,第 3 层的输出是 4096,而第 6 层的输入是 1000,这是错误的。它应该与第 3 层的输出相匹配。只需更改它,一切看起来都很好。只需更改第 6 层的 in_feature 即可。
  • 我添加了上面的代码来解决你的问题。这是必须要做的。
  • 谢谢,除此之外,一个热编码和转换成浮点工作 y_onehot = nn.functional.one_hot(labels, num_classes=3) y_onehot = y_onehot.float()
猜你喜欢
  • 2021-04-08
  • 2021-11-12
  • 2020-01-07
  • 2022-01-21
  • 2021-09-29
  • 2021-12-05
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
相关资源
最近更新 更多