# Tensor¶

Tensor 是 Paddle 中最为基础的数据结构，请参考 Tensor 介绍

• 用预先存在的 data 数据创建 1 个 Tensor，请参考 to_tensor

• 创建一个指定 shape 的 Tensor，请参考 oneszerosfull

• 创建一个与其他 Tensor 具有相同 shapedtype 的 Tensor，请参考 ones_likezeros_likefull_like

## create_tensor(dtype, name=None, persistable=False)¶

>>> import paddle


import paddle
out = linear(input)
out.backward()


## dtype¶

import paddle
print("tensor's type is: {}".format(x.dtype))


## type¶

>>> import paddle

>>> print(x.type)
VarType.LOD_TENSOR


import paddle
z = x * y
z.backward()


## is_leaf¶

import paddle

print(x.is_leaf) # True

y = x + 1
print(x.is_leaf) # True
print(y.is_leaf) # True

y = x + 1
print(x.is_leaf) # True
print(y.is_leaf) # False


## item(*args)¶

import paddle

print(x.item())             #1
print(type(x.item()))       #<class 'int'>

print(x.item())             #1.0
print(type(x.item()))       #<class 'float'>

print(x.item())             #True
print(type(x.item()))       #<class 'bool'>

print(x.item())             #(1+1j)
print(type(x.item()))       #<class 'complex'>

print(x.item(2))            #3.3
print(x.item(0, 2))         #3.3


## name¶

import paddle
# Tensor name: generated_tensor_0


## ndim¶

import paddle
print("Tensor's number of dimensition: ", paddle.to_tensor([[1, 2], [3, 4]]).ndim)
# Tensor's number of dimensition: 2


## persistable¶

import paddle
print("Whether Tensor is persistable: ", paddle.to_tensor(1).persistable)
# Whether Tensor is persistable: false


## place¶

import paddle
print(cpu_tensor.place)


## layout¶

>>> import paddle

>>> x = paddle.to_tensor([1, 2, 3])
>>> print(x.layout)
NCHW


## shape¶

>>> import paddle

>>> print(x.shape)
[]


## strides¶

>>> import paddle

>>> x = paddle.to_tensor([1, 2, 3])
>>> y = x[1]
>>> print(y.strides)
[]


## dist_attr¶

>>> import paddle

>>> mesh = dist.ProcessMesh([[2, 4, 5], [0, 1, 3]], dim_names=["x", "y"])
>>> dist_attr = dist.DistAttr(mesh=mesh, sharding_specs=['x', 'y'])

...                       [5,6,7]])
>>> d_tensor = dist.shard_tensor(a, dist_attr=dist_attr)

>>> print(d_tensor.dist_attr)


## offset¶

>>> import paddle

>>> x = paddle.to_tensor([1, 2, 3])
>>> y = x[1]
>>> print(y.offset)
8


import paddle


## data¶

>>> import paddle

>>> print(x)
1.)

>>> print(x.data)
1.)

>>> print(x)
2.)

>>> print(x.data)
2.)


## numpy()¶

>>> import paddle

>>> data = paddle.uniform([30, 10, 32], dtype="float32", min=-1, max=1)
>>> x = linear(data)


## reconstruct_from_(other)¶

>>> import paddle

>>> t1.reconstruct_from_(t2)
>>> print(t1)


## clone()¶

>>> import paddle

>>> clone_x = x.clone()
>>> y = clone_x**2
>>> y.backward()
False
False

>>> clone_x = x.clone()
>>> z = clone_x**3
>>> z.backward()
False
True
None


>>> import paddle

>>> x = paddle.to_tensor([1.0, 2.0, 3.0])
>>> y = x + x
>>> loss = y.sum()
>>> loss.backward()

[1., 1., 1.])

>>> x = paddle.to_tensor([1.0, 2.0, 3.0])
>>> y = x + x
>>> loss = y.sum()
>>> loss.backward()

[1., 1., 1.])


• set_to_zero (bool) - True 表示将梯度值覆盖为 0。False 则释放梯度持有的存储空间。

>>> import paddle
>>> out = linear(input)
>>> out.backward()
[[-0.03178465, -0.03178465, -0.03178465],
[-0.98546225, -0.98546225, -0.98546225]])
[[0., 0., 0.],
[0., 0., 0.]])


## detach()¶

>>> import paddle

