Pytorch入门

Pytorch Tutorial

向量

初始化

1
2
3
4
5
6
7
8
9
10
import torch
#print(torch.__version__)

#print(torch.cuda.is_available())
device = "cuda" if torch.cuda.is_available() else "cpu"
my_tensor = torch.tensor([[1, 2, 3],[4, 5, 6]], dtype=torch.float32,
device= device, requires_grad=True)


print(my_tensor)

另外一种初始化

1
2
3
4
5
6
7
8
x = torch.empty(size= (3, 3))
print(x)
x = torch.zeros(size= (3, 3))
x = torch.rand(size= (3, 3))
x = torch.eye(size= (3, 3)) #单位矩阵
x = torch.arange(start=0, end=5, step=1) #范围
x = torch.linspace(start=0.1, end=1, steps=10) #0.1 - 1 以内

linspace 和 arrange区别就是

arrange指明了首尾,步长,个数=尾-首/步长

linspace指明了首尾,个数,步长=尾-首/个数

1
2
3
4
5
x = torch.empty(size= (1, 5)).normal_(mean=0, std = 1) #正态分布
x = torch.empty(size=(1,5)).uniform_(0,1) #均匀分布,也就是随机
#但是制定了范围
x = torch.diag(torch.ones(3)) #对角线

1
2
3
4
5
#Array To Tensor
import numpy as np
np_array = np.zeros((5,5))
tensor = torch.from_numpy(np_array)
np_array = tensor.numpy()

向量运算和比较

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import torch

x = torch.tensor([1, 2, 3])
y = torch.tensor([7, 8, 9])

#Addtion
z1 = torch.empty(3)
torch.add(x, y, out=z1)
print(z1)

z2 = torch.add(x, y)

z3 = x + y

#Subtraction
z4 = x - y
print(z4)

#Division
z5 = torch.true_divide(x, y)

#inplace operation
t = torch.zeros(3)
t.add_(x)
t += x #t = t + x

#Expoentiation
z6 = x.pow(2)
z6 = x ** 2

#Simple comparison
z7 = x > 0
z7 = y < 0

#Matrix Multiplacation
x1 = torch.rand((2, 5))
x2 = torch.rand((5, 3))
x3 = torch.mm(x1, x2)
x3 = x1.mm(x2) #等价的

#Matrix exponentiation
matrix_exp = torch.rand(5, 5)
matrix_exp.matrix_power(3) #矩阵n次幂

#element wise mult
z8 = x * y
print(z8)

#dot product
z9 = torch.dot(x, y)
print(z9)

#batch Matrix Multipliction
batch = 32
n = 10
m = 20
p = 30

tensor1 = torch.rand((batch, n, m))
tensor2 = torch.rand((batch, m, p))
out_mm = torch.bmm(tensor1, tensor2)

# Broadcasting

x1 = torch.rand((5, 5))
x2 = torch.rand((1, 5))

z = x1 - x2
z = x1 ** x2
#也就是说,如果两个矩阵的维度不匹配,会自动扩展为相同列数和行数,再进行计算

