TensorLy中的Kronecker产品源代码



我正在努力理解在TensorLy中实现的张量的Kronecker产品的代码。以下是代码:

def kron(self, a, b):
"""Kronecker product of two tensors.
Parameters
----------
a, b : tensor
The tensors to compute the kronecker product of.
Returns
-------
tensor
"""
s1, s2 = self.shape(a)
s3, s4 = self.shape(b)
a = self.reshape(a, (s1, 1, s2, 1))
b = self.reshape(b, (1, s3, 1, s4))
return self.reshape(a * b, (s1 * s3, s2 * s4))

我知道self.shape(a)将给出张量a的形状(行、列、切片(。因此,我们在s1s2中取a的形状,在s3s4中取b的形状。

a = self.reshape(a, (s1, 1, s2, 1))重塑了张量"a",但我发现很难理解什么是(s1, 1, s2, 1),我们为什么要这样做?CCD_ 11也是如此。此外,我们为什么要这样做self.reshape(a * b, (s1 * s3, s2 * s4))?。

这似乎是一个非常开放的问题,但我刚刚开始,我很乐意得到帮助!

这是使用广播的一个相当常见的技巧。将单位尺寸插入到ab中,这样会发生以下情况:

  1. 在第一个轴中,b被复制s1次,以与a的每一行相匹配
  2. 在第二轴中,a被复制s3次,以与b的每一行相匹配
  3. 在第三轴中,b被复制s2次,以与a的每列相匹配
  4. 在第四轴中,a被复制s4次,以与b的每列相匹配

当你进行乘法运算时,你会得到每个元素组合的4D乘积。元素result[i, j, m, n]来自a[i, m] * b[j, n]。最终的整形采用内存中的相同数据,并在不重新排列数据的情况下组合前两个和后两个轴。

让我们看一个简单的例子:

a = [[1, 2, 3],
[2, 3, 4],
[3, 4, 5]]
b = [[6, 7]]

形状从(3, 3)(1, 2)改变为(3, 1, 3, 1)(1, 1, 1, 2)。这不会改变内存中的布局,因此a变为

[[[[1], [2], [3]]],
[[[2], [3], [4]]],
[[[3], [4], [5]]]]

b变为

[[[[6, 7]]]]

结果将被成形为(3, 1, 3, 2),看起来像这样:

[[[[1*6, 1*7], [2*6, 2*7], [3*6, 3*7]]],
[[[2*6, 2*7], [3*6, 3*7], [4*6, 4*7]]],
[[[3*6, 3*7], [4*6, 4*7], [5*6, 5*7]]]]

当您将其重塑为最终结果时,内存布局保持不变,但形状更改为(3*1, 3*2):

[[1*6, 1*7, 2*6, 2*7, 3*6, 3*7],
[2*6, 2*7, 3*6, 3*7, 4*6, 4*7],
[3*6, 3*7, 4*6, 4*7, 5*6, 5*7]]

瞧,看看ab的Kronecker乘积。

相关内容

  • 没有找到相关文章

最新更新