【问题标题】:How to input the image with the size 4x4 and replace the Fully Connected Layers using the Convolution Layers?如何输入大小为 4x4 的图像并使用卷积层替换全连接层?
【发布时间】:2022-01-28 00:16:26
【问题描述】:

我是 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 的图像并使用卷积层替换全连接层?

【问题讨论】:

    标签: python deep-learning pytorch


    【解决方案1】:

    您只需要按照 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。

    【讨论】:

    • 这似乎有效,但有没有办法在torch.tensor() 函数中获取图像的输入而不是随机输入?
    • 是的,您可以像创建 2x2 张量一样手动创建 1x1x4x4 张量。
    • 是的,你说得对,但不确定它是如何为 4x4 创建的,你能告诉我怎么做吗?
    • @Zani123 只需在上面打印inputs = torch.randn(1, 1, 4, 4); print(inputs),您就会看到确切的方式。 tensor([[[[-0.8225, 0.7312, 1.6591, -0.7173], [-0.0793, 1.3285, 0.5713, -0.3532], [-0.4671, 0.6072, 1.7958, -0.6471], [ 1.4627, 0.2415, -0.2369, 0.7092]]]])
    猜你喜欢
    • 2016-05-17
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 2019-12-11
    • 1970-01-01
    • 2017-07-30
    • 2019-05-03
    相关资源
    最近更新 更多