张量的创建:
1.直接创建:
torch.tensor(data, dtype=None, device=None, requires_grad=False, pin_memory=False)
从data创建tensor
data: 数据,可以是list,numpy
dtype: 数据类型,默认与data的一致
device: 所在设备,cuda/cpu
requires_grad: 是否需要梯度
pin_memory: 是否存于锁页内存
torch.tensor([[1,4],[2,6],[6,4]])
#torch([[1,4],[2,6],[6,4]])
从numpy创建tensor
torch.from_numpy(ndarray)
功能:从numpy创建tensor
注意事项:从torch.from_numpy创建的tensor于原ndarray共享内存,当修改其中一个数据,另一个也将会被改动。
a=np.array([[1,2,3],[4,5,6]])
t=torch.from_numpy(a)
t
#tensor([[1, 2, 3],
[4, 5, 6]])
2.依据数值创建
torch.zeros(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
size创建全0张量
size: 张量的形状,如(3, 3)、(3, 224, 224)
out: 输出的张量
layout: 内存中布局形式,有strided, sparse_coo等
device: 所在设备,gpu/cpu
requires_grad: 是否需要梯度
torch.zeros(2,3)
#tensor([[0., 0., 0.],
[0., 0., 0.]])
torch.zeros_like(input, dtype=None, layout=None, device=None, requires_grad=False)
依input形状创建全0张量
input: 创建与input同形状的全0张量
dtype: 数据类型
layout: 内存中布局形式
input=torch.ones(2,3)
torch.zeros_like(input)
#tensor([[0., 0., 0.],
[0., 0., 0.]])
torch.ones和torch.ones_like用法和上述zeros的一样
torch.full(size, fill_value, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
torch.full_like()
和ones和zeros的用法一样,不过生成的值是fill_value
torch.arange(start=0, end. step=1, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
功能:创建等差的1维张量
start: 数列起始值
end: 数列“结束值”
step: 数列公差,默认为1注意事项:数值区间为[𝑠𝑡𝑎𝑟𝑡,𝑒𝑛𝑑)是左闭右开
torch.linspace(start, end, steps=100, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False),解释类似上面
torch.logspace(start, end, steps=100, base=10.0, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
功能: 创建对数均分的1维张量
注意事项:长度为steps,底为base
start: 数列起始值end: 数列结束值steps: 数列长度base: 对数函数的底,默认为10
torch.logspace(start=0.1, end=1.0, steps=5)
#
tensor([ 1.2589, 2.1135, 3.5481, 5.9566, 10.0000])
3.依概率分布创建张量
torch.normal(mean, std, out=None)
功能:生成正态分布(高斯分布),mean: 均值,std: 标准差
有四种模式:
mean为标量,std为标量
mean为标量,std为张量
mean为张量,std为标量
mean为张量,std为张量
torch.normal(mean=torch.arange(1,11),std=torch.arange(1,0,-0.1))
#此情况中mena和std都是张量生成10个正态分布的数
#tensor([ 1.3177, 2.1195, 3.1099, 4.1684, 5.8373, 6.6735, 7.9753, 8.0608,
9.4901, 10.2026])
torch.randn(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)生成标准正态分布,size是张量的形状
torch.randn(2,3)
#tensor([[-0.3172, -0.8660, 1.7482],
[-0.2759, -0.9755, 0.4790]])
torch.rand(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)在区间[0,1)[0,1)上,生成均匀分布。
torch.rand(2, 3)
#tensor([[0.1023, 0.0844, 0.4041],
[0.4924, 0.5558, 0.5627]])
torch.randint(low=0, high, size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)区间 $[low, high)$ 生成整数均匀分布
torch.randint(3, 10, (2, 2))
#tensor([[4, 8],
[7, 8]])
torch.randperm(n, out=None, dtype=torch.int64, layout=torch.strided, device=None, requires_grad=False)生成从0到n-1的随机排列,张量的长度为n(该功能和用法和matlab中的randperm类似)
torch.randperm(4)
#tensor(1,0,2,3)
torch.bernoulli(input, *, generator=None, out=None),以input为概率,生成伯努利分布(0-1分布,两点分布),input:概率值。
a=torch.empty(3,3).uniform_(0,1)
a
#tensor([[0.9041, 0.2509, 0.0461],
[0.3858, 0.9531, 0.6206],
[0.4684, 0.3571, 0.9390]])
torch.bernoulli(a)
#tensor([[0., 1., 1.],
[1., 1., 1.],
[0., 1., 1.]])
张量的操作:
张量的拼接和切分
torch.cat(tensors, dim=0, out=None)功能:将张量按维度dim进行拼接
x = torch.randint(1,7,(2,3))
#tensor([[1, 3, 5],
[5, 2, 1]])
torch.cat((x,x,x),1)
#tensor([[1, 3, 5, 1, 3, 5, 1, 3, 5],
[5, 2, 1, 5, 2, 1, 5, 2, 1]])
torch.cat((x,x,x),0)
#tensor([[1, 3, 5],
[5, 2, 1],
[1, 3, 5],
[5, 2, 1],
[1, 3, 5],
[5, 2, 1]])
torch.stack(tensors, dim=0, out=None) 功能:在新创建的维度dim上进行拼接
torch.stack((x,x),0)
#tensor([[[1, 3, 5],
[1, 3, 5]],
[[5, 2, 1],
[5, 2, 1]]])
torch.stack((x,x),1)
#tensor([[[1, 3, 5],
[1, 3, 5]],
[[5, 2, 1],
[5, 2, 1]]])
#和cat相比,stack进行拼接的时候将二维变成三维,而cat仍是二维
torch.chunk(input, chunks, dim=0)
功能:将张量按维度dim进行平均切分
返回值:张量列表
注意事项:若不能整除,最后一份张量小于其他张量
input:要切分的张量
chunks:要切分的份数
dim:要切分的维度
print(x)
torch.chunk(x,3,1)
#tensor([[1, 3, 5],
[5, 2, 1]])
#(tensor([[1, 3],
[5, 2]]), tensor([[5],
[1]]))
#上述是将x沿列切成2分。
torch.chunk(x,2,0)#将x沿行切成2分
#(tensor([[1, 3, 5]]), tensor([[5, 2, 1]]))
torch.split(tensor, split_size_or_sections, dim=0)
- 功能:将张量按维度dim进行切分
- 返回值:张量列表
- tensor:要切分的张量
- split_size_or_sections:为int时,表示每一份的长度;为list时,按list元素切分
- dim:要切分的维度
z=torch.randint(1,20,(4,3))
#tensor([[ 5, 14, 11],
[11, 5, 13],
[17, 16, 11],
[13, 4, 18]])qiege
torch.split(z,3,0)#将z沿行切分,每一份长度为3,最后一份的时候没有元素了,所以只有长度为1
#(tensor([[ 5, 14, 11],
[11, 5, 13],
[17, 16, 11]]), tensor([[13, 4, 18]]))
torch.split(z,2,1)#按照列来切分,每份长度为2,最后一份只有1列
#(tensor([[ 5, 14],
[11, 5],
[17, 16],
[13, 4]]), tensor([[11],
[13],
[11],
[18]]))
张量索引:
torch.index_select(input, dim, index, out=None)
功能:在维度dim上,按index索引数据
返回值:依index索引数据拼接的张量index:要索引的张量
dim:要索引的维度
index:要索引数据的序号
x = torch.randint(1,20,(5, 4))
(x)
#tensor([[12, 11, 10, 11],
[12, 18, 13, 13],
[ 2, 18, 2, 18],
[ 6, 1, 12, 10],
[ 2, 17, 16, 10]])
indices = torch.tensor([0,2,1])
torch.index_select(x, 0, indices)
tensor([[12, 11, 10, 11],
[ 2, 18, 2, 18],
[12, 18, 13, 13]])
#按照行的方向来索引,索引值是indices里面的值(即索引值
#分别为0,2,1的行)
torch.masked_select(input, mask, out=None)
功能:按mask中的True进行索引
返回值:一维张量input:要索引的张量
mask:与input同形状的布尔类型张量
x = torch.randint(1,20,(5, 4))
#tensor([[14, 14, 6, 4],
[12, 14, 1, 2],
[10, 9, 7, 9],
[ 4, 10, 16, 16],
[ 4, 2, 7, 11]])
mk=x>10
torch.masked_select(x,mk)
#tensor([14, 14, 12, 14, 16, 16, 11])
张量变换:
tensor的形状大小:size()和shape等价
t=torch.tensor([[1,2,3],[4,5,6]])
t.size()#torch.Size([2, 3])
t.shape#torch.Size([2, 3])
torch.tensor和torch.Tensor:
torch.Tensor是torch.empty和torch.tensor之间的一种混合,但是,当传入数据时,torch.Tensor
使用全局默认dtype(FloatTensor),而torch.tensor是从数据中判断数据类型。
torch.tensor(1)返回一个固定值1,而torch.Tensor(1)返回一个大小为1的张量,它是随机初始化的
t1=torch.Tensor(1)
t2=torch.tensor(1)
print('t1的值是{},t1的数据类型是{}'.format(t1,t1.type()))
print('t2的值是{},t2的类型{}'.format(t2,t2.type()))
#t1的值是tensor([5.2293e-08]),t1的数据类型是torch.FloatTensor
@t2的值是1,t2的类型torch.LongTensor
修改tensor形状
torch.size()返回张量的shape属性值
torch.numel()计算tensor的元素个数
torch.view(*shape),修改Tensor的shape,与Reshape类似,但是View返回的对象与源Tensor共享内存,修改一个,另外一个同时修改,Reshape将生成新的Tensor,而且不要求源Tensor是连续的,View(-1)展平数组。
torch.resize(),类似view,但在size超出时会重新分配内存空间
torch.item,若Tensor为单元素,则返回Python的标量
torch.unsqueeze,在指定维度增加一个'1'
torch.squeeze,在指定维度压缩一个'1'
t=torch.tensor([[1,2,3],[4,5,6]])
t.size()#torch.Size([2, 3])
t.dim()#2,查看t的维度
t.numel()#6
x=t.view(-1)#tensor([1, 2, 3, 4, 5, 6]),将t展开为1维向量
x=t.view([3,2])#tensor([[1, 2],
#[3, 4],
#[5, 6]])
z=torch.unsqueeze(x,0)
#tensor([[[1, 2],
[3, 4],
[5, 6]]])
z.shape #torch.size([1, 3, 2]),如果x后面参数变为1则输出变为([3,1, 2]
#如果x后面参数变为2则输出变为([3,2,1]
#添加的位置,和参数有关
虽然z和x元素值相同,但是维度不同
x.eq(z)#逐元素对比
#tensor([[[True, True],
[True, True],
[True, True]]])
x.equal(z)#判断两个张量是否相同
#False
torch.view和torch.reshape的区别:
reshape()课由torch.reshape(),也可以由torch.Tensor.reshape()调用,但是view()只可由torch.Tensor.view()来调用。对于一个将被view的Tensor,新的size必须与原来的size和stride兼容,否则在view之前必须调用conyiguous()方法。
如果只想重塑张量就用torch.reshape,如果还关注内存使用情况并希望确保两个张量共享相同的数据,就用torch.view。
torch.transpose(input, dim0, dim1)
功能:交换张量的两个维度
input:要交换的张量
dim0:要交换的维度
dim1:要交换的维度
x = torch.randint(1,20,(2, 3))
#tensor([[ 7, 17, 5],
[ 4, 11, 17]])
torch.transpose(x, 0, 1)
#tensor([[ 7, 4],
[17, 11],
[ 5, 17]])
torch.t(input)功能:2维张量转置,对矩阵而言,等价于torch.transpose(input, 0, 1)