如何计算线性层的 pytorch 尺寸?



在 PyTorch 教程中,构建的网络是

Net(
(conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
(conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
(fc1): Linear(in_features=400, out_features=120, bias=True)
(fc2): Linear(in_features=120, out_features=84, bias=True)
(fc3): Linear(in_features=84, out_features=10, bias=True)
)

并用于处理尺寸为1x32x32的图像。他们提到,网络不能用于不同大小的图像。

这两个卷积层似乎允许任意数量的特征,因此线性层似乎与将32x32带入最终特征有关10

我真的不明白,12084的数字是如何选择的,以及为什么结果与输入维度匹配。

当我尝试构建一个类似的网络时,我实际上遇到了数据维度的问题。

例如,当我使用更简单的网络时:

Net(
(conv1): Conv2d(3, 8, kernel_size=(5, 5), stride=(1, 1))
(conv2): Conv2d(8, 16, kernel_size=(5, 5), stride=(1, 1))
(fc1): Linear(in_features=400, out_features=3, bias=True)
)

对于大小为3x1200x800的输入,我收到错误消息:

RuntimeError: size mismatch, m1: [1 x 936144], m2: [400 x 3] at /pytorch/aten/src/TH/generic/THTensorMath.cpp:940

936144的数字从何而来,我需要如何设计网络,以使尺寸匹配?

关键步骤是在最后一个卷积和第一个Linear块之间。Conv2d输出形状为[batch_size, n_features_conv, height, width]的张量,而Linear期望[batch_size, n_features_lin]。要使两者对齐,您需要将 3 个维度[n_features_conv, height, width]"堆叠"成一个[n_features_lin]。如下,一定是那个n_features_lin == n_features_conv * height * width.在原始代码中,这种"堆叠"是通过

x = x.view(-1, self.num_flat_features(x))

如果你检查num_flat_features它只是计算这个n_features_conv * height * width产品。换句话说,您的第一个 conv 必须具有num_flat_features(x)输入特征,其中x是从前面的卷积中检索到的张量。但是我们需要提前计算这个值,这样我们才能在第一时间初始化网络......

计算是从逐个检查操作开始的。

  1. 输入为 32x32
  2. 我们在没有填充的情况下进行 5x5 卷积,因此每边损失 2 个像素,我们下降到 28x28
  3. 我们使用 2x2 的感受野进行最大池化,我们将每个维度减少一半,降至 14x14
  4. 我们
  5. 做另一个没有填充的 5x5 卷积,我们下降到 10x10
  6. 我们
  7. 做另一个最大池,我们下降到 5x5

这个 5x5 就是您在教程中看到self.fc1 = nn.Linear(16 * 5 * 5, 120)的原因.从 32x32 图像开始时,它n_features_conv * height * width。如果要使用不同的输入大小,则必须重做上述计算并相应地调整第一个Linear图层。

对于进一步的操作,它只是一个矩阵乘法链(这就是Linear所做的)。因此,唯一的规则是前Linearn_features_out与下一个n_features_in匹配。值 120 和 84 完全是任意的,尽管它们可能是作者选择的,以便生成的网络表现良好。

最新更新