文章目录
- 0. torch<br>
- 1. Tensors
- 2. Creation Ops
- 2.1 torch.tensor(data)<br>
- 2.2 torch.sparse_coo_tensor()
- 2.3 torch.as_tensor()
- 2.4 torch.as_strided()
- 2.5 torch.from_numpy(ndarray)
- 2.6 torch.zeros()
- 2.7 torch.zeros_like()
- 2.8 torch.ones()
- 2.9 torch.ones_like()
- 2.10 torch.arrnge()
- 2.11 torch.range()
- 2.12 torch.linspace()
- 2.13 torch.logspace()
- 2.14 torch.eye()
- 2.15 torch.empty()
- 2.16 torch.empty_like()
- 2.17 torch.empty_strided()
- 2.18 torch.full()
- 2.19 torch.full_like()
- 2.20 torch.quantize_per_tensor()
- 2.21 torch.quantize_per_channel()
- 2.22 torch.dequantize(tensor)
- 2.23 torch.complex()
- 2.24 torch.polar()
- 2.25 torch.heaviside()
- reference:<br>
0. torch
torch包含多维张量的数据结构,并定义了对这些张量的数学运算。
1. Tensors
👉1.Pytorch基础模块torch的API之Tensors实例详解
2. Creation Ops
import torch
import numpy as np
2.1 torch.tensor(data)
用数据构造一个张量
torch.tensor(data, dtype=None, device=None, requires_grad=False, pin_memory=False)
data: 可以是列表、元组、NumPy ndarray、标量和其他类型。
- dtype: 返回张量所需的数据类型。默认:如果为None,则从data推断数据类型。
- device: 返回张量的所需设备CPU或GPU。默认:如果为None,则使用默认张量类型的当前设备
- requires_grad: 是否自动记录返回张量的操作,默认为False
- pin_memory: 如果设置了,返回的张量将在固定内存中分配。只对CPU张量有效。默认为False
torch.tensor([[1.2, 1.6], [2.4, 2.6], [3, 8]])
tensor([[1.2000, 1.6000],
[2.4000, 2.6000],
[3.0000, 8.0000]])
# 创建一个torch.cuda.DoubleTensor
torch.tensor([[0.11111, 0.222222, 0.33333333]], dtype = torch.float64, device = torch.device('cuda:0'))
tensor([[0.1111, 0.2222, 0.3333]], device='cuda:0', dtype=torch.float64)
# 创建一个空的tensor
torch.tensor([])
tensor([])
此外,torch.tensor()是一个函数,与torch.Tensor不同,torch.Tensor是主要的类,所有的张量都是torch.Tensor的实例
- torchTensor(data)是将输入的data转换成torch.FloatTensor,而torch.tensor(data)是依据于data的类型或者dtype
- torch.Tensor()可以创建一个空的FloatTensor,torch.tensor()创建会出错,最少也要给个空的列表 []
2.2 torch.sparse_coo_tensor()
torch.sparse_coo_tensor(indices, values, size=None, *, dtype=None, device=None, requires_grad=False)
创建一个稀疏tensor,格式为coo类型(非零元素的坐标形式)。
稀疏tensor是tensor中数值为0的元素数目远远多于非0元素的数目,并且非0元素分布无规律
反之,非0元素占大多数,称为稠密tensor
indices:非零元素的坐标;values:非零元素的值
i = torch.tensor([[0, 1, 1], [2, 0, 2]])
v = torch.tensor([3, 4, 5], dtype = torch.float32)
torch.sparse_coo_tensor(i, v, [2, 4])
tensor(indices=tensor([[0, 1, 1],
[2, 0, 2]]),
values=tensor([3., 4., 5.]),
size=(2, 4), nnz=3, layout=torch.sparse_coo)
torch.sparse_coo_tensor(i, v, dtype = torch.float64, device = torch.device('cuda:0'))
tensor(indices=tensor([[0, 1, 1],
[2, 0, 2]]),
values=tensor([3., 4., 5.]),
device='cuda:0', size=(2, 3), nnz=3, dtype=torch.float64,
layout=torch.sparse_coo)
2.3 torch.as_tensor()
torch.as_tensor(data, dtype=None, device=None)
将数据转换成torch.Tensor()。
如果数据已经是具有相同dtype和device的tensor,则不会重复执行,否则返回一个新的张量
a = np.array([1, 2, 3])
t = torch.as_tensor(a)
print(t)
tensor([1, 2, 3], dtype=torch.int32)
t1 = torch.as_tensor(a, device = torch.device('cuda'))
print(t1)
tensor([1, 2, 3], device='cuda:0', dtype=torch.int32)
2.4 torch.as_strided()
torch.as_strided(input, size, stride, storage_offset=0)
根据现有的tensor及步长来创建一个可视的tensor视图
- input: 输入的tensor
- size: 指定大小,需要指定行和列
- stride: 指定步长,也是需要指定行和列
- storage_offset: 输出张量的偏移量
x = torch.randn(3, 3)
print(x)
tensor([[ 1.5352, -1.5436, 0.3728],
[-0.9212, -0.2614, -1.0020],
[-0.9214, 0.7106, -0.0114]])
t = torch.as_strided(x, (2, 2), (1, 2))
print(t)
tensor([[ 1.5352, 0.3728],
[-1.5436, -0.9212]])
这里的参数(2, 2)很好理解,就是输出2行2列;而(1, 2)是指定步长的行和列,t的每一行从x中取值,因为行步长为1,取了1.5352,-1.5436放在t中每一行的开头;t的每一列也从给x中取值,第一列的值已经确定,第二列的值从x中按列步长2来取值,1.5352后两步是0.3728,-1.5436后两步是-0.9212
# 再试一下输出3*3的,步长为(1,3),结果看着是转置的效果-_-
t = torch.as_strided(x, (3, 3), (1, 3))
print(t)
tensor([[ 1.5352, -0.9212, -0.9214],
[-1.5436, -0.2614, 0.7106],
[ 0.3728, -1.0020, -0.0114]])
# 还有个storage_offset参数,控制行步长是否偏移,默认为0
#
t = torch.as_strided(x, (2, 2), (1, 2), 1)
print(t)
tensor([[-1.5436, -0.9212],
[ 0.3728, -0.2614]])
2.5 torch.from_numpy(ndarray)
从numpy.ndarray创建一个Tensor
a = np.array([1, 2, 3])
t = torch.from_numpy(a)
print(t)
tensor([1, 2, 3], dtype=torch.int32)
2.6 torch.zeros()
torch.zeros(*size, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
返回一个张量,其标量值为0,形状由变量size定义
torch.zeros(2, 3)
tensor([[0., 0., 0.],
[0., 0., 0.]])
torch.zeros(5)
tensor([0., 0., 0., 0., 0.])
2.7 torch.zeros_like()
torch.zeros_like(input, *, dtype=None, layout=None, device=None, requires_grad=False, memory_format=torch.preserve_format)
返回一个张量,其标量值为0,与输入的大小相同。torch.zeros_like(input)等价于torch.zeros(input.size(), dtype=input.dtype,layout=input.dtype,device= input.device).
input = torch.empty(2, 3)
torch.zeros_like(input)
tensor([[0., 0., 0.],
[0., 0., 0.]])
2.8 torch.ones()
torch.ones(*size, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
返回一个张量,该张量填充标量值1,形状由变量size定义。
torch.ones(2, 3)
tensor([[1., 1., 1.],
[1., 1., 1.]])
torch.ones(5)
tensor([1., 1., 1., 1., 1.])
2.9 torch.ones_like()
torch.ones_like(input, *, dtype=None, layout=None, device=None, requires_grad=False, memory_format=torch.preserve_format)
返回一个张量,其标量值为1,与输入的大小相同。torch.ones_like(input)等价于torch.ones(input.size(), dtype=input.dtype,layout=input.dtype,device= input.device).
input = torch.empty(2, 3)
torch.ones_like(input)
tensor([[1., 1., 1.],
[1., 1., 1.]])
2.10 torch.arrnge()
torch.arange(start=0, end, step=1, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
创建一个通过步长step间隔,大小为(end-start)/step的一维张量
start默认值为0
step默认值为1
end需要指定
#只指定end
a = torch.arange(5)
a
tensor([0, 1, 2, 3, 4])
# 指定start,end
b = torch.arange(1, 4)
b
tensor([1, 2, 3])
# 指定start,end, step,但输出的张量不包含end
torch.arange(1, 3, 0.5)
tensor([1.0000, 1.5000, 2.0000, 2.5000])
# 不能整除时,输出的张量也不包含end
torch.arange(1, 3, 0.3)
tensor([1.0000, 1.3000, 1.6000, 1.9000, 2.2000, 2.5000, 2.8000])
2.11 torch.range()
torch.range(start=0, end, step=1, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
此函数已弃用,并将在未来版本中删除,建议用上个torch.arange()
2.12 torch.linspace()
torch.linspace(start, end, steps, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
创建一个均匀间隔steps,大小为(end-start)/steps的一维张量
torch.linspace(3, 10, steps = 5)
tensor([ 3.0000, 4.7500, 6.5000, 8.2500, 10.0000])
2.13 torch.logspace()
torch.logspace(start, end, steps, base=10.0, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
创建一个起始
b
a
s
e
s
t
a
r
t
base^{start}
basestart均匀间隔steps,结束为
b
a
s
e
e
n
d
base^{end}
baseend的一维张量
torch.logspace(start = -10, end = 10, steps = 5)
tensor([1.0000e-10, 1.0000e-05, 1.0000e+00, 1.0000e+05, 1.0000e+10])
2.14 torch.eye()
torch.eye(n, m=None, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
返回一个二维张量,对角线上为1,其他地方为0。
n: 张量函数
m:默认等于n
torch.eye(3)
tensor([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
torch.eye(3, 2)
tensor([[1., 0.],
[0., 1.],
[0., 0.]])
2.15 torch.empty()
torch.empty(*size, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False, pin_memory=False)
返回一个包含未初始化数据的张量。张量的形状是由变量size定义的
torch.empty(2)
tensor([1.0653e-38, 1.0469e-38])
# size可以是元组
torch.empty(2, 3)
tensor([[0.0000e+00, 4.1292e-05, 1.0500e-08],
[1.6894e-07, 4.2969e-05, 1.6853e+22]])
# size也可以是list
torch.empty([2, 3])
tensor([[8.4113e+20, 1.0569e+21, 1.0573e-05],
[1.6521e-07, 1.3543e-05, 6.6523e+22]])
2.16 torch.empty_like()
torch.empty_like(input, *, dtype=None, layout=None, device=None, requires_grad=False, memory_format=torch.preserve_format)
返回与输入大小相同的未初始化张量。torch.emptys_like(input)等价于torch.emptys(input.size(), dtype=input.dtype,layout=input.dtype,device= input.device).
输入的必须是Tensor
i = torch.tensor([2., 3.])
t = torch.empty_like(i)
print(t)
t.dtype
tensor([-5.7296e+35, 4.5916e-41])
torch.float32
2.17 torch.empty_strided()
torch.empty_strided(size, stride, *, dtype=None, layout=None, device=None, requires_grad=False, pin_memory=False)
返回一个包含未初始化数据的张量。张量的形状和步幅分别由变量size和stride定义。
torch.empty_strided(size, stride)等价于torch.empty(size).as_strided(size, stride).
a = torch.empty_strided((2, 3), (1, 2))
a
tensor([[6.6460e+22, 4.1726e+21, 5.1205e-11],
[4.1292e-05, 8.3112e+20, 7.5034e+28]])
a.stride()
(1, 2)
a.size()
torch.Size([2, 3])
2.18 torch.full()
torch.full(size, fill_value, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
创建一个用fill_value填充的size张量。张量的dtype是从fill_value推断出来的。
torch.full((2, 3), 3.14)
tensor([[3.1400, 3.1400, 3.1400],
[3.1400, 3.1400, 3.1400]])
2.19 torch.full_like()
torch.full_like(input, fill_value, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False, memory_format=torch.preserve_format)
返回一个张量,其大小与填充了fill_value的输入相同。
torch.full_like(input, fill_value)等价于torch.full(input.size(), fill_value, dtype=input.dtype, layout=input.layout, device=input.device).
2.20 torch.quantize_per_tensor()
torch.quantize_per_tensor(input, scale, zero_point, dtype)
将浮点张量转换为具有给定尺度和零点的量化张量。
a = torch.quantize_per_tensor(torch.tensor([-1.0, 3.0, 1.0, 2.0]), 0.1, 10, torch.quint8)
a
tensor([-1., 3., 1., 2.], size=(4,), dtype=torch.quint8,
quantization_scheme=torch.per_tensor_affine, scale=0.1, zero_point=10)
a.dtype
torch.quint8
量化是指用于执行计算并以低于浮点精度的位宽存储张量的技术,主要是一种加速推理的技术,并且量化算子仅支持前向传递。
量化参考:
这个函数是pytorch量化中的静态量化,给定了scale和zero_point,将32位浮点数量化成了8位定点数
还有动态量化:torch.quantization.quantize_dynamic
# 一般量化后的模型带入运算时,需要用dequantize()函数解除量化,重新变为float32
a.dequantize().dtype
torch.float32
2.21 torch.quantize_per_channel()
torch.quantize_per_channel(input, scales, zero_points, axis, dtype)
将浮点张量转换为具有给定尺度和零点的每个通道量化张量。
这个和上一个对比,上一个按Tensor量化,这个函数按channel量化
参数部分,除了需要指定scale,zero_point,dtype,还需指定per_channel的维度
# 这里的scale和zero_point就是一维张量,而且要和input的size匹配
x = torch.tensor([[-1.0, 0.0], [1.0, 2.0]])
torch.quantize_per_channel(x, torch.tensor([0.1, 0.01]), torch.tensor([10, 0]), 0, torch.quint8)
tensor([[-1., 0.],
[ 1., 2.]], size=(2, 2), dtype=torch.quint8,
quantization_scheme=torch.per_channel_affine,
scale=tensor([0.1000, 0.0100], dtype=torch.float64),
zero_point=tensor([10, 0]), axis=0)
2.22 torch.dequantize(tensor)
这个函数在2.20以经用过了,就是反量化的,把量化的张量重新转换成float32
2.23 torch.complex()
torch.complex(real, imag, *, out=None)
构造一个复张量,其实部等于real,虚部等于imag。
real必须时float或double,imag和real保持一致
# 如果real和imag都是float32,输出为complex64
real = torch.tensor([1, 2], dtype = torch.float32)
imag = torch.tensor([3, 4], dtype = torch.float32)
z = torch.complex(real, imag)
print(z)
z.dtype
tensor([1.+3.j, 2.+4.j])
torch.complex64
2.24 torch.polar()
torch.polar(abs, angle, *, out=None)
构造一个complex张量,其元素为笛卡尔坐标,对应于绝对值为abs、夹角为angle的极坐标
o
u
t
=
a
b
s
⋅
c
o
s
(
a
n
g
l
e
)
+
a
b
s
⋅
s
i
n
(
a
n
g
l
e
)
⋅
j
out=abs⋅cos(angle)+abs⋅sin(angle)⋅j
out=abs⋅cos(angle)+abs⋅sin(angle)⋅j
abs: 必须为float或double
angle: 和abs保持一致
# 如果abs和angle都是float64,输出为complex128
abs = torch.tensor([1, 2], dtype=torch.float64)
angle = torch.tensor([np.pi / 2, 5 * np.pi / 4], dtype=torch.float64)
z = torch.polar(abs, angle)
print(z)
z.dtype
tensor([ 6.1232e-17+1.0000j, -1.4142e+00-1.4142j], dtype=torch.complex128)
torch.complex128
2.25 torch.heaviside()
torch.heaviside(input, values, * , out=None)
为输入中的每个元素计算Heaviside阶跃函数。
Heaviside阶跃函数定义为:
h
e
a
v
i
s
i
d
e
(
i
n
p
u
t
,
v
a
l
u
e
s
)
=
{
0
,
i
f
i
n
p
u
t
<
0
v
a
l
u
e
s
,
i
f
i
n
p
u
t
=
=
0
1
,
i
f
i
n
p
u
t
>
0
heaviside(input,values) = \begin{cases} 0, & if input < 0 \\ values, & if input == 0 \\ 1, & if input > 0 \\ \end{cases}
heaviside(input,values)=⎩
⎨
⎧0,values,1,ifinput<0ifinput==0ifinput>0
input = torch.tensor([-1.5, 0, 2.0])
value = torch.tensor([0.5])
torch.heaviside(input, value)
tensor([0.0000, 0.5000, 1.0000])