记录使用pytorch过程中踩过的坑之全连接层

在进行一篇文章的网络结构复现时,其网络结构有一部分是vgg结构。在使用tensorboard对整体网络结构进行可视化的时候发现vgg结构的FC层疯狂报错。先贴出源码:

        '''
        这是网络设置部份
        '''
        self.maxpool = nn.MaxPool2d(2, 2)
        # conv1
        self.conv1_1 = nn.Conv2d(2, 64, 3, padding=1)
        
        
        # conv2
        self.conv2_1 = nn.Conv2d(64, 128, 3, padding=1)
        
        
        # conv3
        self.conv3_1 = nn.Conv2d(128, 256, 3, padding=1)
        self.conv3_2 = nn.Conv2d(256, 256, 3, padding=1)
        
        
        # conv4
        self.conv4_1 = nn.Conv2d(256, 512, 3, padding=1)
        self.conv4_2 = nn.Conv2d(512, 512, 3, padding=1)
        
        
        # conv5
        self.conv5_1 = nn.Conv2d(512, 512, 3, padding=1)
        self.conv5_2 = nn.Conv2d(512, 512, 3, padding=1)
       
        self.dropout = nn.Dropout2d(p=0.5,inplace=True)
        
        # fc
        self.fc1 = nn.Linear(512 * 4 * 4, 1024)
        self.fc2 = nn.Linear(1024, 1024)
        '''
        这是网络的forward部份
        '''
        x = self.maxpool(F.leaky_relu(self.conv1_1(x)))
        x = self.maxpool(F.leaky_relu(self.conv2_1(x)))
        x = self.maxpool(F.leaky_relu(self.conv3_2(F.leaky_relu(self.conv3_1(x)))))
        x = self.maxpool(F.leaky_relu(self.conv4_2(F.leaky_relu(self.conv4_1(x)))))
        x = self.maxpool(F.leaky_relu(self.conv5_2(F.leaky_relu(self.conv5_1(x)))))
        x = self.dropout(x)
        x = F.leaky_relu(self.fc1(x))
        x = F.leaky_relu(self.fc2(x))

tensorboard可视化结构部份为:

if __name__ == '__main__':        
   output = t.rand(1,2,128,128)       
   model = RDANet()
   with SummaryWriter(comment='RDANet')  as w:
       w.add_graph(model, output)

       从这可以看出我的网络结构input为128 * 128 * 2的矩阵。在此处另有的一坑就是需要对conv2d层设置padding=1(因为kernel_size=3所以填1),不然的话每一个conv后原矩阵的WH均会变小。具体计算见pytorch官网。而带来的影响就是你在计算池化后的WH时会惊讶的发现和你所设想的不太一样。也因此会带来一系列的报错。
       接下来就进入了全连接层的大坑了。在我的想法中在进入第一个FC层时输出应该是 [1,2014] ,因为在dropout层之后x.size[1,512,4,4] ,因此若想FC层输出为 [1,2014] 的话FC层应该为 (512 * 512 * 4,2014) ,然而你会发现报错为m1=[2014 * 4], m2=[8196 * 2014]。从这个报错能看出来,pytorch将输入的前三参数合并,因此导致了两者维度不一致。所以解决方案很简单

  x = self.maxpool(F.leaky_relu(self.conv1_1(x)))
        x = self.maxpool(F.leaky_relu(self.conv2_1(x)))
        x = self.maxpool(F.leaky_relu(self.conv3_2(F.leaky_relu(self.conv3_1(x)))))
        x = self.maxpool(F.leaky_relu(self.conv4_2(F.leaky_relu(self.conv4_1(x)))))
        x = self.maxpool(F.leaky_relu(self.conv5_2(F.leaky_relu(self.conv5_1(x)))))
        x = self.dropout(x)
        #加入这一段
        x = x.view(x.size(0), 512 * 4 * 4)
        
        x = F.leaky_relu(self.fc1(x))
        x = F.leaky_relu(self.fc2(x))
        x = np.array(x).reshape(self.image_size[0]/2,self.image_size[1]/2)

在此处我也曾加过x = x.view(-1, 512 * 4 * 4),然而输出还是为x.size()还是为[1,512,4,4]这就使我非常困扰。因此最终解决方案还是为x = x.view(x.size(0), 512 * 4 * 4) 这样x.size()就为 [1,8196],这样经过FC层之后输出就为 [1,2014] 这样输出就正确了。

你可能感兴趣的:(深度学习)