英文:
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论