Tensor

Ascend GPU CPU 入门

在线运行下载Notebook下载样例代码查看源文件

概述

张量(Tensor)是MindSpore网络运算中的基本数据结构。张量中的数据类型可参考dtype

不同维度的张量分别表示不同的数据,0维张量表示标量,1维张量表示向量,2维张量表示矩阵,3维张量可以表示彩色图像的RGB三通道等等。

张量构造

构造张量时,支持传入Tensorfloatintbooltuplelistcomplexnumpy.arraynumpy.str类型,其中tuplelist里只能存放floatintboolcomplex类型数据, 其中complex表示复数数据类型,其中numpy.str仅支持数据透传使用,不支持在算子侧运行。

Tensor初始化时,可指定dtype。如果没有指定dtype,初始值intfloatboolcomplex分别生成数据类型为mindspore.int32mindspore.float64mindspore.bool_mindspore.complex128的0维Tensor, 初始值tuplelist生成的1维Tensor数据类型与tuplelist里存放的数据类型相对应,如果包含多种不同类型的数据,则按照优先级:bool < int < float < complex,选择相对优先级最高类型所对应的mindspore数据类型。 如果初始值是Tensor,则生成的Tensor数据类型与其一致;如果初始值是NumPy.array,则生成的Tensor数据类型与之对应。

代码样例如下:

[1]:
import numpy as np
from mindspore import Tensor
from mindspore import dtype as mstype

x = Tensor(np.array([[1, 2], [3, 4]]), mstype.int32)
y = Tensor(1.0, mstype.int32)
z = Tensor(2, mstype.int32)
m = Tensor(True, mstype.bool_)
n = Tensor((1, 2, 3), mstype.int16)
p = Tensor([4.0, 5.0, 6.0], mstype.float64)
q = Tensor(p, mstype.float64)

print(x, "\n\n", y, "\n\n", z, "\n\n", m, "\n\n", n, "\n\n", p, "\n\n", q)
[[1 2]
 [3 4]]

 1

 2

 True

 [1 2 3]

 [4. 5. 6.]

 [4. 5. 6.]

张量的运算、属性和方法

运算

