【问题标题】:`*** RuntimeError: mat1 dim 1 must match mat2 dim 0` whenever I run model(images)`*** RuntimeError: mat1 dim 1 must match mat2 dim 0` 每当我运行模型时(图片)
【发布时间】:2021-02-28 05:50:12
【问题描述】:
    def __init__(self):
        super().__init__()

        self.conv = nn.Sequential(
            nn.Conv2d(1, 64, kernel_size=5, stride=2, bias=False),
            nn.BatchNorm2d(64),
            nn.ReLU(),

            nn.Conv2d(64, 64, kernel_size=3, stride=2, bias=False),
            nn.BatchNorm2d(64),
            nn.ReLU(),
            
            nn.Conv2d(64, 64, kernel_size=3, stride=2, bias=False),
            nn.BatchNorm2d(64),
  
        )

我该如何处理这个错误?我认为错误在于 self.fc,但我不能说如何解决它。

【问题讨论】:

    标签: pytorch conv-neural-network


    【解决方案1】:

    我遇到了同样的问题,但是我已经通过使用一批 32 和张量大小为 [3, 32, 32] 的图像和模型上的以下配置来解决它。我正在使用带有 9 个 CNN 的 ResNet 并寻找 4 个输出。

    transform = transforms.Compose([transforms.Resize((32, 32)), transforms.ToTensor()])
    
    def conv_block(in_channels, out_channels, pool=False):
        layers = [nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1), 
                  nn.BatchNorm2d(out_channels), 
                  nn.ReLU(inplace=True)]
        if pool: layers.append(nn.MaxPool2d(2))
        return nn.Sequential(*layers)
    class ResNet9(ImageClassificationBase):
        def __init__(self, in_channels, num_classes):
            super().__init__()
            
            self.conv1 = conv_block(in_channels, 64)
            self.conv2 = conv_block(64, 128, pool=True)
            self.res1 = nn.Sequential(conv_block(128, 128), conv_block(128, 128))
            
            self.conv3 = conv_block(128, 256, pool=True)
            self.conv4 = conv_block(256, 512, pool=True)
            self.res2 = nn.Sequential(conv_block(512, 512), conv_block(512, 512))
            
            self.classifier = nn.Sequential(nn.MaxPool2d(4), 
                                            nn.Flatten(), 
                                            nn.Dropout(0.2),
                                            nn.Linear(512, num_classes))    
        def forward(self, xb):
            out = self.conv1(xb)
            out = self.conv2(out)
            out = self.res1(out) + out
            out = self.conv3(out)
            out = self.conv4(out)
            out = self.res2(out) + out
            out = self.classifier(out)
            return out
    

    【讨论】:

      【解决方案2】:

      self.conv(x) 的输出形状为 torch.Size([32, 64, 2, 2]):32*64*2*2= 8192(这相当于 (self.conv_out_size)。全连接层的输入需要一个单维向量,即您需要在传递到之前将其展平前向函数中的全连接层。

      class Network():
          ...
          def foward():
          ...
              conv_out = self.conv(x)
              print(conv_out.shape)
              conv_out = conv_out.view(-1, 32*64*2*2)
              print(conv_out.shape)
              x = self.fc(conv_out)
              return x
      

      输出

      torch.Size([32, 64, 2, 2])
      torch.Size([1, 8192])
      

      编辑:

      我认为你使用 self._get_conv_out 函数错误。

      应该是

          def _get_conv_out(self, shape):
              output = self.conv(torch.zeros(1, *shape)) # not (32, *size)
              return int(numpy.prod(output.size()))
      

      那么,在前向传球中,你可以使用

              conv_out = self.conv(x)
              # flatten the output of conv layers
              conv_out = conv_out.view(conv_out.size(0), -1)
              x = self.fc(conv_out)
      

      对于(32, 1, 110, 110) 的输入,输出应为torch.Size([32, 2])

      【讨论】:

      • 展平后应该可以正常工作,输入大小是多少(我假设它是 32、1、110、110)?
      • 它可以在 google colab (torch 1.7.0) 上运行,我不确定为什么它不能在你的系统上运行。
      • 好的,我知道了!
      • 输入形状 (32, 1, 110, 110) 是您要传递给模型的张量,对吗?对应(batch_size, channel, height, width)
      • 我所做的编辑可以处理任何批量大小:1) 更改 _get_conv_out 函数和 2) 使用 (conv_out.size(0), -1) 在前向函数中展平。
      猜你喜欢
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 2021-04-09
      • 2021-08-02
      • 2021-10-12
      • 2018-10-05
      • 1970-01-01
      相关资源
      最近更新 更多