如何在PyTorch中的许多转换层之后指定平坦化层的输入大小?

时间:2018-09-24 07:23:45

标签: python python-3.x pytorch

这是我的问题,我在CIFAR10数据集上做了一个小测试,如何在PyTorch中指定平整层的输入大小?如下所示,输入大小为16 * 5 * 5,但是我不知道如何计算,我想通过某个函数获取输入大小。有人可以在此Net类中编写一个简单的函数并解决这个问题吗?

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3,6,5)  
        self.conv2 = nn.Conv2d(6,16,5)

        # HERE , the input size is 16*5*5, but I don't know how to get it.
        self.fc1 = nn.Linear(16*5*5, 120)
        self.fc2 = nn.Linear(120,84)
        self.fc3 = nn.Linear(84,10)

    def forward(self, x):
        x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
        x = F.max_pool2d(F.relu(self.conv2(x)),2)
        x = x.view(x.size()[0],-1)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

5 个答案:

答案 0 :(得分:3)

Pytorch默认设置中没有“展平层”。您可以创建如下所示的类。干杯

class Flatten(nn.Module):
    def forward(self, input):
        return input.view(input.size(0), -1)


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.flatten   = Flatten()  ## describing the layer
        self.conv1 = nn.Conv2d(3,6,5)  
        self.conv2 = nn.Conv2d(6,16,5)

        # HERE , the input size is 16*5*5, but I don't know how to get it.
        self.fc1 = nn.Linear(16*5*5, 120)
        self.fc2 = nn.Linear(120,84)
        self.fc3 = nn.Linear(84,10)

    def forward(self, x):
        x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
        x = F.max_pool2d(F.relu(self.conv2(x)),2)
        #x = x.view(x.size()[0],-1)
        x = self.flatten(x)   ### using of flatten layer
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

答案 1 :(得分:0)

第一个FC层的输入大小取决于您输入的大小。 documentation告诉您给定输入的Conv2d图层的输出大小是多少,因此您只需要将该公式转换为函数即可。在您的情况下,如果您输入的图像是m×n,则您要查找的输入大小将为16 *(m-8)*(n-8)。

答案 2 :(得分:0)

我想这是pytorch教程的一些代码吧? 我遇到了同样的问题,Jens Petersen是正确的:完全连接(FC)层的输入大小取决于输入大小以及您在FC层之前对其执行的操作。在您的情况下,您忘记考虑最大池化步骤。 由于此网络构建为可接收32x32输入,因此第一转换层将输出6 *(32-3)*(32-3),在最大缓冲后6 * floor(29/2)* floor(29/2)= 6 * 14 *14。在第二个conv层+最大池化之后,我们的输出大小为16 * 5 * 5。

答案 3 :(得分:0)

只需回答以更新此帖子,Pytorch的1.3版中现在就有一个扁平层:https://pytorch.org/docs/stable/_modules/torch/nn/modules/flatten.html

此外,值得一提的是,如果您不能使用> = 1.3,并且“需要” CNN输出大小(例如,如果您有多个头部,那么大多数人确实会通过编程从虚拟输入中获取输出,例如:

    def get_flat_fts(self, input_shape, conv_net):
      f = conv_net(Variable(torch.ones(1,*input_shape)))
      return int(np.prod(f.size()[1:]))

答案 4 :(得分:0)

尽管它很旧,我会为将来的读者解答。 5x5是所有卷积和合并后的图像尺寸。在docs中,有一个公式可以计算出来: Hight_out =(身高+ 2 *填充-膨胀*(内核大小-1)-1)/步幅+1。宽度相同。 因此,您从32x32的图片开始。在第一个卷积层之后,由于内核大小(每侧损失2个像素),您获得了28x28的图像。合并后,您得到了14x14,因为它是一个跨度为2的2x2蒙版。然后,第二个卷积层为您提供了10x10的图像,最后,最后一个合并为5x5。然后乘以输出通道数:16。

我认为@trizard的答案很接近,但他误读了内核大小。