张量的创建与常用方法
1 2
| import numpy as np import torch
|
1 2
| a1=np.array([[1,2,3],[4,5,6]]) a1
|
array([[1, 2, 3],
[4, 5, 6]])
1 2
| t3=torch.tensor([a1,a1]) t3
|
tensor([[[1, 2, 3],
[4, 5, 6]],
[[1, 2, 3],
[4, 5, 6]]], dtype=torch.int32)
torch.Size([2, 2, 3])
3
2
tensor([1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6], dtype=torch.int32)
1 2
| t1=torch.tensor([1,2]) t1
|
tensor([1, 2])
torch.Size([2])
tensor([[1],
[2]])
tensor([1, 2])
1 2
| t2=torch.tensor([1,2,3]) t2
|
tensor([1, 2, 3])
tensor([[1],
[2],
[3]])
tensor([1, 2, 3])
tensor([1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6], dtype=torch.int32)
tensor([[1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 5, 6]], dtype=torch.int32)
tensor([[1., 1., 1.],
[1., 1., 1.]])
tensor([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])
tensor([[1, 0],
[0, 2]])
tensor([[0.9925, 0.4613, 0.1272],
[0.6944, 0.3979, 0.4879]])
tensor([[ 0.7202, -1.3448, 1.1586],
[-1.3567, -0.6265, 0.6884]])
1
| torch.normal(2,3,size=(2,2))
|
tensor([[-1.8283, 0.6573],
[ 0.7957, 4.2425]])
1
| torch.randint(1,10,[2,4])
|
tensor([[2, 8, 1, 3],
[4, 6, 9, 5]])
tensor([0, 1, 2, 3, 4])
tensor([1.0000, 1.5000, 2.0000, 2.5000, 3.0000, 3.5000, 4.0000, 4.5000])
tensor([1., 3., 5.])
tensor([1.0000, 2.6000, 4.2000, 5.8000, 7.4000, 9.0000])
tensor([[8.1717e+20, 2.1274e+23, 8.5032e+20],
[1.0616e+21, 4.3445e-05, 2.0432e+20]])
tensor([[2, 2, 2, 2],
[2, 2, 2, 2]])
tensor([2, 2])
1
| torch.randint_like(t2,1,10)
|
tensor([5, 1, 5])
1 2
| t1=torch.arange(1,11) t1
|
tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype=int64)
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype=int64)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[tensor(1),
tensor(2),
tensor(3),
tensor(4),
tensor(5),
tensor(6),
tensor(7),
tensor(8),
tensor(9),
tensor(10)]
tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
1 2 3
| t1[0]=200 print(t1) print(t11)
|
tensor([200, 2, 3, 4, 5, 6, 7, 8, 9, 10])
tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
张量的索引、分片、合并以及维度调整
张量作为有序的序列,也是具备数值索引的功能,并且基本索引方法和python原生的列表、numpy中的数组基本一致,当然,所不同的是,pytorch中还定义了一种采用函数来进行索引的方式。
而作为pytorch中基本数据类型,张量即具备了列表、数组的基本功能,同时还充当着向量、矩阵、数据框等重要的数据结构,因此pytorch中也设置了非常完备的张量合并与变换的操作
1 2
| import torch import numpy as np
|
一维张量索引
一维张量的索引过程和python原生对象类型的索引一致,[start:end,step]
1 2
| t1=torch.arange(1,11) t1
|
tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
tensor([2, 3, 4, 5, 6, 7, 8])
tensor([2, 4, 6, 8])
tensor([ 2, 4, 6, 8, 10])
tensor([1, 3, 5, 7])
在张量的索引中,step位必须大于0
二维张量
二维张量可以视为两个一维张量组合而成,在实际的索引过程中,需要用逗号进行分割,分别不表示对哪个一维张量进行索引,以及具体的一维张量的索引
1 2
| t2=torch.arange(1,10).reshape(3,3) t2
|
tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
tensor(2)
tensor([1, 3])
tensor([[1, 3],
[7, 9]])
三维张量
即二维张量组成的三维张量
1 2
| t3=torch.arange(1,28).reshape(3,3,3) t3
|
tensor([[[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9]],
[[10, 11, 12],
[13, 14, 15],
[16, 17, 18]],
[[19, 20, 21],
[22, 23, 24],
[25, 26, 27]]])
tensor(14)
tensor([13, 14, 15])
tensor([[10, 11, 12],
[13, 14, 15],
[16, 17, 18]])
tensor([[10, 12],
[16, 18]])
torch.Size([3, 3, 3])
tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
1 2
| indices=torch.tensor([1,2]) indices
|
tensor([1, 2])
torch.Size([3, 3])
1
| torch.index_select(t2,0,indices)
|
tensor([[4, 5, 6],
[7, 8, 9]])
1
| torch.index_select(t2,1,indices)
|
tensor([[2, 3],
[5, 6],
[8, 9]])
tensor.view()方法
.view方法会返回一个类似视图的结果,通过。view方法还可以改变对象结构,生成一个不同结构,但是是“浅拷贝“
1 2
| t=torch.arange(6).reshape(2,3) t
|
tensor([[0, 1, 2],
[3, 4, 5]])
tensor([[0, 1],
[2, 3],
[4, 5]])
tensor([[1, 1, 1],
[1, 4, 5]])
tensor([[1, 1],
[1, 1],
[4, 5]])
tensor([[[1, 1, 1],
[1, 4, 5]]])
张量的分片函数
1. 分块 chunk函数
chunk函数能够按照某维度,对张量进行均匀切分,并返回原张量的视图
1 2
| t2=torch.arange(12).reshape(4,3) t2
|
tensor([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
1 2
| tc=torch.chunk(t2,4,dim=0) tc
|
(tensor([[0, 1, 2]]),
tensor([[3, 4, 5]]),
tensor([[6, 7, 8]]),
tensor([[ 9, 10, 11]]))
tensor([0, 1, 2])
(tensor([[1, 1, 2]]),
tensor([[3, 4, 5]]),
tensor([[6, 7, 8]]),
tensor([[ 9, 10, 11]]))
torch.Size([4, 3])
1 2
| tc=torch.chunk(t2,3,dim=1) tc
|
(tensor([[1],
[3],
[6],
[9]]),
tensor([[ 1],
[ 4],
[ 7],
[10]]),
tensor([[ 2],
[ 5],
[ 8],
[11]]))
1 2
| tc=torch.chunk(t2,3,dim=0) tc
|
(tensor([[1, 1, 2],
[3, 4, 5]]),
tensor([[ 6, 7, 8],
[ 9, 10, 11]]))
(tensor([[1, 1, 2]]),
tensor([[3, 4, 5]]),
tensor([[6, 7, 8]]),
tensor([[ 9, 10, 11]]))
2.拆分:split函数
split既能进行均分也能进行自定义切分,当然,和chunk函数一样,都是返回视图
1 2
| t2=torch.arange(12).reshape(4,3) t2
|
tensor([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
(tensor([[0, 1, 2],
[3, 4, 5]]),
tensor([[ 6, 7, 8],
[ 9, 10, 11]]))
1 2
| tc=torch.split(t2,[1,3],0) tc
|
(tensor([[0, 1, 2]]),
tensor([[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]]))
4
1 2
| tc[1][0]=torch.tensor([1,2,3]) tc
|
(tensor([[0, 1, 2]]),
tensor([[ 1, 2, 3],
[ 6, 7, 8],
[ 9, 10, 11]]))
3.拼接
张量的合并操作类似于列表的追加元素,可以拼接、也可以堆叠
tensor([[0., 0., 0.],
[0., 0., 0.]])
tensor([[1., 1., 1.],
[1., 1., 1.]])
tensor([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
tensor([[0., 0., 0.],
[0., 0., 0.],
[1., 1., 1.],
[1., 1., 1.]])
tensor([[0., 0., 0., 1., 1., 1.],
[0., 0., 0., 1., 1., 1.]])
- 堆叠函数:stack
和拼接不同,堆叠不是将元素拆分重组,而是简单的将各参与堆叠的对象分装到一个更高维度的张量里
堆叠要求张量形状都相同
tensor([[0., 0., 0.],
[0., 0., 0.]])
tensor([[1., 1., 1.],
[1., 1., 1.]])
tensor([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
1 2
| t3=torch.stack([torch.cat([a,c]),torch.cat([b,c])]) t3
|
tensor([[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]],
[[1., 1., 1.],
[1., 1., 1.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]]])
torch.Size([2, 5, 3])
tensor([[[0., 0., 0.],
[0., 0., 0.]],
[[1., 1., 1.],
[1., 1., 1.]]])
1
| torch.stack([a,b]).shape
|
torch.Size([2, 2, 3])
张量维度变换
通过reshape方法可以灵活调整张量的形状,在实际使用中往往要使用升维和降维操作
使用squeeze函数进行降维,使用unsqueeze函数进行升维
tensor([0, 1, 2, 3])
tensor([[0, 1, 2, 3]])
1
1 2
| a2=torch.zeros(1,2,1,2) a2
|
tensor([[[[0., 0.]],
[[0., 0.]]]])
1
| torch.unsqueeze(a2,dim=0)
|
tensor([[[[[0., 0.]],
[[0., 0.]]]]])
1
| torch.unsqueeze(a2,dim=0).shape
|
torch.Size([1, 1, 2, 1, 2])
1
| torch.unsqueeze(a2,dim=2).shape
|
torch.Size([1, 2, 1, 1, 2])
1
| torch.unsqueeze(a2,dim=3).shape
|
torch.Size([1, 2, 1, 1, 2])
1
| torch.unsqueeze(a2,dim=4).shape
|
torch.Size([1, 2, 1, 2, 1])