少女祈祷中...

张量

张量是什么

张量(tensor)是深度学习中最重要、最基本的一种数据结构,由数字组成,类似于Python中的列表,也可以进行多层嵌套。说得通俗一些,就是向量里面继续嵌套向量,再嵌套向量。所以数学中的向量、矩阵都可以称为张量。

列举几个张量

这里用列表的格式表示张量:
a = [1,2,3] 是一个形状为[3]的一维张量。
b = [[1,3,1,2],
  [2,5,4,3]] 是一个形状为[2,4]的二维张量。
c = [[[1,2,5,6],
  [3,4,3,2],]
  [[6,7,3,2],
  [1,2,3,2]]] 是一个形状为[2,2,4]的三维张量。

张量的基本操作

Pytorch

Pytorch是一个深度学习框架,作用就是它能把绝大部分的脏活累活替你干了。用Pytorch也可以轻而易举地操纵张量。

在Pytorch中张量的操作

以下操作仅作为速查表,具体细节需参考更详细资料。

构建从0到n-1的行向量

虽然叫的时候叫Pytorch,但导入模块的时候用的是torch。
注意不要把torch像什么pandas,numpy这种一样简写成pd,np,torch就是torch,不要图懒省事,或许是大家约定好了都不简写。

1
2
3
import torch
x = torch.arange(12)
x
1
## tensor([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

访问张量的大小和形状

1
x.shape
1
## torch.Size([12])
1
x.numel()
1
## 12

改变张量的形状

-1可以自动计算剩余维度大小。

1
x.reshape(3,4)
1
2
3
## tensor([[ 0,  1,  2,  3],
## [ 4, 5, 6, 7],
## [ 8, 9, 10, 11]])
1
x.reshape(2,-1)
1
2
## tensor([[ 0,  1,  2,  3,  4,  5],
## [ 6, 7, 8, 9, 10, 11]])

生成元素全为0或全为1的张量

1
torch.zeros((2,3,4))
1
2
3
4
5
6
7
## tensor([[[0., 0., 0., 0.],
## [0., 0., 0., 0.],
## [0., 0., 0., 0.]],
##
## [[0., 0., 0., 0.],
## [0., 0., 0., 0.],
## [0., 0., 0., 0.]]])
1
torch.ones((3,5))
1
2
3
## tensor([[1., 1., 1., 1., 1.],
## [1., 1., 1., 1., 1.],
## [1., 1., 1., 1., 1.]])

生成元素为正态分布的随机张量

这个方法生成的张量遵从标准正态分布,不信的话你可以算算它的均值和方差。

1
torch.randn(3,4)
1
2
3
## tensor([[ 1.0705,  0.6769, -0.1804,  0.0617],
## [ 0.7141, 1.7879, -0.4943, 0.5468],
## [-0.0972, -0.1657, -0.4988, 0.3958]])

列表创建张量

这是最常容易理解的张量创建方式。

1
torch.tensor([[2,1,4,3],[1,2,3,4],[4,3,2,1]])
1
2
3
## tensor([[2, 1, 4, 3],
## [1, 2, 3, 4],
## [4, 3, 2, 1]])

注意,括号里是一个列表变量也可以。

两个张量按某一维度连接

1
2
3
X = torch.arange(12).reshape((3,4))
Y = torch.tensor([[2,1,4,3],[1,2,3,4,],[4,3,2,1]])
torch.cat((X,Y),dim=0)
1
2
3
4
5
6
## tensor([[ 0,  1,  2,  3],
## [ 4, 5, 6, 7],
## [ 8, 9, 10, 11],
## [ 2, 1, 4, 3],
## [ 1, 2, 3, 4],
## [ 4, 3, 2, 1]])
1
torch.cat((X,Y),dim=1)
1
2
3
## tensor([[ 0,  1,  2,  3,  2,  1,  4,  3],
## [ 4, 5, 6, 7, 1, 2, 3, 4],
## [ 8, 9, 10, 11, 4, 3, 2, 1]])

两个张量是否相等

判断两个形状相同的张量对应位置元素是否相等,生成一个新的bool类型张量。

1
X
1
2
3
## tensor([[ 0,  1,  2,  3],
## [ 4, 5, 6, 7],
## [ 8, 9, 10, 11]])
1
Y
1
2
3
## tensor([[2, 1, 4, 3],
## [1, 2, 3, 4],
## [4, 3, 2, 1]])
1
X == Y
1
2
3
## tensor([[False,  True, False,  True],
## [False, False, False, False],
## [False, False, False, False]])

张量按某一维度求和

不给维度dim就是全求和。

1
X
1
2
3
## tensor([[ 0,  1,  2,  3],
## [ 4, 5, 6, 7],
## [ 8, 9, 10, 11]])
1
X.sum(dim=0)
1
## tensor([12, 15, 18, 21])
1
X.sum()
1
## tensor(66)

对张量中的一个或多个元素访问或修改

可以用[-1]选择最后一个元素,可以用[1:3]选择第二个和第三个元素。除读取外,我们还可以通过指定索引来将元素写入矩阵。如果我们想为多个元素赋值相同的值,我们只需要索引所有元素,然后为它们赋值。例如,[0:2,:]访问第1行和第2行,其中”:”代表沿轴1(列)的所有元素。

1
X
1
2
3
## tensor([[ 0,  1,  2,  3],
## [ 4, 5, 6, 7],
## [ 8, 9, 10, 11]])
1
print('X[-1] = ',X[-1])
1
## X[-1] =  tensor([ 8,  9, 10, 11])
1
print('X[1:3] = ',X[1:3])
1
2
## X[1:3] =  tensor([[ 4,  5,  6,  7],
## [ 8, 9, 10, 11]])
1
2
X[1,2] = 9
print(X)
1
2
3
## tensor([[ 0,  1,  2,  3],
## [ 4, 5, 9, 7],
## [ 8, 9, 10, 11]])
1
2
X[0:2,:] = 12
X
1
2
3
## tensor([[12, 12, 12, 12],
## [12, 12, 12, 12],
## [ 8, 9, 10, 11]])

张量转其他类型

张量与numpy数组互相转换

1
2
3
A = X.numpy()
B = torch.tensor(A)
A
1
2
3
## array([[12, 12, 12, 12],
## [12, 12, 12, 12],
## [ 8, 9, 10, 11]], dtype=int64)
1
B
1
2
3
## tensor([[12, 12, 12, 12],
## [12, 12, 12, 12],
## [ 8, 9, 10, 11]])

大小为1的张量转标量

1
2
a = torch.tensor([3.5])
a
1
## tensor([3.5000])
1
a.item()
1
## 3.5

Dataframe转numpy再转张量

Dataframe是pandas中从csv表格中读取的数据格式,这里假设df是一个Dataframe。

1
2
X_tensor = torch.from_numpy(df).float()
Y_tensor = torch.tensor(Y.values,dtype=torch.long)