如何输入 4x4 大小的图像并使用卷积层替换全连接层?

How to input the image with the size 4x4 and replace the Fully Connected Layers using the Convolution Layers?

我是 PyTorch 库的初学者,在一次练习中卡住了。 下面的代码适用于大小为 2x2 的输入图像。我正在尝试做与下面相同的事情,但输入图像的大小为 4x4。

代码:

import torch 

假设我们有一个 2x2 输入图像

inputs = torch.tensor([[[[1., 2.],
                         [3., 4.]]]])
inputs.shape

Output: torch.Size([1,1,2,2]

将 4 个输入特征映射到两个 2 个输出的全连接层计算如下:

fc = torch.nn.Linear(4, 2)

weights = torch.tensor([[1.1, 1.2, 1.3, 1.4],
                        [1.5, 1.6, 1.7, 1.8]])
bias = torch.tensor([1.9, 2.0])
fc.weight.data = weights
fc.bias.data = bias
torch.relu(fc(inputs.view(-1, 4)))

Output: torch.Size([2, 1, 2, 2])
Output: torch.Size([2])

如果我们使用内核大小与输入特征数组大小相同的卷积层,则获得相同的输出:

conv = torch.nn.Conv2d(in_channels=1,
                       out_channels=2,
                       kernel_size=inputs.squeeze(dim=(0)).squeeze(dim=(0)).size())
print(conv.weight.size())
print(conv.bias.size())

Output: torch.Size([2, 1, 2, 2])
Output: torch.Size([2])
conv.weight.data = weights.view(2, 1, 2, 2)
conv.bias.data = bias
torch.relu(conv(inputs))

Output: tensor([[[[14.9000]],

         [[19.0000]]]], grad_fn=<ReluBackward0>)

当我们将输入图像重塑为 num_inputs x 1 x 1 图像时,使用卷积层替换全连接层:

conv = torch.nn.Conv2d(in_channels=4,
                       out_channels=2,
                       kernel_size=(1, 1))

conv.weight.data = weights.view(2, 4, 1, 1)
conv.bias.data = bias
torch.relu(conv(inputs.view(1, 4, 1, 1)))

Output: tensor([[[[14.9000]],

         [[19.0000]]]], grad_fn=<ReluBackward0>)

那么基于这段代码如何输入一个大小为 4x4 的图像并使用卷积层替换全连接层?

您只需根据 4x4 更改输入的形状和重塑权重。

inputs = torch.randn(1, 1, 4, 4)
fc = torch.nn.Linear(16, 2)
torch.relu(fc(inputs.view(-1, 16)))

# output
tensor([[0.0000, 0.2525]], grad_fn=<ReluBackward0>)

现在,对于转换层

conv = torch.nn.Conv2d(in_channels=1,
                       out_channels=2,
                       kernel_size=inputs.squeeze(dim=(0)).squeeze(dim=(0)).size())
conv.weight.data = fc.weight.data.view(2, 1, 4, 4)
conv.bias.data = fc.bias.data
torch.relu(conv(inputs))

# output
tensor([[[[0.0000]],
         [[0.2525]]]], grad_fn=<ReluBackward0>)

如果不确定转换层参数是如何获取的,您可以阅读Converting FC layers to CONV layers