>>> detach_x = x.detach()
>>> detach_x[0] = 10.0
>>> print(x)

>>> y = x**2
>>> y.backward()

None

>>> z = detach_x**3
>>> z.backward()

>>> # Due to sharing of data with origin Tensor, There are some unsafe operations:
>>> # y = 2 * x
>>> # detach_x[:] = 5.0
>>> # y.backward()
>>> # It will raise Error:
>>> #   one of the variables needed for gradient computation has been modified by an inplace operation.


## get_tensor()¶

>>> import paddle

>>> underline_x = x.get_tensor()
>>> print(underline_x)
- place: Place(cpu)
- shape: [1]
- layout: NCHW
- dtype: float32
- data: [1]


## is_dense()¶

>>> import paddle

>>> print(x.is_dense())
True


## is_dist()¶

>>> import paddle

>>> print(x.is_dist())
False


## data_ptr()¶

>>> import paddle

>>> x = paddle.to_tensor([1, 2, 3])
>>> print(x.data_ptr())
93220864


## get_strides()¶

>>> import paddle

>>> x = paddle.to_tensor([1, 2, 3])
>>> y = x[1]
>>> print(y.get_strides())
[]


## contiguous()¶

>>> import paddle

>>> x = paddle.to_tensor([1, 2, 3])
>>> y = x[1]
>>> y = y.contiguous()
>>> print(y)


## is_contiguous()¶

>>> import paddle

>>> x = paddle.to_tensor([1, 2, 3])
>>> y = x[1]
>>> print(y.is_contiguous())


## acos(name=None)¶

Inplace 版本的 add API，对输入 x 采用 Inplace 策略。

## astype(dtype)¶

• dtype (str) - 转换后的 dtype，支持'bool'，'float16'，'float32'，'float64'，'int8'，'int16'， 'int32'，'int64'，'uint8'。

import paddle
print("original tensor's dtype is: {}".format(x.dtype))
print("new tensor's dtype is: {}".format(x.astype('float64').dtype))


## atan(name=None)¶

• grad_tensor (Tensor, 可选) - 当前 Tensor 的初始梯度值。如果 grad_tensor 是 None，当前 Tensor 的初始梯度值将会是值全为 1.0 的 Tensor；如果 grad_tensor 不是 None，必须和当前 Tensor 有相同的长度。默认值：None。

• retain_graph (bool, 可选) - 如果为 False，反向计算图将被释放。如果在 backward()之后继续添加 OP， 需要设置为 True，此时之前的反向计算图会保留。将其设置为 False 会更加节省内存。默认值：False。

import paddle
for i in range(5):
y.backward()
# 0: [500.]
# 1: [1000.]
# 2: [1500.]
# 3: [2000.]
# 4: [2500.]
# 0.
for i in range(5):
# 0: [1000.]
# 1: [2000.]
# 2: [3000.]
# 3: [4000.]
# 4: [5000.]


## ceil_(name=None)¶

Inplace 版本的 ceil API，对输入 x 采用 Inplace 策略。

## clip_(min=None, max=None, name=None)¶

Inplace 版本的 clip API，对输入 x 采用 Inplace 策略。

## clone()¶

import paddle

clone_x = x.clone()
y = clone_x**2
y.backward()

clone_x = x.clone()
z = clone_x**3
z.backward()


## cosh(name=None)¶

>>> import paddle

>>> x = paddle.to_tensor([-0.4, -0.2, 0.1, 0.3])
>>> print(out)
[1.08107233, 1.02006674, 1.00500417, 1.04533851])


## cpu()¶

import paddle

print(x.place)    # CUDAPlace(0)

y = x.cpu()
print(y.place)    # CPUPlace


## cuda(device_id=None, blocking=False)¶

• device_id (int, 可选) - 目标 GPU 的设备 Id，默认为 None，此时为当前 Tensor 的设备 Id，如果当前 Tensor 不在 GPU 上，则为 0。

• blocking (bool, 可选) - 如果为 False 并且当前 Tensor 处于固定内存上，将会发生主机到设备端的异步拷贝。否则，会发生同步拷贝。默认为 False。

import paddle
print(x.place)        # CPUPlace

y = x.cuda()
print(y.place)        # CUDAPlace(0)

y = x.cuda(1)
print(y.place)        # CUDAPlace(1)


## dim()¶