张量支持多种操作符运算,包括算术运算、逻辑运算等。当不同形状的两个数组进行运算时,提供与Numpy相似的broadcast广播机制。以下是一些常用运算操作符:

  • 算术运算:加(+)、减(-)、乘(*)、除(/)、取模(%)、幂次方(**)、整除(//

  • 逻辑运算:等于(==)、不等于(!=)、大于(>)、大于等于(>=)、小于(<)、小于等于(<=

代码样例如下:

[2]:
import numpy as np
from mindspore import Tensor
from mindspore import dtype as mstype

x = Tensor(np.array([1, 2, 3]), mstype.float32)
y = Tensor(np.array([4, 5, 6]), mstype.float32)
output_add = x + y
output_sub = x - y
output_mul = x * y
output_div = y / x
output_mod = x % y
output_pow = x ** 2
output_floordiv = y // x
print("add:", output_add)
print("sub:", output_sub)
print("mul:", output_mul)
print("div:", output_div)
print("mod:", output_mod)
print("pow:", output_pow)
print("floordiv:", output_floordiv)

a = Tensor(np.array([2, 2, 2]), mstype.int32)
b = Tensor(np.array([1, 2, 3]), mstype.int32)
output_eq = a == b
output_ne = a != b
output_gt = a > b
output_gq = a >= b
output_lt = a < b
output_lq = a <= b
print("equal:", output_eq)
print("not equal:", output_ne)
print("greater than:", output_gt)
print("greater or equal:", output_gq)
print("less than:", output_lt)
print("less or equal:", output_lq)
add: [5. 7. 9.]
sub: [-3. -3. -3.]
mul: [ 4. 10. 18.]
div: [4. 2.5 2. ]
mod: [1. 2. 3.]
pow: [1. 4. 9.]
floordiv: [4. 2. 2.]
equal: [False True False]
not equal: [ True False True]
greater than: [ True False False]
greater or equal: [ True True False]
less than: [False False True]
less or equal: [False True True]

属性

张量的属性包括形状、数据类型、转置张量、单个元素大小、占用字节数量、维数、元素个数、每一维步长。

  • 形状(shape):Tensor的shape,是一个tuple。

  • 数据类型(dtype):Tensor的dtype,是MindSpore的一个数据类型。

  • 转置张量(T):Tensor的转置,也是一个Tensor

  • 单个元素大小(itemsize): Tensor中每一个元素占用字节数,是一个整数。

  • 占用字节数量(nbytes): Tensor占用的总字节数,是一个整数。

  • 维数(ndim): Tensor的秩,也就是len(tensor.shape),是一个整数。

  • 元素个数(size): Tensor中所有元素的个数,是一个整数。

  • 每一维步长(strides): Tensor中每一维中进行遍历所需要经过的字节数。

代码样例如下:

[3]:
import numpy as np
from mindspore import Tensor
from mindspore import dtype as mstype

x = Tensor(np.array([[1, 2], [3, 4]]), mstype.int32)
x_shape = x.shape
x_dtype = x.dtype
x_transposed = x.T
x_itemsize = x.itemsize
x_nbytes = x.nbytes
x_ndim = x.ndim
x_size = x.size
x_strides = x.strides
print("x_shape:", x_shape)
print("x_dtype:", x_dtype)
print("x_transposed:", x_transposed)
print("x_itemsize:", x_itemsize)
print("x_nbytes:", x_nbytes)
print("x_ndim:", x_ndim)
print("x_size:", x_size)
print("x_strides:", x_strides)
x_shape: (2, 2)
x_dtype: Int32
x_transposed: [[1 3]
 [2 4]]
x_itemsize: 4
x_nbytes: 16
x_ndim: 2
x_size: 4
x_strides: (8, 4)

方法

张量的方法包括lenstrreprhashallanyasnumpy等,我们同时提供了与Numpyndarray使用方式类似的Tensor方法来提升用户体验。详细的方法列表,使用方式以及支持后端请参考Tensor类方法API,以下是一些类方法的简单介绍:

  • len():返回张量的长度。

  • str():返回张量的字符串表达。

  • repr():返回张量的字符串表达,供解释器读取。

  • hash():获取张量的哈希值。

  • all(axis, keep_dims):在指定维度上通过and操作进行归约,axis代表归约维度,keep_dims表示是否保留归约后的维度。

  • any(axis, keep_dims):在指定维度上通过or操作进行归约,参数含义同all

  • asnumpy():将Tensor转换为NumPyarray

  • sum(axis, dtype, keepdims, initial): 在指定维度上对张量进行归约求和,axis代表归约维度,dtype代表输出的数据的类型,keepdims表示是否保留归约后的维度, initial表示规约求和开始前的初始值。

代码样例如下:

[4]:
import numpy as np
from mindspore import Tensor
from mindspore import dtype as mstype

t = Tensor(np.array([1, 2, 3]), mstype.int32)
t_len = len(t)
t_str = str(t)
t_repr = repr(t)
t_hash = hash(t)
print("t_len:", t_len)
print("t_str:", t_str)
print("t_repr:", t_repr)
print("t_hash:", t_hash)

x = Tensor(np.array([[True, True], [False, False]]), mstype.bool_)
x_all = x.all()
x_any = x.any()
x_array = x.asnumpy()
print("x_all:", x_all)
print("x_any:", x_any)
print("x_array:", x_array)

import mindspore.numpy as mnp
y = Tensor(np.array([[1., 2.], [3., 4.]]), mstype.float32)
# y.sum() and mindspore.numpy.sum(y) are equivalent methods
y_sum_tensor = y.sum()
y_sum_mnp = mnp.sum(y)
print("y_sum_tensor:", y_sum_tensor)
print("y_sum_mnp:", y_sum_mnp)
t_len: 3
t_str: [1 2 3]
t_repr: Tensor(shape=[3], dtype=Int32, value= [1, 2, 3])
t_hash: 281470264268272
x_all: False
x_any: True
x_array: [[ True  True]
 [False False]]
y_sum_tensor: 10.0
y_sum_mnp: 10.0

稀疏张量

稀疏张量是一种特殊张量,其中绝大部分元素的值为零。在某些应用场景中(比如推荐系统),数据的特征是稀疏的,若使用普通张量表征这些数据会引入大量不必要的计算、存储和通讯开销。在这种时候就可以使用稀疏张量来表征这些数据。

常用稀疏张量的表达形式是<indices:Tensor, values:Tensor, dense_shape:Tensor>。其中,indices表示非零下标元素, values表示非零元素的值,dense_shape表示的是被压缩的稀疏张量的形状。 在这个结构下,我们定义了RowTensorSparseTensor两种稀疏张量结构。

PyNative模式暂不支持稀疏张量。

RowTensor

RowTensor用于压缩第零个维度稀疏的张量。若RowTensor的维度为[L0, D1, D2, ..., DN ]。第零维度的非零元素个数为D0, 则有L0 >> D0

  • indices: 一维整数张量,表示稀疏张量第零维度中非零元素的位置。形状:[D0]

  • values: 表示相对应的非零元素的值。形状:[D0, D1, D2, ..., DN]

  • dense_shape: 表示的是被压缩的稀疏张量的形状。

RowTensor只能在Cell的构造方法中使用。详细内容,请参考mindspore.RowTensor。代码样例如下:

[5]:
import mindspore as ms
import mindspore.nn as nn
from mindspore import Tensor
from mindspore import RowTensor

class Net(nn.Cell):
    def __init__(self, dense_shape):
        super(Net, self).__init__()
        self.dense_shape = dense_shape
    def construct(self, indices, values):
        x = RowTensor(indices, values, self.dense_shape)
        return x.values, x.indices, x.dense_shape

indices = Tensor([0])
values = Tensor([[1, 2]], dtype=ms.float32)
out = Net((3, 2))(indices, values)
print(out[0])
print(out[1])
print(out[2])
[[1. 2.]]
[0]
(3, 2)

SparseTensor

SparseTensor用于压缩非零元素位置分布不规则的Tensor,若非零元素的个数为N,被压缩的张量的维数为ndims,则有:

  • indices: 二维整数张量,每行代表非零元素下标。形状:[N, ndims]

  • values: 一维张量,表示相对应的非零元素的值。形状:[N]

  • dense_shape: 表示的是被压缩的稀疏张量的形状。

SparseTensor只能在Cell的构造方法中使用。详细内容,请参考mindspore.SparseTensor。代码样例如下:

[6]:
import mindspore as ms
import mindspore.nn as nn
from mindspore import Tensor
from mindspore import SparseTensor

class Net(nn.Cell):
    def __init__(self, dense_shape):
        super(Net, self).__init__()
        self.dense_shape = dense_shape
    def construct(self, indices, values):
        x = SparseTensor(indices, values, self.dense_shape)
        return x.values, x.indices, x.dense_shape

indices = Tensor([[0, 1], [1, 2]])
values = Tensor([1, 2], dtype=ms.float32)
out = Net((3, 4))(indices, values)
print(out[0])
print(out[1])
print(out[2])
[1. 2.]
[[0 1]
 [1 2]]
(3, 4)