批次卷积 – 对于每个批次元素使用不同的权重

huangapple go评论58阅读模式
英文:

Batchwise convolutions – for each batch element a different weight

问题

给定形状为(32, 4, 16)的输入 x。需要对该输入应用一维卷积(conv1d)。请注意,有4个输入通道,每个通道的维度为16,批处理大小为32。假设要输出8个通道,因此weight的形状为(8, 4, 1)

总的来说,以下是代码:

batch_size = 32
input_channels = 4
output_channels = 8
dim = 16

x = torch.zeros(size=(batch_size, input_channels, dim))
weight = torch.rand(size=(output_channels, input_channels, 1))
y = F.conv1d(x, weight)

现在来回答您的问题:
与其对每个批次元素应用相同的权重,我想对每个批次元素应用不同的权重。换句话说,weight必须具有形状(32, 8, 4, 1)
我如何实现这种批处理卷积操作?

如果将weight分配为torch.rand(size=(batch_size, output_channels, input_channels, 1)),那么代码不起作用。
当然,存在一种基于for循环的简单解决方案。我正在寻找一种无需for循环的解决方案。

翻译部分结束,不包括问题回答。

英文:

Given an input x which has a shape of (32, 4, 16). To this input, a convolution (conv1d) shall be applied. Note that, there are 4 input channels. Each of these channels has a dimensionality of 16. The batch size is 32. In the following, it is assumed that the number of output channels shall be 8. Therefore, the weight has the shape (8, 4, 1)

Overall, we got the following code:

batch_size = 32
input_channels = 4
output_channels = 8
dim = 16

x = torch.zeros(size=(batch_size, input_channels, dim))
weight = torch.rand(size=(output_channels, input_channels, 1))
y = F.conv1d(x, weight)

Now to my question:
Instead of applying the same weight to each batch element, I want to apply to each batch element a different weight. In other words, the weight must have the shape (32, 8, 4, 1).
How I can implement this batchwise convolution operation?

If weight is assigned to torch.rand(size=(batch_size, output_channels, input_channels, 1)) then the code does not work.
Ofcourse there exists a simple solution which is based on a for-loop.
I am looking for a solution without a for-loop.

答案1

得分: 0

shape(1)Conv1d 与广播乘法和求和缩减相同。具体来说

# x.shape (32, 4, 16)
# weight.shape (8, 4, 1)

y = (x.unsqueeze(1) * weight.unsqueeze(0)).sum(dim=2)
# 等同于 y = F.conv1d(x, weight)
# 等同于 y = torch.einsum('bin,oin->bon', x, weight)

所以如果我们假设 weight 的形状是 (32, 8, 4, 1),那么我们就不需要在第一维上进行广播。

# x.shape (32, 4, 16)
# weight.shape (32, 8, 4, 1)

y = (x.unsqueeze(1) * weight).sum(dim=2)
# 等同于 y = torch.einsum('bin,boin->bon', x, weight)
英文:

Conv1d with a kernel of shape (1) is the same as broadcasted multiply with sum-reduction. Specifically

# x.shape (32, 4, 16)
# weight.shape (8, 4, 1)

y = (x.unsqueeze(1) * weight.unsqueeze(0)).sum(dim=2)
# equivalent to y = F.conv1d(x, weight)
# equivalent to y = torch.einsum('bin,oin->bon', x, weight)

So if we assume weight has shape (32, 8, 4, 1) then we just don't need to broadcast over the first dimension.

# x.shape (32, 4, 16)
# weight.shape (32, 8, 4, 1)

y = (x.unsqueeze(1) * weight).sum(dim=2)
# equivalent to y = torch.einsum('bin,boin->bon', x, weight)

huangapple
  • 本文由 发表于 2023年2月24日 00:28:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75547629.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定