#other
x = torch.tensor([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
sum_x = torch.sum(x, dim=0)
print(sum_x)
#具体来说,dim=0 指的是沿着第一维(即行的方向)进行操作,tensor([ 6, 15, 24])
#而 dim=1 则是沿着第二维(即列的方向)进行操作。tensor([12, 15, 18])

values, indices = torch.max(x, dim = 0) #取每行最大值 可以直接x.max(dim = 0)
values, indices = torch.min(x, dim = 1) #每列最小值

abs_x = torch.abs(x)

z = torch.argmax(x, dim = 0)
z = torch.argmin(x, dim = 1)

# 函数 功能 返回值
# torch.max 查找最大值 如果没有 dim 参数,返回最大值本身。如果指定 dim,返回一个元组,其中第一个元素是最大值,第二个元素是最大值的索引
# torch.argmax 查找最大值的索引 返回最大值的索引(仅返回索引,不返回最大值本身)

mean_x = torch.mean(x.float(), dim = 0) #平均值
z = torch.eq(x, y) #判断对应位置是否相等

sorted_x, indices = torch.sort(x, dim = 0, descending = False) #升序排序

z = torch.clamp(x, min = 0, max = 10) #将向量小于0的变为0,大于10的变为10

向量下标、取值、赋值

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import torch

batch_size = 10
features = 25
x = torch.rand((batch_size, features))
#x 将是一个 10 行 25 列的张量,形状是 (10, 25)
print(x.shape)
print(x[0].shape) #x[0, :]也就是行向量维数
print(x[:, 0].shape) #提取所有行的第0列元素,也就是列向量的维数
#torch.Size([10, 25])
# torch.Size([25])
# torch.Size([10])
print(x[2, 0:10])
x[0 , 0] = 100

#打印特定的行
x = torch.arange(10)
indices = [2, 4, 7]
print(x[indices])

#Fancy index
x = torch.rand((3, 5))
rows = torch.tensor([1, 0])
cols = torch.tensor([4, 0])
print(x)
print(x[rows, cols]) #rows的第一个元素和cols的第一个元素作为坐标
#同理对应第二个元素
#最终给出两个tensor
# tensor([[0.4546, 0.8152, 0.0296, 0.5971, 0.8530],
# [0.3312, 0.4452, 0.5283, 0.3958, 0.0696],
# [0.6694, 0.0788, 0.6363, 0.8018, 0.7811]])
# tensor([0.0696, 0.4546])

#More advanced
import torch
x = torch.arange(10)
print(x[(x < 2) | (x > 8)]) #设定输出性质
#tensor([0, 1, 9])

print(x[x.remainder(2) == 0 ]) #%2=0的数
#tensor([0, 2, 4, 6, 8])

print(torch.where(x > 5, x, x*2)) #类似三目运算
#大于5的依然是x
#否则乘2
#tensor([ 0, 2, 4, 6, 8, 10, 6, 7, 8, 9])

print(torch.tensor([0, 0, 1, 2, 2, 5, 6, 6]).unique()) #取不重复出现的唯一值
print(x.ndimension()) #维度
print(x.numel()) #个数
# tensor([0, 1, 2, 5, 6])
# 1
# 10

向量变换

1
2
3
4
5
import torch

x = torch.range(9)
x_33 = torch.view(3, 3)
x_33 = torch.reshape(3, 3)
特性 view reshape
内存要求 原张量必须是连续的 无需连续内存,支持非连续张量
行为 如果内存不连续,抛出错误 会在必要时返回副本,确保连续性
返回值 返回视图(可能共享内存) 返回新张量(可能是副本)
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
28
29
30
31
32
y = x_33.t() #转置
#需要注意的是,转置在内存上看来就是进行了跳跃
#所以y的元素的内存位置不再试连续的,所以使用y.view(9)将会出现错误
#解决方法,1.reshape;2.y.contiguous().view(9)

#tensors shape change
import torch
x1 = torch.rand((2, 5))
x2 = torch.rand((2, 5))
print(torch.cat((x1, x2), dim = 0).shape) #拼接两个矩阵,dim= 0 ,做行方向的拼接
print(torch.cat((x1, x2), dim = 1).shape) #做列方向的拼接
# torch.Size([4, 5])
# torch.Size([2, 10])

z = x1.view(-1) #直接将x1展开为一维的向量,不用自己计算应该是多大
print(z.shape)
#torch.Size([10])

batch = 64
x = torch.rand((batch, 2, 5))
z = x.permute(0, 2, 1) #permute将x的维度(0,1,2)位置进行调换
#换为(0,2,1)
print(z.shape)
#torch.Size([64, 5, 2])

x = torch.arange(10)
print(x.unsqueeze(0).shape) #unsqueeze在指定位置添加一个维度
print(x.unsqueeze(1).shape)
#torch.Size([1, 10])
#torch.Size([10, 1])

z = x.squeeze(1) #同理可以消除一个维度