【发布时间】:2021-01-03 02:21:24
【问题描述】:
我有兴趣应用一个只有 HxW 参数的卷积核,其中 (H, W) 是核大小。内核仍然像普通卷积一样具有 CxHxW 维度,但参数在通道维度中是恒定的。
PyTorch 中是否有内置选项?
【问题讨论】:
-
@Ivan 不,它没有。我知道我想做什么(我不是在征求关于这是否明智的建议)。只是在寻找一个潜在的选项,它可以让我不必制作自定义图层
标签: pytorch
我有兴趣应用一个只有 HxW 参数的卷积核,其中 (H, W) 是核大小。内核仍然像普通卷积一样具有 CxHxW 维度,但参数在通道维度中是恒定的。
PyTorch 中是否有内置选项?
【问题讨论】:
标签: pytorch
这相当于具有一维(求和)输入的卷积核。您可以在数学上验证这一点(只需考虑权重)。我们也可以用代码来验证,所以如果你真的想这样做,你可以使用它。
import torch
import torch.nn as nn
# Normal conv
normal_conv = nn.Conv2d(1, 2, kernel_size=1)
# We can artificially repeat the weight along the channel dimension -> constant depthwise
repeated_conv = nn.Conv2d(6, 2, kernel_size=1)
repeated_conv.weight.data = normal_conv.weight.data.expand(-1, 6, -1, -1)
repeated_conv.bias.data = normal_conv.bias.data
data = torch.randn(1, 6, 3, 3)
# same result
print(repeated_conv(data))
print(normal_conv(data.sum(1, keepdim=True)))
因此,您不需要自定义图层。只需创建一个输入通道数 = 1 的卷积,并将输入在通道维度上求和,然后再将其输入层。
更新:向后通过测试:
data1 = torch.randn(1, 6, 3, 3)
data2 = data1.clone()
data1.requires_grad = True
data2.requires_grad = True
repeated_conv(data1).mean().backward()
normal_conv(data2.sum(1, keepdim=True)).mean().backward()
print(data1.grad, repeated_conv.weight.grad.sum(1))
print(data2.grad, normal_conv.weight.grad)
【讨论】:
data 作为输入,使用repeated_conv 和normal_conv 进行反向传递,您将获得不同的渐变。这 6 层是从 normal_conv 中的唯一层复制而来的,但激活似乎是分开的。所以你最好使用带有总和输入的单层 Conv1d。
sum+normal_conv。 repeated_conv 只是用来验证两者是否相等。