tensordot

paddle. tensordot ( x, y, axes=2, name=None ) [source]

This function computes a contraction, which sum the product of elements from two tensors along the given axes.

Parameters
  • x (Tensor) – The left tensor for contraction with data type float16 or float32 or float64.

  • y (Tensor) – The right tensor for contraction with the same data type as x.

  • axes (int|tuple|list|Tensor, optional) –

    The axes to contract for x and y, defaulted to integer 2.

    1. It could be a non-negative integer n, in which the function will sum over the last n axes of x and the first n axes of y in order.

    2. It could be a 1-d tuple or list with data type int, in which x and y will be contracted along the same given axes. For example, axes =[0, 1] applies contraction along the first two axes for x and the first two axes for y.

    3. It could be a tuple or list containing one or two 1-d tuple|list|Tensor with data type int. When containing one tuple|list|Tensor, the data in tuple|list|Tensor specified the same axes for x and y to contract. When containing two tuple|list|Tensor, the first will be applied to x and the second to y. When containing more than two tuple|list|Tensor, only the first two axis sequences will be used while the others will be ignored.

    4. It could be a tensor, in which the axes tensor will be translated to a python list and applied the same rules described above to determine the contraction axes. Note that the axes with Tensor type is ONLY available in Dygraph mode.

  • name (str, optional) – The default value is None. Normally there is no need for user to set this property. For more information, please refer to Name .

Returns

Output (Tensor), The contraction result with the same data type as x and y. In general, \(output.ndim = x.ndim + y.ndim - 2 \times n_{axes}\), where \(n_{axes}\) denotes the number of axes to be contracted.

Notes

  1. This function supports tensor broadcast, the size in the corresponding dimensions of x and y should be equal, or applies to the broadcast rules.

  2. This function also supports axes expansion, when the two given axis sequences for x and y are of different lengths, the shorter sequence will expand the same axes as the longer one at the end. For example, if axes =[[0, 1, 2, 3], [1, 0]], the axis sequence for x is [0, 1, 2, 3], while the corresponding axis sequences for y will be expanded from [1, 0] to [1, 0, 2, 3].

Examples

>>> import paddle

>>> data_type = 'float64'

>>> # For two 2-d tensor x and y, the case axes=0 is equivalent to outer product.
>>> # Note that tensordot supports empty axis sequence, so all the axes=0, axes=[], axes=[[]], and axes=[[],[]] are equivalent cases.
>>> x = paddle.arange(4, dtype=data_type).reshape([2, 2])
>>> y = paddle.arange(4, dtype=data_type).reshape([2, 2])
>>> z = paddle.tensordot(x, y, axes=0)
>>> print(z)
Tensor(shape=[2, 2, 2, 2], dtype=float64, place=Place(cpu), stop_gradient=True,
 [[[[0., 0.],
    [0., 0.]],
   [[0., 1.],
    [2., 3.]]],
  [[[0., 2.],
    [4., 6.]],
   [[0., 3.],
    [6., 9.]]]])

>>> # For two 1-d tensor x and y, the case axes=1 is equivalent to inner product.
>>> x = paddle.arange(10, dtype=data_type)
>>> y = paddle.arange(10, dtype=data_type)
>>> z1 = paddle.tensordot(x, y, axes=1)
>>> z2 = paddle.dot(x, y)
>>> print(z1)
Tensor(shape=[], dtype=float64, place=Place(cpu), stop_gradient=True,
285.)
>>> print(z2)
Tensor(shape=[], dtype=float64, place=Place(cpu), stop_gradient=True,
285.)


>>> # For two 2-d tensor x and y, the case axes=1 is equivalent to matrix multiplication.
>>> x = paddle.arange(6, dtype=data_type).reshape([2, 3])
>>> y = paddle.arange(12, dtype=data_type).reshape([3, 4])
>>> z1 = paddle.tensordot(x, y, axes=1)
>>> z2 = paddle.matmul(x, y)
>>> print(z1)
Tensor(shape=[2, 4], dtype=float64, place=Place(cpu), stop_gradient=True,
[[20., 23., 26., 29.],
 [56., 68., 80., 92.]])
>>> print(z2)
Tensor(shape=[2, 4], dtype=float64, place=Place(cpu), stop_gradient=True,
[[20., 23., 26., 29.],
 [56., 68., 80., 92.]])

>>> # When axes is a 1-d int list, x and y will be contracted along the same given axes.
>>> # Note that axes=[1, 2] is equivalent to axes=[[1, 2]], axes=[[1, 2], []], axes=[[1, 2], [1]], and axes=[[1, 2], [1, 2]].
>>> x = paddle.arange(24, dtype=data_type).reshape([2, 3, 4])
>>> y = paddle.arange(36, dtype=data_type).reshape([3, 3, 4])
>>> z = paddle.tensordot(x, y, axes=[1, 2])
>>> print(z)
Tensor(shape=[2, 3], dtype=float64, place=Place(cpu), stop_gradient=True,
[[506. , 1298., 2090.],
 [1298., 3818., 6338.]])

>>> # When axes is a list containing two 1-d int list, the first will be applied to x and the second to y.
>>> x = paddle.arange(60, dtype=data_type).reshape([3, 4, 5])
>>> y = paddle.arange(24, dtype=data_type).reshape([4, 3, 2])
>>> z = paddle.tensordot(x, y, axes=([1, 0], [0, 1]))
>>> print(z)
Tensor(shape=[5, 2], dtype=float64, place=Place(cpu), stop_gradient=True,
[[4400., 4730.],
 [4532., 4874.],
 [4664., 5018.],
 [4796., 5162.],
 [4928., 5306.]])

>>> # Thanks to the support of axes expansion, axes=[[0, 1, 3, 4], [1, 0, 3, 4]] can be abbreviated as axes= [[0, 1, 3, 4], [1, 0]].
>>> x = paddle.arange(720, dtype=data_type).reshape([2, 3, 4, 5, 6])
>>> y = paddle.arange(720, dtype=data_type).reshape([3, 2, 4, 5, 6])
>>> z = paddle.tensordot(x, y, axes=[[0, 1, 3, 4], [1, 0]])
>>> print(z)
Tensor(shape=[4, 4], dtype=float64, place=Place(cpu), stop_gradient=True,
[[23217330., 24915630., 26613930., 28312230.],
 [24915630., 26775930., 28636230., 30496530.],
 [26613930., 28636230., 30658530., 32680830.],
 [28312230., 30496530., 32680830., 34865130.]])