torch.Sequential 中尺寸不兼容

问题描述 投票:0回答:1

我正在尝试在尺寸为

(batch_size, 1, 28, 28)
的输入(图像)上使用 pytorch 在 Python 中实现卷积神经网络。换句话说,我有 28x28 的图像将提供给我的模型。

为此,为了获得正确的尺寸,我做了以下操作:

x = torch.zeros(64, 1, 28, 28)

layer_0 = nn.Conv2d(1, 16, 3, stride=2, padding=1)
out_layer_0 = layer_0(x)
print(out_layer_0.shape)

layer_1 = nn.MaxPool2d(2)
out_layer_1 = layer_1(out_layer_0)
print(out_layer_1.shape)

layer_2 = nn.BatchNorm2d(16)
out_layer_2 = layer_2(out_layer_1)
print(out_layer_2.shape)

layer_3 = nn.Dropout2d(0.2)
out_layer_3 = layer_2(out_layer_2)
print(out_layer_3.shape)

layer_4 = nn.Conv2d(16, 16, 3, stride=1)
out_layer_4 = layer_2(out_layer_3)
print(out_layer_4.shape)

layer_5 = nn.MaxPool2d(2)
out_layer_5 = layer_5(out_layer_4)
print(out_layer_5.shape)

layer_6 = nn.Flatten()
out_layer_6 = layer_6(out_layer_5)
print(f"L6 out: {out_layer_6.shape}")

layer_7 = nn.Linear(144, 200)
out_layer_7 = layer_7(out_layer_6)
print(out_layer_7.shape)

layer_8 = nn.Dropout(0.2)
out_layer_8 = layer_8(out_layer_7)
print(out_layer_8.shape)

layer_9 = nn.ReLU()
out_layer_9 = layer_9(out_layer_8)
print(out_layer_9.shape)

layer_10 = nn.Linear(200, 10)
out_layer_10 = layer_10(out_layer_9)
print(out_layer_10.shape)

请注意,第 6 层输出尺寸为 64 x 144 的张量,因此,下一层(线性层)应采用尺寸为 144 的张量。至少这是我的理解。

计算出尺寸后,我为模型创建了以下类:

class CNN(nn.Module):
    def __init__(self):
        super().__init__()
        
        self.cnn = nn.Sequential(
            nn.Conv2d(1, 16, 3, stride=2, padding=1),
            nn.MaxPool2d(2),
            nn.BatchNorm2d(16),
            nn.Dropout2d(0.2),
            nn.Conv2d(16, 16, 3, stride=1),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(144, 200),
            nn.Dropout(0.2),
            nn.ReLU(),
            nn.Linear(200, 10)
        )

    def forward(self, x):
        out = self.cnn(x)
        return out


x = torch.zeros(128, 1, 28, 28)
myCnn = CNN()
out = myCnn(x)

奇怪的事情 - 这是我第一次遇到这种情况 - 是我收到以下错误,这表明该线性层的输入应该是 64 而不是 144。我在这里做错了什么吗?

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[26], line 26
     24 x = torch.zeros(64, 1, 28, 28)
     25 myCnn = CNN()
---> 26 out = myCnn(x)

File ~\anaconda3\envs\ForDataAnalytics\lib\site-packages\torch\nn\modules\module.py:1102, in Module._call_impl(self, *input, **kwargs)
   1098 # If we don't have any hooks, we want to skip the rest of the logic in
   1099 # this function, and just call forward.
   1100 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1101         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1102     return forward_call(*input, **kwargs)
   1103 # Do not call functions when jit is used
   1104 full_backward_hooks, non_full_backward_hooks = [], []

Cell In[26], line 20, in CNN.forward(self, x)
     19 def forward(self, x):
---> 20     out = self.cnn(x)
     21     return out

File ~\anaconda3\envs\ForDataAnalytics\lib\site-packages\torch\nn\modules\module.py:1102, in Module._call_impl(self, *input, **kwargs)
   1098 # If we don't have any hooks, we want to skip the rest of the logic in
   1099 # this function, and just call forward.
   1100 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1101         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1102     return forward_call(*input, **kwargs)
   1103 # Do not call functions when jit is used
   1104 full_backward_hooks, non_full_backward_hooks = [], []

File ~\anaconda3\envs\ForDataAnalytics\lib\site-packages\torch\nn\modules\container.py:141, in Sequential.forward(self, input)
    139 def forward(self, input):
    140     for module in self:
--> 141         input = module(input)
    142     return input

File ~\anaconda3\envs\ForDataAnalytics\lib\site-packages\torch\nn\modules\module.py:1102, in Module._call_impl(self, *input, **kwargs)
   1098 # If we don't have any hooks, we want to skip the rest of the logic in
   1099 # this function, and just call forward.
   1100 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1101         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1102     return forward_call(*input, **kwargs)
   1103 # Do not call functions when jit is used
   1104 full_backward_hooks, non_full_backward_hooks = [], []

File ~\anaconda3\envs\ForDataAnalytics\lib\site-packages\torch\nn\modules\linear.py:103, in Linear.forward(self, input)
    102 def forward(self, input: Tensor) -> Tensor:
--> 103     return F.linear(input, self.weight, self.bias)

File ~\anaconda3\envs\ForDataAnalytics\lib\site-packages\torch\nn\functional.py:1848, in linear(input, weight, bias)
   1846 if has_torch_function_variadic(input, weight, bias):
   1847     return handle_torch_function(linear, (input, weight, bias), input, weight, bias=bias)
-> 1848 return torch._C._nn.linear(input, weight, bias)

RuntimeError: mat1 and mat2 shapes cannot be multiplied (64x64 and 144x200)
python python-3.x machine-learning pytorch conv-neural-network
1个回答
0
投票

您期望的维度与网络中实际发生的情况似乎不匹配。我们来分析一下这个问题:

在前向传递中,您正确计算了卷积层的输出,从而得到大小为(batch_size,144)的张量,其中batch_size是输入批次中的样本数。

但是,错误消息表明在尝试执行从展平卷积输出到第一个线性层的线性变换时存在形状不匹配。它表明输入张量大小为 (64, 144),但您的线性层期望输入大小为 (64, 64)。

出现这种差异是因为批量大小为 64,但线性层的预期输入大小为 144。这种尺寸差异导致了 RuntimeError

要解决此问题,您需要调整 CNN 模型中第一个线性层的输入大小,以匹配卷积层的实际输出大小。由于卷积层的输出大小为 (batch_size, 144),因此线性层的输入大小应为 144

© www.soinside.com 2019 - 2024. All rights reserved.