来自不同阵列的行跨行pytorch点产品

发布于 2025-01-21 07:22:57 字数 1392 浏览 3 评论 0原文

我正在尝试编码类似于变形金刚纸中的位置编码的内容。 为了这样做,我需要执行以下操作:

对于以下三个矩阵,我想在行级别上加入它们(即每个堆叠在一起的第一行,第二行,等等),然后应用点每个矩阵及其转置之间的产品,最后将它们弄平并堆叠在一起。我将在以下示例中澄清:

x = torch.tensor([[1,1,1,1],
                  [2,2,2,2],
                  [3,3,3,3]])
y = torch.tensor([[0,0,0,0],
                  [0,0,0,0],
                  [0,0,0,0]])
z = torch.tensor([[4,4,4,4],
                  [5,5,5,5],
                  [6,6,6,6]])

concat = torch.cat([x, y, z], dim=-1).view(-1, x.shape[-1])
print(concat)
 张量([[[1,1,1,1],
        [0,0,0,0],
        [4、4、4、4],
        [2,2,2,2],
        [0,0,0,0],
        [5,5,5,5],
        [3,3,3,3],
        [0,0,0,0],
        [6,6,6,6]])
 
# Here I get each three rows together, and then apply dot product, flatten, and stack them.
concat = torch.stack([
            torch.flatten(
                torch.matmul(
                    concat[i:i+3, :], # 3 is the number of tensors (x,y,z)
                    torch.transpose(concat[i:i+3, :], 0, 1))
                )
            for i in range(0, concat.shape[0], 3)
            ])

print(concat)
 张量([[[4,0,16,0,0,0,0,16,0,64],
        [16、0、40、0、0、0、0、40、0、100],
        [36,0,72,0,0,0,0,72,0,144]])
 

最后,我能够获得我想要的最后一个矩阵。我的问题是,是否有一种方法可以像在最后一步一样使用循环而无需使用循环?我希望一切都在张量中。

I am trying to code up something similar to the positional encoding in the transformers paper.
In order to do so I need to do the following:

For the following three matrices, I want to concatenate them at row level (i.e. the first row from each one stacked together, the second rows together, etc.), and then apply dot product between each matrix and its transpose, and finally, flatten them and stack them together. I'll clarify this in the following example:

x = torch.tensor([[1,1,1,1],
                  [2,2,2,2],
                  [3,3,3,3]])
y = torch.tensor([[0,0,0,0],
                  [0,0,0,0],
                  [0,0,0,0]])
z = torch.tensor([[4,4,4,4],
                  [5,5,5,5],
                  [6,6,6,6]])

concat = torch.cat([x, y, z], dim=-1).view(-1, x.shape[-1])
print(concat)
tensor([[1, 1, 1, 1],
        [0, 0, 0, 0],
        [4, 4, 4, 4],
        [2, 2, 2, 2],
        [0, 0, 0, 0],
        [5, 5, 5, 5],
        [3, 3, 3, 3],
        [0, 0, 0, 0],
        [6, 6, 6, 6]])
# Here I get each three rows together, and then apply dot product, flatten, and stack them.
concat = torch.stack([
            torch.flatten(
                torch.matmul(
                    concat[i:i+3, :], # 3 is the number of tensors (x,y,z)
                    torch.transpose(concat[i:i+3, :], 0, 1))
                )
            for i in range(0, concat.shape[0], 3)
            ])

print(concat)
tensor([[  4,   0,  16,   0,   0,   0,  16,   0,  64],
        [ 16,   0,  40,   0,   0,   0,  40,   0, 100],
        [ 36,   0,  72,   0,   0,   0,  72,   0, 144]])

Finally, I was able to get the final matrix that I want. My question is, is there a way to achieve this without using a loop as I did in the final step? I want everything to be in tensors.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

祁梦 2025-01-28 07:22:57

torch.einsum使matmul您想要的轴更容易。

c = torch.concat([x, y, z], dim=-1).reshape(-1, *x.shape)
torch.einsum('ijl,ikl->ikj', c, c).reshape(3, -1)

输出

tensor([[  4,   0,  16,   0,   0,   0,  16,   0,  64],
        [ 16,   0,  40,   0,   0,   0,  40,   0, 100],
        [ 36,   0,  72,   0,   0,   0,  72,   0, 144]])

torch.einsum makes it a bit easier to matmul the axes you want.

c = torch.concat([x, y, z], dim=-1).reshape(-1, *x.shape)
torch.einsum('ijl,ikl->ikj', c, c).reshape(3, -1)

Output

tensor([[  4,   0,  16,   0,   0,   0,  16,   0,  64],
        [ 16,   0,  40,   0,   0,   0,  40,   0, 100],
        [ 36,   0,  72,   0,   0,   0,  72,   0, 144]])
我早已燃尽 2025-01-28 07:22:57

您引入的循环只需要在那里即可获得数据的“切片列表”,这几乎与重塑数据相同。您基本上是在引入一个额外的维度,其中有3个条目。基本上是从形状[n,k][n,3,k]
对于直接与张量合作,您只需调用.Reshape即可达到相同的形状。之后,您使用的代码其余代码也几乎完全相同。由于尺寸的变化,必须稍微更改转置。

总而言之,您想要的是:

concat2 = concat.reshape((-1, 3, concat.shape[1]))
torch.flatten(
  torch.matmul(
    concat2, 
    concat2.transpose(1,2)
  ), 
  start_dim=1,
)

The loop you introduce only needs to be there to get a "list of slices" of the data, which is practically the same as reshaping it. You are basically introducing a additional dimension, in which there are 3 entries. Basically from shape [n, k] to [n, 3, k].
For working directly with tensors, you can just call .reshape to get to the same shape. After that, the rest of the code you use also works almost the exact same. The transpose has to be changed slightly, due to the change in dimensions.

All in all, what you want can be achieved with:

concat2 = concat.reshape((-1, 3, concat.shape[1]))
torch.flatten(
  torch.matmul(
    concat2, 
    concat2.transpose(1,2)
  ), 
  start_dim=1,
)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文