我已经在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个特征图?这是否意味着我们只有两个内核?
我希望有人能阐明我的理解是否正确!
答案 0 :(得分:1)
您对第一个示例的理解是正确的,您有64个不同的内核来生成64个不同的特征图。
在第二个示例的情况下,因此输入通道的数量不等于一个,您仍然拥有“很多”内核作为输出特征图的数量(因此为128),每个特征图都是根据输出特征图的线性组合进行训练的。输入要素图。因此,在您的情况下,这些内核中的每个内核将具有4x4x64的可训练权重。
答案 1 :(得分:0)
通过过滤器(内核)的卷积将所有输入通道连接到每个输出通道(默认情况下为group = 1
-每个输出通道一个。每个内核都有每个输入通道的子内核。
因此,在第一层中,您有in_channels = 1
和out_channels = 64
,这意味着有64个内核(和子内核)。在第二层中,您有in_channels = 64
和out_channels = 128
,这意味着有128个内核,每个内核具有64 * 128个子内核。
下面是一个简单的示例,它是从cs231n提取的一个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.]]]])