了解卷积层(PyTorch)中的特征图

时间:2019-02-27 11:37:47

标签: neural-network pytorch

我已经在MNIST的鉴别器网络中获得了这段代码:

nn.Conv2d(1, 64, 4, 2, 1),

根据我的理解,有1个输入通道(MNIST图像),然后我们以2的步幅将4x4内核应用于图像,以生成64个特征图。这是否意味着我们实际上在这一层有64个内核?因为要获得64个不同的特征图,我们需要64个独立的内核才能在图像上进行卷积?

然后在ReLu之后,我们又有了一个卷积:

nn.Conv2d(64, 128, 4, 2, 1),

我们如何从64变为128?根据我对第一个示例的理解,我们有64个独立的内核,它们可以产生64个独立的特征图。但是在这里,我们从64个特征图变为128个特征图?这是否意味着我们只有两个内核?

我希望有人能阐明我的理解是否正确!

2 个答案:

答案 0 :(得分:1)

您对第一个示例的理解是正确的,您有64个不同的内核来生成64个不同的特征图。

在第二个示例的情况下,因此输入通道的数量不等于一个,您仍然拥有“很多”内核作为输出特征图的数量(因此为128),每个特征图都是根据输出特征图的线性组合进行训练的。输入要素图。因此,在您的情况下,这些内核中的每个内核将具有4x4x64的可训练权重。

答案 1 :(得分:0)

通过过滤器(内核)的卷积将所有输入通道连接到每个输出通道(默认情况下为group = 1 -每个输出通道一个。每个内核都有每个输入通道的子内核。

因此,在第一层中,您有in_channels = 1out_channels = 64,这意味着有64个内核(和子内核)。在第二层中,您有in_channels = 64out_channels = 128,这意味着有128个内核,每个内核具有64 * 128个子内核。

下面是一个简单的示例,它是从cs231n提取的一个conv层进行说明的:

enter image description here

我在Pytorch中的实现

import torch
from torch import nn


cnn = nn.Conv2d(in_channels=3, out_channels=2, kernel_size=3,
                stride=2, padding=1, bias=True, groups=1)


w0 = torch.FloatTensor([[[-1, -1,  0],
                         [ 1,  1,  1],
                         [ 1,  1,  0]],

                        [[ 1,  1, -1],
                         [ 0,  0,  0],
                         [ 1,  1, -1]],

                        [[ 0, -1,  0],
                         [-1,  0, -1],
                         [ 1,  0,  1]]])

b0 = torch.FloatTensor([1])

w1 = torch.FloatTensor([[[-1,  0,  0],
                         [ 1,  1,  1],
                         [-1, -1,  0]],

                        [[ 1, -1, -1],
                         [-1,  1, -1],
                         [ 1, -1,  0]],

                        [[ 1, -1,  0],
                         [ 0,  1,  1],
                         [ 1,  0,  1]]])

b1 = torch.FloatTensor([0]) 


cnn.weight = torch.nn.Parameter(torch.stack((w0, w1), 0))
cnn.bias = torch.nn.Parameter(torch.cat((b0, b1), 0))

inpt = torch.FloatTensor([[[ 1, 2, 0, 1, 2],
                           [ 1, 0, 2, 2, 0],
                           [ 2, 0, 0, 2, 2],
                           [ 0, 0, 2, 2, 0],
                           [ 2, 2, 2, 1, 2]],

                          [[ 2, 0, 0, 1, 1],
                           [ 1, 0, 2, 1, 2],
                           [ 2, 0, 2, 2, 1],
                           [ 0, 2, 0, 0, 1],
                           [ 1, 2, 1, 2, 0]],

                          [[ 0, 0, 2, 1, 2],
                           [ 0, 1, 0, 2, 0],
                           [ 1, 1, 0, 0, 2],
                           [ 0, 0, 0, 1, 1],
                           [ 0, 1, 2, 0, 2]]])

cnn(inpt.unsqueeze(0))

输出:

tensor([[[[ 7.,  9., 10.],
          [ 0.,  6., 10.],
          [ 2.,  5.,  2.]],

         [[ 4.,  4.,  4.],
          [ 5.,  1.,  2.],
          [ 2.,  6.,  0.]]]])