import paddle
print("Tensor's number of dimensition: ", paddle.to_tensor([[1, 2], [3, 4]]).dim())
# Tensor's number of dimensition: 2


## element_size()¶

import paddle

x.element_size() # 1

x.element_size() # 2

x.element_size() # 4

x.element_size() # 8

x.element_size() # 16


## exp_(name=None)¶

Inplace 版本的 exp API，对输入 x 采用 Inplace 策略。

## exponential_(lam=1.0, name=None)¶

lam指数分布$$\lambda$$ 参数。随机数符合以下概率密度函数：

$f(x) = \lambda e^{-\lambda x}$

• x (Tensor) - 输入 Tensor，数据类型为 float32/float64。

• lam (float) - 指数分布的 $$\lambda$$ 参数。

• name (str，可选) - 具体用法请参见 Name，一般无需设置，默认值为 None。

import paddle

x.exponential_()
# [[0.80643415, 0.23211166, 0.01169797],
#  [0.72520673, 0.45208144, 0.30234432]]


## fill_(x, value, name=None)¶

• x (Tensor) - 需要修改的原始 Tensor。

• value (float) - 以输入 value 值修改原始 Tensor 元素。

• name (str，可选) - 具体用法请参见 Name，一般无需设置，默认值为 None。

import paddle
tensor.fill_(0)
print(tensor.tolist())   #[0, 0, 0, 0, 0]


## zero_(x, name=None)¶

• x (Tensor) - 需要修改的原始 Tensor。

• name (str，可选) - 具体用法请参见 Name，一般无需设置，默认值为 None。

import paddle
tensor.zero_()
print(tensor.tolist())   #[0, 0, 0, 0, 0]


## fill_diagonal_(x, value, offset=0, wrap=False, name=None)¶

• x (Tensor) - 需要修改对角线元素值的原始 Tensor。

• value (float) - 以输入 value 值修改原始 Tensor 对角线元素。

• offset (int，可选) - 所选取对角线相对原始主对角线位置的偏移量，正向右上方偏移，负向左下方偏移，默认为 0。

• wrap (bool，可选) - 对于 2 维 Tensor，height>width 时是否循环填充，默认为 False。

• name (str，可选) - 具体用法请参见 Name，一般无需设置，默认值为 None。

import paddle
x.fill_diagonal_(2)
print(x.tolist())   #[[2.0, 1.0, 1.0], [1.0, 2.0, 1.0], [1.0, 1.0, 2.0], [1.0, 1.0, 1.0]]

x.fill_diagonal_(2, wrap=True)
print(x)    #[[2.0, 1.0, 1.0], [1.0, 2.0, 1.0], [1.0, 1.0, 2.0], [1.0, 1.0, 1.0], [2.0, 1.0, 1.0], [1.0, 2.0, 1.0], [1.0, 1.0, 2.0]]


## fill_diagonal_tensor(x, y, offset=0, dim1=0, dim2=1, name=None)¶

• x (Tensor) - 需要填充局部对角线区域的原始 Tensor。

• y (Tensor) - 需要被填充到原始 Tensor x 对角线区域的输入 Tensor。

• offset (int，可选) - 选取局部区域对角线位置相对原始主对角线位置的偏移量，正向右上方偏移，负向左下方偏移，默认为 0。

• dim1 (int，可选) - 指定对角线所参考第一个维度，默认为 0。

• dim2 (int，可选) - 指定对角线所参考第二个维度，默认为 1。

• name (str，可选) - 具体用法请参见 Name，一般无需设置，默认值为 None。

import paddle
x = paddle.ones((4, 3)) * 2
nx = x.fill_diagonal_tensor(y)
print(nx.tolist())   #[[1.0, 2.0, 2.0], [2.0, 1.0, 2.0], [2.0, 2.0, 1.0], [2.0, 2.0, 2.0]]


## fill_diagonal_tensor_(x, y, offset=0, dim1=0, dim2=1, name=None)¶

Inplace 版本的 fill_diagonal_tensor(x, y, offset=0, dim1=0, dim2=1, name=None) API，对输入 x 采用 Inplace 策略。

import paddle
x = paddle.ones((4, 3)) * 2
x.fill_diagonal_tensor_(y)
print(x.tolist())   #[[1.0, 2.0, 2.0], [2.0, 1.0, 2.0], [2.0, 2.0, 1.0], [2.0, 2.0, 2.0]]


