张量是 Mindspore 网络计算中的基本数据结构,储存了一个 n 维数组。下面简要介绍张量的基本操作。
张量的语法:mindspore.Tensor(input_data=None, dtype=None, shape=None, init=None)
input_data:待保存的数据,可以是 Tensor, float, int, bool, tuple, list, numpy.ndarray。
dtype: 指定输出张量的数据类型,可以为 mindspore. int8/byte, int16/short, int32/intc, int64/intp, unit8/ubyte, uint16/ushort, uint32/uintc uint64/uintp, float16/half, float32/single, float64/double, complex64, complex128. 默认和 input_data 一致。
shape:指定输出张量的数据形状,可以为 tuple, list, int。
init:初始化数据信息,用于并行模式的延迟初始化,不建议在其他模式下使用。如果要使用,要调用 Tensor.init_data 来转换为实际数据。
import numpy as np
import mindspore as ms
from mindspore import Tensor, context
context.set_context(mode=context.GRAPH_MODE,device_target="CPU") # 设置MindSpore运行配置: 静态图模式,训练硬件为 CPU
张量可以用多种方案定义:
x = Tensor(np.array([[-4,-2],[-1,-3]]),dtype=ms.float64)
print('数据为:\n{}\n'.format(x))
print('数值类型为:\n{}\n'.format(x.dtype))
y = Tensor.from_numpy(np.array([1,2,3]))
print('另一种方式为张量设值:\n{}\n'.format(y))
数据为:
[[-4. -2.]
[-1. -3.]]
数值类型为:
Float64
另一种方式为张量设值:
[1 2 3]
张量所涉及到的操作:
print('数值为:\n{}\n'.format(x))
print('类型:\n{}\n'.format(type(x)))
print('数值类型:\n{}\n'.format(x.dtype))
print('张量形状:\n{}\n'.format(x.shape))
print('改变形状:\n{}\n'.format(x.reshape((1,4))))
print('另一种方式改变形状:\n{}\n'.format(x.view(1,4)))
数值为:
[[-4. -2.]
[-1. -3.]]
类型:
数值类型:
Float64
张量形状:
(2, 2)
改变形状:
[[-4. -2. -1. -3.]]
另一种方式改变形状:
[[-4. -2. -1. -3.]]
print('张量尺寸:\n{}\n'.format(x.size)) # 元素个数
print('改变尺寸:\n{}\n'.format(x.resize(3, 3))) # 如果超过原有尺寸,会以 0 补之
print('张量维度:\n{}\n'.format(x.ndim))
print('转置:\n{}\n'.format(x.T))
print('另一种转置方式:\n{}\n'.format(x.transpose()))
张量尺寸:
4
改变尺寸:
[[-4. -2. -1.]
[-3. 0. 0.]
[ 0. 0. 0.]]
张量维度:
2
转置:
[[-4. -1.]
[-2. -3.]]
另一种转置方式:
[[-4. -1.]
[-2. -3.]]
print('换轴:\n{}\n'.format(x.swapaxes(0,1)))
print('绝对值:\n{}\n'.format(x.abs()))
print('最大值:\n{}\n'.format(x.max()))
print('最大值位置:\n{}\n'.format(x.argmax())) # 默认是对扁平张量中的操作
print('轴向最大值位置:\n{}\n'.format(x.argmax(axis=0))) # 指定轴
换轴:
[[-4. -1.]
[-2. -3.]]
绝对值:
[[4. 2.]
[1. 3.]]
最大值:
-1.0
最大值位置:
2
轴向最大值位置:
[1 0]
print('平均值:\n{}\n'.format(x.mean())) # 平均值
print('求和:\n{}\n'.format(x.sum()))
print('计算方差:\n{}\n'.format(x.var()))
print('计算标准差:\n{}\n'.format(x.std(axis=0))) # std(axis=None, ddof=0, keepdims=False)
print('求迹:\n{}\n'.format(x.trace()))
平均值:
-2.5
求和:
-10.0
计算方差:
1.25
计算标准差:
[1.5 0.5]
求迹:
-7.0
print('转换为 np 数组:\n{}\n'.format(x.asnumpy())) # 转换为 np 数组
print('转换其他数值类型:\n{}\n'.format((x.astype(ms.float32).dtype))) # 转换为其他数值类型
print('截取数值区间:\n{}\n'.format(x.clip(-3,0))) # 截取数值区间
print('对张量进行复制:\n{}\n'.format(x.copy())) # 对张量进行复制
print('轴向累和:\n{}\n'.format(x.cumsum(axis=0))) # 轴向累和
print('提取对角线元素:\n{}\n'.format(x.diagonal())) # 提取对角线元素
转换为 np 数组:
[[-4. -2.]
[-1. -3.]]
转换其他数值类型:
Float32
截取数值区间:
[[-3. -2.]
[-1. -3.]]
对张量进行复制:
[[-4. -2.]
[-1. -3.]]
轴向累和:
[[-4. -2.]
[-5. -5.]]
提取对角线元素:
[-4. -3.]
print('扩展维度:\n{}\n'.format(x.expand_dims(axis=0))) # 扩展维度
print('压缩维度:\n{}\n'.format(x.expand_dims(axis=0).squeeze()))
print('常值填充:\n{}\n'.format(x.fill(1.0))) #
print('扁平化:\n{}\n'.format(x.flatten(order="F")))
print('连续扁平张量:\n{}\n'.format(x.ravel()))
扩展维度:
[[[-4. -2.]
[-1. -3.]]]
压缩维度:
[[-4. -2.]
[-1. -3.]]
常值填充:
[[1. 1.]
[1. 1.]]
扁平化:
[-4. -1. -2. -3.]
连续扁平张量:
[-4. -2. -1. -3.]
print('输出元素值:\n{}\n'.format(x.item((0,1)))) # 输出指定元素,注意输出元素类型为张量
print('元素值设置:\n{}\n'.format(x.itemset((0,1), 0))) # 元素值设置,生成新的张量,不会影响原来张量。
print('元素字节长度:\n{}\n'.format(x.item((0,0)).itemsize)) # 元素字节长度
print('张量字节长度:\n{}\n'.format(x.nbytes))
print('取窄:\n{}\n'.format(x.narrow(0, 0, 1))) # 取窄 (axis, start, length)
print('重复:\n{}\n'.format(x.repeat([1,2], axis=0))) # repeat(repeats, axis=None)
输出元素值:
-2.0
元素值设置:
[[-4. 0.]
[-1. -3.]]
元素字节长度:
8
张量字节长度:
32
取窄:
[[-4. -2.]]
重复:
[[-4. -2.]
[-1. -3.]
[-1. -3.]]
mask = Tensor([[False, True],[True, True]])
print('掩码后:\n{}\n'.format(x.masked_fill(mask, 0.0))) # 掩码
a = Tensor(np.array([1,0]))
print('选择:\n{}\n'.format(a.choose(x))) # 选择
indices = Tensor(np.array([1,2]))
print('提取元素:\n{}\n'.format(x.take(indices)))
掩码后:
[[-4. 0.]
[ 0. 0.]]
选择:
[-1. -2.]
提取元素:
[-2. -1.]
from mindspore.common.initializer import One
print('\n延迟初始化:\n')
z = Tensor(shape = (3,), dtype=ms.float32, init=One()) # 采用初始化方法设置值
print('\n是否有初始化操作\n',z.has_init) #
print('\n未调用前未初始化\n',z[0]) # 延迟初始化
print('\n调用\n',z)
print('\n调用后才有初始化\n',z[0]) # 在调用之后才完成初始化
print('\n是否有初始化操作:\n',z.has_init)
延迟初始化:
是否有初始化操作
True
未调用前未初始化
0.0
调用
[1. 1. 1.]
调用后才有初始化
1.0
是否有初始化操作:
False
from mindspore.common.initializer import initializer
x = initializer(ms.common.initializer.Constant(1), [2, 2], ms.float32) # 另一种初始化方法
print('\n另一种即时初始化操作:\n',x.init_data())
另一种即时初始化操作:
[[1. 1.]
[1. 1.]]
继承另一个张量的属性,形成新的张量。
from mindspore import ops
oneslike = ops.OnesLike()
x = Tensor(np.array([[0,1],[2,3]]).astype(np.int32))
output = oneslike(x)
print('Data type of output: {}'.format(type(output)))
print(output)
Data type of output:
[[1 1]
[1 1]]
输出指定大小的恒定值张量。可指定 dtype,如 mytype.int32、mytype.float32、mytype.bool_ 等。
from mindspore import ops
shape = (2,2)
ones = ops.Ones()
output = ones(shape,mytype.float32)
print(output)
zeros = ops.Zeros()
output = zeros(shape,mytype.float32)
print(output)
[[ True True]
[ True True]]
[[0. 0.]
[0. 0.]]
张量运算:算术、线性代数、矩阵处理(转置、标引、切片)、采样等。
tensor = Tensor(np.array([[0,1],[2,3]]).astype(np.float32))
print('First row: {}'.format(tensor[0]))
print('First column: {}'.format(tensor[:,0]))
print('Last column: {}'.format(tensor[...,-1]))
First row: [0. 1.]
First column: [0. 2.]
Last column: [1. 3.]
Concat 将给定维度上的一系列张量连接起来。
data1 = Tensor(np.array([[0,1],[2,3]]).astype(np.float32))
data2 = Tensor(np.array([[4,5],[6,7]]).astype(np.float32))
op = ops.Concat()
output = op((data1,data2))
print(output)
[[0. 1.]
[2. 3.]
[4. 5.]
[6. 7.]]
Stack 则是从另一个维度上将两个张量合并起来。
data1 = Tensor(np.array([[0,1],[2,3]]).astype(np.float32))
data2 = Tensor(np.array([[4,5],[6,7]]).astype(np.float32))
op = ops.Stack()
output = op([data1,data2])
print(output)
[[[0. 1.]
[2. 3.]]
[[4. 5.]
[6. 7.]]]
普通运算:
data1 = Tensor(np.array([[0,1],[2,3]]).astype(np.float32))
data2 = Tensor(np.array([[4,5],[6,7]]).astype(np.float32))
mul = ops.Mul()
output = mul(data1, data2)
print(output)
[[ 0. 5.]
[12. 21.]]