首页 > 解决方案 > 简单的卷积网络

问题描述

我是 pytorch 的新手,我希望你在我尝试设置的小网上点亮你的灯。


class PzConv2d(nn.Module):
    """ Convolution 2D Layer followed by PReLU activation
    """
    def __init__(self, n_in_channels, n_out_channels, **kwargs):
        super(PzConv2d, self).__init__()
        self.conv = nn.Conv2d(n_in_channels, n_out_channels, bias=True,
                            **kwargs)
        self.activ = nn.ReLU()

    def forward(self, x):
        x = self.conv(x)
        return self.activ(x)


class PzPool2d(nn.Module):
    """ Average Pooling Layer
    """
    def __init__(self, kernel_size, stride, padding=0):
        super(PzPool2d, self).__init__()
        self.pool = nn.AvgPool2d(kernel_size=kernel_size,
                                 stride=stride,
                                 padding=padding,
                                 ceil_mode=True,
                                 count_include_pad=False)

    def forward(self, x):
        return self.pool(x)

class PzFullyConnected(nn.Module):
    """ Dense or Fully Connected Layer followed by ReLU
    """
    def __init__(self, n_inputs, n_outputs, withrelu=True, **kwargs):
        super(PzFullyConnected, self).__init__()
        self.withrelu = withrelu
        self.linear = nn.Linear(n_inputs, n_outputs, bias=True)
        self.activ = nn.ReLU()

    def forward(self, x):
        x = self.linear(x)
        if self.withrelu:
            x = self.activ(x)
        return x


class NetCNN(nn.Module):
    def __init__(self,n_input_channels,debug=False):
        super(NetCNN, self).__init__()

        self.n_bins = 180
        self.debug = debug
        self.conv0 = PzConv2d(n_in_channels=n_input_channels,
                              n_out_channels=64,
                              kernel_size=5,padding=2)
        self.pool0 = PzPool2d(kernel_size=2,stride=2,padding=0)

        self.conv1 = PzConv2d(n_in_channels=64,
                              n_out_channels=92,
                              kernel_size=3,padding=2)
        self.pool1 = PzPool2d(kernel_size=2,stride=2,padding=0)

        self.conv2 = PzConv2d(n_in_channels=92,
                              n_out_channels=128,
                              kernel_size=3,padding=2)
        self.pool2 = PzPool2d(kernel_size=2,stride=2,padding=0)


        self.fc0 = PzFullyConnected(n_inputs=12800,n_outputs=1024)
        self.fc1 = PzFullyConnected(n_inputs=1024,n_outputs=self.n_bins)

    def num_flat_features(self, x):
        size = x.size()[1:]  # all dimensions except the batch dimension
        num_features = 1
        for s in size:
            num_features *= s
        return num_features

    def forward(self, x, dummy):
        # x:image tensor N_batch, Channels, Height, Width
        #    size N, Channels:=5 filtres, H,W = 64 pixels
        # dummy: is not used

        # stage 0 conv 64 x 5x5
        x = self.conv0(x)
        x = self.pool0(x)

        # stage 1 conv 92 x 3x3
        x = self.conv1(x)
        x = self.pool1(x)

        # stage 2 conv 128 x 3x3
        x = self.conv2(x)
        x = self.pool2(x)

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

        output = x


        return output

我已经检查了正向过程中中间“x”张量的尺寸是否良好(至少在我发送随机输入图像张量时)。但如果你看到一些奇怪的东西,请告诉我。

现在,我在 forward 方法中看到了带有 F."function" 序列的代码,而不是像我所做的那样声明不同的层。这有什么不同吗?

(请注意,我使用 F.cross_entropy 作为损失函数,所以我不会通过 SoftMax 结束可能的网络。)

谢谢。

标签: pytorchconv-neural-network

解决方案


正如您从 pytorch 文档中看到的那样,有“层”“功能”。您已经注意到它们非常相似,有区别:
层通常不仅仅是一个“功能”,它还包含可训练参数
因此,您可以F.conv2d(...)forward()函数中使用 a,但您必须手动提供(存储/更新)此卷积的权重/内核。另一方面,如果您使用的是nn.Conv2dpytorch,它会为您管理/存储/更新权重/内核。
有些层没有内部参数/缓冲区(例如nn.ReLUnn.Softmax等)因此您可以选择是否要为此操作设置“层”或仅在您的函数中调用适当的forward()函数。这是方便和习惯的问题,这取决于您。


推荐阅读