## flatten_(start_axis=0, stop_axis=-1, name=None)¶

Inplace 版本的 flatten API，对输入 x 采用 Inplace 策略。

## floor_(name=None)¶

Inplace 版本的 floor API，对输入 x 采用 Inplace 策略。

## floor_mod(y, name=None)¶

mod 函数的别名，请参考 mod

## gcd(x, y, name=None)¶

Tensor.grad 相同，查看一个 Tensor 的梯度，数据类型为 numpy.ndarray。

import paddle
z = x * y
z.backward()


## ndimension()¶

import paddle
print("Tensor's number of dimensition: ", paddle.to_tensor([[1, 2], [3, 4]]).ndimension())
# Tensor's number of dimensition: 2


## pin_memory(y, name=None)¶

import paddle

print(x.place)      # CUDAPlace(0)

y = x.pin_memory()
print(y.place)      # CUDAPinnedPlace


## reciprocal_(name=None)¶

Inplace 版本的 reciprocal API，对输入 x 采用 Inplace 策略。

## register_hook(hook)¶

• hook (function) - 一个需要注册到 Tensor.grad 上的 hook 函数

import paddle

# hook function return None

# hook function return Tensor

z = paddle.to_tensor([1., 2., 3., 4.])

# one Tensor can register multiple hooks
h = x.register_hook(print_hook_fn)
x.register_hook(double_hook_fn)

w = x + y
# register hook by lambda function

o = z.matmul(w)
o.backward()
# print_hook_fn print content in backward
#        [2., 4., 6., 8.])

# remove hook
h.remove()


## remainder(y, name=None)¶

mod 函数的别名，请参考 remainder

## remainder_(y, name=None)¶

Inplace 版本的 remainder API，对输入 x 采用 Inplace 策略。

## reshape_(shape, name=None)¶

Inplace 版本的 reshape API，对输入 x 采用 Inplace 策略

## round_(name=None)¶

Inplace 版本的 round API，对输入 x 采用 Inplace 策略。

## rsqrt_(name=None)¶

Inplace 版本的 rsqrt API，对输入 x 采用 Inplace 策略。

## scale_(scale=1.0, bias=0.0, bias_after_scale=True, act=None, name=None)¶

Inplace 版本的 scale API，对输入 x 采用 Inplace 策略。

Inplace 版本的 scatter API，对输入 x 采用 Inplace 策略。

## set_value(value)¶

• value (Tensor|np.ndarray) - 需要被设置的值，类型为 Tensor 或者 numpy.array。

import paddle
import numpy as np

data = np.ones([3, 1024], dtype='float32')
linear(input)  # call with default weight
custom_weight = np.random.randn(1024, 4).astype("float32")
linear.weight.set_value(custom_weight)  # change existing weight
out = linear(input)  # call with different weight


## sinh(name=None)¶

>>> import paddle

>>> x = paddle.to_tensor([-0.4, -0.2, 0.1, 0.3])
>>> print(out)
[-0.41075233, -0.20133601,  0.10016675,  0.30452031])


## sqrt_(name=None)¶

Inplace 版本的 sqrt API，对输入 x 采用 Inplace 策略。

## squeeze_(axis=None, name=None)¶

Inplace 版本的 squeeze API，对输入 x 采用 Inplace 策略。

## subtract_(y, name=None)¶

Inplace 版本的 subtract API，对输入 x 采用 Inplace 策略。

## tanh_(name=None)¶

Inplace 版本的 tan API，对输入 x 采用 Inplace 策略。

## to(*args, **kwargs)¶

1. to(dtype, blocking=True)

2. to(device, dtype=None, blocking=True)

3. to(other, blocking=True)

>>> import paddle
>>> print(tensorx)
[1, 2, 3])

>>> tensorx = tensorx.to("cpu")
>>> print(tensorx.place)
Place(cpu)

>>> tensorx = tensorx.to("float32")
>>> print(tensorx.dtype)

>>> tensorx = tensorx.to("gpu", "int16")
>>> print(tensorx)
[1, 2, 3])
>>> tensor2
[4, 5, 6])
>>> tensor2 = tensor2.to(tensorx)
>>> print(tensor2)
[4, 5, 6])


## uniform_(min=-1.0, max=1.0, seed=0, name=None)¶

Inplace 版本的 uniform，返回一个从均匀分布采样的随机数填充的 Tensor。输出 Tensor 将被置于输入 x 的位置。

