Neural network 理解卷积层中的特征映射(PyTorch)

Neural network 理解卷积层中的特征映射(PyTorch),neural-network,pytorch,Neural Network,Pytorch,我在MNIST的鉴别器网络中得到了这段代码: nn.Conv2d(1, 64, 4, 2, 1), 据我所知,有1个输入通道(MNIST图像),然后我们以2的步幅对图像应用4x4内核,以生成64个特征映射。这是否意味着我们在这一层实际上有64个内核?因为为了得到64个不同的特征映射,我们需要64个单独的内核来对图像进行卷积 然后在重新计算之后,我们有另一个卷积: nn.Conv2d(64, 128, 4, 2, 1), 我们如何从64到128?根据我对第一个示例的理解,我们有64个独立的内核

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

nn.Conv2d(1, 64, 4, 2, 1),
据我所知,有1个输入通道(MNIST图像),然后我们以2的步幅对图像应用4x4内核,以生成64个特征映射。这是否意味着我们在这一层实际上有64个内核?因为为了得到64个不同的特征映射,我们需要64个单独的内核来对图像进行卷积

然后在重新计算之后,我们有另一个卷积:

nn.Conv2d(64, 128, 4, 2, 1),
我们如何从64到128?根据我对第一个示例的理解,我们有64个独立的内核,可以生成64个独立的特征映射。但这里我们从64个要素地图到128个要素地图?这是否意味着我们只有两个内核


我希望有人能对我的理解是否正确有所启发

您在第一个示例中的理解是正确的,您有64个不同的内核来生成64个不同的特征映射


在第二个示例中,由于输入通道的数量不是一个,因此仍然有与输出特征映射的数量相同的“多”内核(因此128个),每个内核都在输入特征映射的线性组合上进行训练。因此,在您的情况下,这些内核中的每一个都有4x4x64个可训练权重。

所有输入通道都通过卷积滤波器(内核)连接到每个输出通道(默认情况下,如果
group=1
),每个输出通道一个。不过,每个内核对于每个输入通道都有子内核

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

下面是一个简单的示例,其中一个conv层取自:

以及我在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.]]]])

你被“群卷积”弄糊涂了,谢谢你的回复。我没有意识到内核在卷上卷积。