我正在尝试训练CNN使用Conv2d
,Maxpool
和Linear
层对Fashion-MNIST
数据中的图像进行分类。我遇到了下面提到的代码,nn.Linear
层中有in_features = 12*4*4
。
我能否获得有关如何为 nn 选择in_features
参数的帮助。线性层?
class Network(nn.Module):
def __init__(self):
super(Network, self).__init__()
self.conv1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5)
self.conv2 = nn.Conv2d(in_channels=6, out_channels=12, kernel_size=5)
self.fc1 = nn.Linear(in_features=12*4*4, out_features=120)
self.fc2 = nn.Linear(in_features=120, out_features=60)
self.out = nn.Linear(in_features=60, out_features=10)
Fashion-MNIST
数据集中的每个示例都是28 x 28
灰度图像。
- 输入
28 x 28
- 我们做一个没有填充(自
default padding=0
以来(和stride=1(by default)
的5 x 5
卷积,所以我们在每边损失2
像素,我们下降到24 x 24
,即(28-5(/1 + 1 - 然后,我们使用
2 x 2
感受野执行最大池化操作,我们将每个维度切成两半,精确到12 x 12
- 我们再次做另一个没有
padding
和stride=1
5 x 5
卷积,我们下降到8 x 8
,即(12-5(/1 + 1
然后,我们 - 执行另一个最大池操作,我们下降到
4 x 4
这就是为什么,self.fc1 = nn.Linear(in_features=12*4*4, out_features=120)
.基本上,n_features_conv * height * width
,其中高度和宽度分别4
,n_features_conv
与位于其上方的conv2D
层的out_channels
相同。
请注意,如果更改输入图像的大小,则必须执行上述计算并相应地调整第一个Linear
图层。
希望对您有所帮助!
如果CNN最终有fc层,首先你必须决定输入大小。接下来,您有三个选项:
-
自己算一算。计算张量大小在经过不同的卷积池层时如何变化。
-
只需输入一个您通过初始层固定大小的随机张量。然后查看输出的大小 (
tensor.size()
(。在您给出的示例中,它将是(torch.Size([12, 4, 4])
(。 -
使用类似 tsalib 的东西来处理后台调整大小。
我个人更喜欢方法 2,因为它快速、准确且不需要任何第三方库。