pytorch学习笔记(一)

数据操作实现

1.arange() 用于输出从 0~所设值-1 的向量

1
2
3
4
x = torch.arange(12)  #输出从0到11的一维向量
x

#out: tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])

2.shape 用于访问张量的形状和张量中元素的总量

1
2
3
x.shape  #接上文代码,输出张量x的形状

#out: torch.Size([12])

3.numel 输出张量内包含的元素个数,输出为标量

1
2
3
x.numel  #输出张量x内元素的个数

#out: 12

4.reshape() 改变张量形状而不改变元素值和元素数量

1
2
3
4
5
6
X = x.reshape(3,4)  #把前面含12个元素的向量改为三行四列的矩阵
X

#out: tensor([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])

5.zeros()/ones() 创建全零/全一 张量

1
2
3
4
5
6
7
8
9
torch.zeros((2,3,4))  #创建2维的三行四列的矩阵

#out: 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.]]])

6.tensor() 可用于输入张量元素,可通过python的列表(或或者嵌套列表)来为张量中的每个元素赋值

1
2
3
4
5
torch.tensor([[2,1,4,3],[1,2,3,4],[4,3,2,1]])  #用列表为一个矩阵赋值

#out:tensor([[2, 1, 4, 3],
# [1, 2, 3, 4],
# [4, 3, 2, 1]])

7.常见标准运算符(+,-,,/和*)都可以被升级为按元素运算

​ exp() 函数可用来求自然指数,即 e^x

1
2
3
4
5
6
7
8
9
10
11
x = torch.tensor([1.,2,4,8])  #第一个元素1.为浮点数
y = torch.tensor([2,2,2,2])
x+y,x-y,x*y,x/y,x**y #对每个元素分别计算
torch.exp(x) #求x的自然指数

#out= (tensor([ 3., 4., 6., 10.]),
# tensor([-1., 0., 2., 6.]),
# tensor([ 2., 4., 8., 16.]),
#tensor([0.5000, 1.0000, 2.0000, 4.0000]),
#tensor([ 1., 4., 16., 64.]))
#tensor([2.7183e+00, 7.3891e+00, 5.4598e+01, 2.9810e+03])

8.cat() 函数用于将多个张量连接在一起

1
2
3
4
5
6
7
8
9
10
11
12
13
14
X = torch.arange(12,dtype=torch.float32).reshape(3,4)  #创建从0到11的三行四列的矩阵,且元素均为浮点型
Y = torch.tensor([[2.0,1,4,3],[1,2,3,4],[4,3,2,1]])
print(torch.cat((X,Y),dim=0)) #将X,Y矩阵沿0轴(纵向)连接
torch.cat((X,Y),dim=1) #将X,Y矩阵沿1轴(横向)连接

#out: (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.]]),
# 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.]]))

9.使用“==”判断两个张量中的每个元素是否相等

1
2
3
4
5
X == Y

#out: tensor([[False, True, False, True],
# [False, False, False, False],
# [False, False, False, False]])

10.sum() 函数可求张量内所有元素的和,产生一个只有一个元素的张量

1
2
3
X.sum()

#out: tensor(66.)

11.广播机制 形状不同的向量可以通过广播机制扩充成形状相同的形状进而计算。

1
2
3
4
5
6
7
8
9
10
11
12
13
a = torch.arange(3).reshape(3,1)  #创建一个从0-2的三行一列的矩阵
b = torch.arange(2).reshape(1,2) #创建一个从0-1的一行两列的矩阵
a,b

#out: (tensor([[0],
# [1],
# [2]]),
# tensor([[0, 1]]))

a+b
#out:tensor([[0, 1],
# [1, 2],
# [2, 3]])

12.元素索引 具体用法和列表的索引类似

1
2
3
4
5
6
7
8
9
10
11
12
13
14
X[0][2]  # 输出第一行第三列的元素
#out: tensor(2.)
X[0,2] #同上
X[0:2] #输出第一第二行(从冒号前值的到冒号后的值,但不包括冒号后的值)
#out: tensor([[0., 1., 2., 3.],
# [4., 5., 6., 7.]])
X[0:2,3] #先取出第一行和第二行,然后再取第四列的元素,输出
#out: tensor([[3.],
# [7.]])
X[0:2,1:3] #先取出第一行第二行,再取出第二列到第三列的元素,输出
#out: tensor([[1., 2.],
# [5., 6.]])
X[-1] #-1即为倒序输出,大体如上
#out: tensor([ 8., 9., 10., 11.])

​ 也可用索引的方法写入元素

1
2
3
4
5
6
7
8
9
10
11
12
X[1,2] = 9  #把第二行第三列的元素替换为9
X

#out: tensor([[ 0., 1., 2., 3.],
# [ 4., 5., 9., 7.],
# [ 8., 9., 10., 11.]])

X[0:2.:] = 12 #把第一行和第二行的元素替换为12,也可以写为X[0:2]

#out: tensor([[12., 12., 12., 12.],
# [12., 12., 12., 12.],
# [ 8., 9., 10., 11.]])

13.内存分配问题

​ 运行一些操作可能会导致为新结果分配内存

1
2
3
4
5
before = id(Y)  #id()是类似于C语言指针的东西,存放着变量的地址
Y = Y + X
id(Y) == before #判断Y的地址是否发生变化

#out: False

​ 执行原地操作

1
2
3
4
5
6
7
Z = torch.zeros_like(Y)  #创建一个和Y形状相似但全为0的张量Z
print('id(z):',id(Z)) #输出Z的地址
Z[:] = X + Y #把Z的元素全部替换为X+Y的值
print('id(Z):',id(Z)) #再次输出

#out: id(Z): 2825373601664
# id(Z): 2825373601664

​ 可以看到使用该方法没有造成新的地址出现

​ 如果在后续计算中没有重复使用X,我们也可以使用X[:] = X + Y或X + = Y来减少操作的内存开销

1
2
3
4
5
before = id(X)
X += Y #把计算后的值放进了X中
id(X) == before

#out: True

14.转换为Numpy张量 Numpy是常用的基础的python张量表示库

1
2
3
4
5
A = X.numpy()
B = torch.tensor(A)
type(A),type(B)

#out: (numpy.ndarray, torch.Tensor)

​ 将大小为1的张量转换为Python标量

1
2
3
4
a = torch.tensor([3.5])
a,a.item(),float(a),int(a) #分别将其转换为源形式、Numpy浮点数、浮点型、int型

#out: (tensor([3.5000]), 3.5, 3.5, 3)