【问题标题】:ValueError: Target size (torch.Size([2])) must be the same as input size (torch.Size([504, 2]))ValueError: 目标尺寸 (torch.Size([2])) 必须与输入尺寸 (torch.Size([504, 2])) 相同
【发布时间】:2022-01-21 15:59:00
【问题描述】:

我有一个用于分类的 CNN 网络(2 个标签)。它由许多 conv3d 层组成,这些层在一个列表中链接在一起,然后在我的 forward 函数的 for 循环中执行。模型如下:

(0) : Sequential(
      (0): Dropout3d(p=0.2, inplace=False)
      (1): Conv3d(1, 8, kernel_size=(3, 3, 3), stride=(1, 1, 1), padding=(1, 1, 1))
      (2): BatchNorm3d(8, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (3): ELU(alpha=1.0)
      (4): Conv3d(8, 16, kernel_size=(3, 3, 3), stride=(1, 1, 1))
      (5): BatchNorm3d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (6): ELU(alpha=1.0)
    )
(1) : Sequential(
      (0): Dropout3d(p=0.1, inplace=False)
      (1): Conv3d(16, 24, kernel_size=(3, 3, 3), stride=(1, 1, 1), padding=(1, 1, 1))
      (2): BatchNorm3d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (3): ELU(alpha=1.0)
      (4): Conv3d(24, 32, kernel_size=(3, 3, 3), stride=(1, 1, 1))
      (5): BatchNorm3d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (6): ELU(alpha=1.0)
    )
 (2) : Sequential(
      (0): Conv3d(32, 80, kernel_size=(3, 3, 3), stride=(1, 1, 1), padding=(1, 1, 1))
      (1): BatchNorm3d(80, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (2): ELU(alpha=1.0)
      (3): Conv3d(80, 128, kernel_size=(3, 3, 3), stride=(1, 1, 1))
      (4): BatchNorm3d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (5): ELU(alpha=1.0)
    )
 (3) : Sequential(
      (0): Conv3d(128, 72, kernel_size=(3, 3, 3), stride=(1, 1, 1), padding=(1, 1, 1))
      (1): BatchNorm3d(72, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (2): ELU(alpha=1.0)
      (3): Conv3d(72, 16, kernel_size=(3, 3, 3), stride=(1, 1, 1))
      (4): BatchNorm3d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (5): ELU(alpha=1.0)
    )
  (finallayer) : Conv3d(16, 2, kernel_size=(4, 5, 4), stride=(1, 1, 1))

在每个顺序块 [0-4] 之后,我们使用以下方法进行最大池化:

max_pool3d(x, kernel_size=2, stride=2)

最后一层的输出然后被重新整形:

x = x.reshape(-1, 2)

每个顺序和最大池化层调用后的维度如下所示:

Input dimension before calling forward: torch.Size([2, 1, 182, 218, 182])
#Here, 2 is batch size and 1 is channel. 

Output dimension of (0) convolution layer: [2, 16, 180, 216, 180] 
#printing as list(x.shape)

Output dimension of pool (0) layer : [2, 16, 90, 108, 90]

Output dimension of (1) convolution layer : [2, 32, 88, 106, 88]

Output dimension of pool (1) layer : [2, 32, 44, 53, 44]

Output dimension of (2) convolution layer : [2, 128, 42, 51, 42]

Output dimension of pool (2) layer : [2, 128, 21, 25, 21]

Output dimension of (3) convolution layer : [2, 16, 19, 23, 19]

Output dimension of pool (3) layer : [2, 16, 9, 11, 9]

Dimension before calling finallayer : [2, 16, 9, 11, 9]

Dimension after finallayer but before reshape : [2, 2, 6, 7, 6]

Dimension post reshape : [504, 2]

在调用 criterion 时,它在内部调用了 pytorch 的 binary_cross_entropy_with_logits。我发现尺寸不匹配。

ValueError: Target size (torch.Size([2])) must be the same as input size (torch.Size([504, 2]))

我已经研究过他们提到使用 torch.unsqueeze() 的类似问题,但是我不确定是否可以使用 unsqueeze 创建 504 行。

此外,我在每次调用后交叉检查了每个输出层通道号并进行了验证。 任何帮助表示赞赏。

【问题讨论】:

  • 我认为您缺少将输入特征维度转换为类维度的线性模块。你不应该以这种方式重塑你的卷积层的输出来获得你的类的维度。

标签: python deep-learning pytorch


【解决方案1】:

我认为您缺少将Batch x Features 转换为Batch x Classesfully connected

将此添加到您的模型构造器(假设您的批量大小为 = 1)

self.fc = nn.Linear(1008, 2)

这到前传的结尾:-

x = x.reshape(batch_size, -1)
x = self.fc(x)

确保按批次尺寸缩放 1008。理想情况下,您应该能够在最后计算 conv 输出的维度

【讨论】:

  • 谢谢。我会尝试在这个线程中更新。
  • 我刚刚编辑了答案,请查看更新后的答案。
猜你喜欢
  • 2021-12-05
  • 1970-01-01
  • 2021-11-12
  • 2020-01-07
  • 2021-04-08
  • 2021-09-29
  • 1970-01-01
  • 2022-06-24
  • 2022-11-23
相关资源
最近更新 更多