在我们对某一功能进行测试或展示时
通常都需要构建一系列tensor
用于小型数据测试
以验证功能的正确性或展示的可行性
因此本文就梳理了pytorch
中构建tensor
的一系列方法
将存储在别的结构中的数据转为tensor
的格式
内部拷贝源数据并构建返回相应的tensor
必要参数(Parameters)
data
- 传入的结构类型 - array
、 list
、 tuple
、scalar
(标量)…可选参数(Keywords)
dtype
- 生成的数据类型 - torch.float
、 .double
、.int
、.long
…requires_grad
- 是否需要计算梯度device
- 表示tensor
所在的设备 - torhc.device('cpu')
、.device('cuda')
Test
a = torch.tensor(1.0)
b = torch.tensor([1, 2, 3], dtype=torch.float64, device=torch.device('cuda:0'))
c = torch.tensor(1.66666666666, dtype=torch.float)
d = torch.tensor(1.66666666666, dtype=torch.double)
e = torch.tensor([])
Output
a = tensor(1.)
b = tensor([1., 2., 3.], device='cuda:0', dtype=torch.float64)
c = tensor(1.6667)
d = tensor(1.6667, dtype=torch.float64)
e = tensor([])
将数据转化为稀疏张量
Parameters:
indices
- N
个非零值的索引 - shape(2, N)
values
- 值 - 索引对应的N
个值 size
- 稀疏tensor
的形状 - 默认为符合输入要求的最小形状Keywords
: dtype - device - requires_grad
Test 1
i = torch.tensor([[0, 1, 1], [2, 0, 2]])
v = torch.tensor([3, 4, 5], dtype=torch.float32)
torch.sparse_coo_tensor(i, v)
Output 1
tensor(indices=tensor([[0, 1, 1],
[2, 0, 2]]),
values=tensor([3., 4., 5.]),
size=(2, 3), nnz=3, dtype=torch.float32, layout=torch.sparse_coo)
# nnz: number of nonzero - 存储非零值的数目
# layout: 表示在内存中的布局形式 - 先放一放
Test 2 尝试手动指定size
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])
Output 2
tensor(indices=tensor([[0, 1, 1],
[2, 0, 2]]),
values=tensor([3., 4., 5.]),
size=(2, 4), nnz=3, dtype=torch.float32, layout=torch.sparse_coo)
与tensor
方法类似,但as_tensor
可能不会拷贝源数据(共享内存),如果更改数据,可能引发未知的错误。不进行拷贝的条件如下:
ndarray
类型 且 数据所处设备为CPU
tensor
类型 且 数据类型、数据所处设备与默认设置一致建议不必管上述条件
可默认所有生成的数据都没有拷贝源数据
如果出现必须拷贝的地方使用copy.deepcopy()或 torch.clone()
应对
Test 1
# Test 1
a = np.array([1, 2, 3])
t = torch.as_tensor(a)
print(a, t)
t[0] = -1
print(a, t)
Output 1
a = [1 2 3]
t = tensor([1, 2, 3])
# 并没有发生拷贝
a = [-1 2 3]
t = tensor([-1, 2, 3])
Test 2
# Test 2
a = np.array([1, 2, 3])
t = torch.as_tensor(a, device=torch.device('cuda'))
print(a, t)
t[0] = -1
print(a, t)
Output 2
a = [1 2 3]
t = tensor([1, 2, 3], device='cuda:0')
# 没有发生拷贝:因为所处设备不一致
a = [1 2 3]
t = tensor([-1, 2, 3], device='cuda:0')
将ndarray
转换为tensor
共享内存
不能修改底层容器的大小 - The returned tensor is not resizable.
Test
a = np.array([1, 2, 3, 4])
t = torch.from_numpy(a)
print(a, t)
t[0] = -99
print(a, t)
Output
a = [1 2 3 4]
t = tensor([1, 2, 3, 4])
# 共享内存
a = [-99 2 3 4]
t = tensor([-99, 2, 3, 4])
构建复数tensor
Parameters
real
- 实部 - tensor
- float or double
imag
- 虚部 - tensor
- the same dtype as real part
Tips: real
和 imag
的数据类型必须要一致哦
类型转换
float
将转化为 torch.complex64
double
将转化为 torch.complex128
Test
real = torch.tensor([1, 2], dtype=torch.float)
imag = torch.tensor([3, 4], dtype=torch.float)
z = torch.complex(real, imag)
Output
z = tensor([1.+3.j, 2.+4.j])
z.type = torch.complex64
生成指定tensor
:生成tensor后并填入指定的数值
上面这三个方法用法大体一致
Parameters
size
- sequence of integers
empty
返回的未经初始化的值,仅仅分配了空间
为什么有的shape
的输入需要用tuple
表示,有的直接输入就行了呢
因为只有这一个位置参数,后续的参数输入需要指定参数名称,因此size不必封装为tuple
Test
a = torch.ones(1, 2, 3, dtype=torch.float)
b = torch.zeros(2)
c = torch.empty(1)
Output
a = tensor([[[1., 1., 1.],
[1., 1., 1.]]])
b = tensor([0., 0.])
c = tensor([4.2195e-08])
用所给的值fill_value
进行填充生成tensor
Parameters
size
- (sequence of integers)
fill_value
- 填充入tensor
的数值Test
a = torch.full((2, 3), fill_value=10.)
b = torch.full((2, 3), 10.)
Output
a = tensor([[10., 10., 10.],
[10., 10., 10.]])
b = tensor([[10., 10., 10.],
[10., 10., 10.]])
该类方法一共有四种:
zeros_like
ones_like
empty_like
full_like
简单理解如下:
torch.zeros_like(input) == torch.zeros(input.size(), dtype=input.dtype, layout=input.layout, device=input.device)
即利用输入tensor
的属性生成新的tensor
full_like
中的fill_value
仍需要输入哦~
Test
a = torch.ones(2, 2)
b = torch.zeros_like(a)
c = torch.full_like(a, 10)
Output
a = tensor([[1., 1.],
[1., 1.]])
b = tensor([[0., 0.],
[0., 0.]])
c = tensor([[10., 10.],
[10., 10.]])
这就和numpy
中的arange
一致啦,简单介绍下
Parameter
start
- 序列起始值 - 初始值为0end
- 序列结束值step
- 步长Test
# 输入 1 个参数 - start(0) end(10) step(1)
a = torch.arange(10)
# 输入 2 个参数 - start(3) end(5) step(1)
b = torch.arange(3, 5)
# 输入 3 个参数 - start(3) end(9) step(3)
c = torch.arange(3, 9, 3)
Output
a = tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
b = tensor([3, 4])
c = tensor([3, 6])
给定起始值s
、结束值e
与数值个数N
,生成线性等分向量。间距大小由数值个数N
决定
Test
# 输入 2 个参数 - start(3) end(5) size(100)
a = torch.linspace(10, 100)
# 输入 3 个参数 - start(10) end(100) size(10)
b = torch.linspace(10, 100, 10)
Output
a = tensor([ 10.0000, 10.9091, ... , 99.0909, 100.0000])
b = tensor([ 10., 20., 30., 40., 50., 60., 70., 80., 90., 100.])
和linspace
类似,看样例就行啦
Test
# torch.logspace(start=1, end=10,steps=10, base=2)
# 两个参数 start(1) end(2) steps(100) base(10)
a = torch.logspace(1, 2)
# 三个参数 start(1) end(3) steps(3) base(10)
b = torch.logspace(1, 3, 3)
# 四个参数 start(1) end(10) steps(10) base(2)
c = torch.logspace(1, 10, 10, 2)
Output
a = tensor([ 10.0000, 10.2353, ..., 97.7010, 100.0000])
b = tensor([ 10., 100., 1000.])
c = tensor([ 2., 4., 8., 16., 32., 64., 128., 256., 512., 1024.])
生成二维矩阵,对角线上为1,其它地方为0
Parameters
n
- int
- 矩阵的行数m
- default(n):
默认等于n
- 矩阵的列数,默认out, dtype, layout, device, requires_grad
eye
生成的可并不完全是单位阵哦,因为他的行数n
可以不等于列数m
Test
# 一个参数 n(2) m=n(2)
a = torch.eye(2)
# 两个参数 n(2) m(3)
b = torch.eye(2, 3)
Output
# Output
a = tensor([[1., 0.],
[0., 1.]])
b = tensor([[1., 0., 0.],
[0., 1., 0.]])
不在意tensor
中的数据,常用作各类tensor
操作测试
随机为tensor
填充数据,数据符合[0,1]
上的均匀分布 (
Parameters - size
- ints
一系列整数
rand_like
的用法与上文讲述一致
Test
a = torch.rand(2, 2)
b = torch.rand_like(a)
Output
a = tensor([[0.8395, 0.9932],
[0.3633, 0.6407]])
b = tensor([[0.0679, 0.1779],
[0.8335, 0.6131]])
随机为tensor
填充数据,数据符合标准正太分布 (
randn_like
的用法与上文讲述一致
Test
a = torch.randn(2, 2)
b = torch.randn_like(a)
Output
a = tensor([[ 1.3448, -0.3945],
[ 0.9157, -0.3566]])
b = tensor([[ 0.4449, 1.2405],
[ 1.3466, -0.0139]])
随机为tensor
填充数据,数据为整数且介于low
与high
之间(
Parameters
low
- default(0)
high
- int
size
- (ints)
- 为tuple
元祖的形式Test
# low(0) high(10) size(2, 3)
a = torch.randint(10, (3, 4))
# low(2) high(4) size(2, 3)
b = torch.randint(2, 4, (2, 3))
Output
a = tensor([[8, 8, 7],
[5, 5, 5]])
b = tensor([[3, 2, 2],
[3, 2, 3]])
伯努利分布 / 0-1
分布
简单理解(
tensor
中的每个元素做一次硬币实验得到的结果即为该元素的值
input
-tensor
- 输入表示为1的概率p
Test
p = torch.rand(2, 3)
b = torch.bernoulli(p)
Output
p = tensor([[0.4427, 0.9014, 0.1100],
[0.3531, 0.6641, 0.2243]])
b = tensor([[1., 1., 0.],
[0., 1., 0.]])
正太分布
Parameters
mean
- tensor
- 每个输出元素所在正太分布的均值std
- tensor
- 每个输出元素所在正太分布的标准差size
- (ints)
- mean
和 std
一致时可以给定size
Test 1
# 一一对应
a = torch.normal(mean=torch.arange(1., 11.), std=torch.linspace(0, 1, 10))
# 支持广播
b = torch.normal(mean=torch.rand(2), std=torch.rand(2, 2))
c = torch.normal(mean=torch.rand(2, 2), std=0.6)
Output 1
a = tensor([1.0000, 2.0786, 3.1498, 3.6431, 5.8021])
b = tensor([[ 0.9664, 0.4581],
[ 1.0587, -0.9274]])
c = tensor([[ 0.7546, -0.4395],
[ 0.9626, 0.4912]])
Test 2
a = torch.normal(0, 1, size=(2, 3))
Output 2
a = tensor([[-0.2457, -0.5191, 0.5012],
[-0.1364, -0.1612, 0.0908]])
泊松分布
Parameters - input
- tensor
- 单位时间(或单位面积)内随机事件的平均发生率
Test
rates = torch.randint(4, 10, (2, 3), dtype=torch.float)
p = torch.poisson(rates)
Output
rates = tensor([[5., 6., 6.],
[9., 5., 9.]])
p = tensor([[ 5., 6., 12.],
[11., 4., 6.]])
感谢你的阅读,如果文中有错误的地方,请一定要在评论区指出鸭~