• x (Tensor) - 待被随机数填充的输入 Tensor。

• min (float|int，可选) - 生成随机数的下界，min 包含在该范围内。默认为-1.0。

• max (float|int，可选) - 生成随机数的上界，max 不包含在该范围内。默认为 1.0。

• seed (int，可选) - 用于生成随机数的随机种子。如果 seed 为 0，将使用全局默认生成器的种子（可通过 paddle.seed 设置）。

注意如果 seed 不为 0，该操作每次将生成同一个随机值。默认为 0。

• name (str，可选) - 具体用法请参见 Name，一般无需设置，默认值为 None。

import paddle
x.uniform_()
print(x)
# result is random
# Tensor(shape=[3, 4], dtype=float32, place=CUDAPlace(0), stop_gradient=True,
#     [[ 0.97134161, -0.36784279, -0.13951409, -0.48410338],
#      [-0.15477282,  0.96190143, -0.05395842, -0.62789059],
#      [-0.90525085,  0.63603556,  0.06997657, -0.16352385]])


## unsqueeze_(axis, name=None)¶

Inplace 版本的 unsqueeze API，对输入 x 采用 Inplace 策略。

## lerp_(y, weight, name=None)¶

Inplace 版本的 lerp API，对输入 x 采用 Inplace 策略。

## nnz()¶

import paddle

indices = [[0, 1, 2], [1, 2, 0]]
values = [1.0, 2.0, 3.0]
dense_shape = [3, 3]
coo.nnz()
# 3


## indices()¶

import paddle

indices = [[0, 1, 2], [1, 2, 0]]
values = [1.0, 2.0, 3.0]
dense_shape = [3, 3]
coo.indices()
# Tensor(shape=[2, 3], dtype=int64, place=Place(gpu:0), stop_gradient=True,
#        [[0, 1, 2],
#         [1, 2, 0]])


## values()¶

import paddle

indices = [[0, 1, 2], [1, 2, 0]]
values = [1.0, 2.0, 3.0]
dense_shape = [3, 3]
coo.values()
#        [1., 2., 3.])


## crows()¶

import paddle

crows = [0, 2, 3, 5]
cols = [1, 3, 2, 0, 1]
values = [1, 2, 3, 4, 5]
dense_shape = [3, 4]
csr = paddle.sparse.sparse_csr_tensor(crows, cols, values, dense_shape)
csr.crows()
#        [0, 2, 3, 5])


## cols()¶

import paddle

crows = [0, 2, 3, 5]
cols = [1, 3, 2, 0, 1]
values = [1, 2, 3, 4, 5]
dense_shape = [3, 4]
csr = paddle.sparse.sparse_csr_tensor(crows, cols, values, dense_shape)
csr.cols()
#        [1, 3, 2, 0, 1])


## is_sparse()¶

import paddle

indices = [[0, 1, 2], [1, 2, 0]]
values = [1.0, 2.0, 3.0]
dense_shape = [3, 3]
coo.is_sparse()
# True


## is_sparse_coo()¶

import paddle

indices = [[0, 1, 2], [1, 2, 0]]
values = [1.0, 2.0, 3.0]
dense_shape = [3, 3]
coo.is_sparse_coo()
# True


## is_sparse_csr()¶

import paddle

crows = [0, 2, 3, 5]
cols = [1, 3, 2, 0, 1]
values = [1, 2, 3, 4, 5]
dense_shape = [3, 4]
csr = paddle.sparse.sparse_csr_tensor(crows, cols, values, dense_shape)
csr.is_sparse_csr()
# True


## to_sparse_csr()¶

import paddle

indices = [[0, 1, 2], [1, 2, 0]]
values = [1.0, 2.0, 3.0]
dense_shape = [3, 3]
coo.to_sparse_csr()
#        crows=[0, 1, 2, 3],
#        cols=[1, 2, 0],
#        values=[1., 2., 3.])


## unfold(x, axis, size, step, name=None)¶

Inplace 版本的 masked_fill API，对输入 x 采用 Inplace 策略。

Inplace 版本的 masked_scatter API，对输入 x 采用 Inplace 策略。

## select_scatter(x, values, axis, index, name=None)¶

values 矩阵的值嵌入到 x 矩阵的第 axis 维的 index 列, values 的形状需要与 x 矩阵除去第 axis 维后的形状一致