文章

Pytorch

Pytorch笔记

Pytorch

一、Tensor——Pytorch的数组

Tensor的定义

1
2
3
4
5
6
7
import torch

x = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32)

print(x)
print(x.shape)
print(x.dtype)

Tensor与Numpy的相互转换

1
2
a = x.numpy()
a = x.detach().cpu().numpy()

二、Pytorch的矩阵运算

矩阵乘法

1
2
3
4
5
6
7
8
x = torch.tensor([[1., 2.],
                  [3., 4.]])

W = torch.tensor([[1., 0.],
                  [0., 1.]])

y = x @ W
print(y)

逐元素乘法

1
x * W

求和

1
torch.sum(x)

按行/列求和

1
2
torch.sum(x, dim=0)  # 按第0维求和,结果是每一列的和
torch.sum(x, dim=1)  # 按第1维求和,结果是每一行的和

三、自动求导

1
2
3
4
5
6
7
8
9
import torch

x = torch.tensor(2.0, requires_grad=True)

y = x ** 2 + 3 * x + 1

y.backward()

print(x.grad)

四、用PyTorch搭建神经网络

1
2
3
4
5
6
7
8
9
10
11
import torch
import torch.nn as nn

class LinearModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(2, 1)

    def forward(self, x):
        y = self.linear(x)
        return y

五、常见激活函数

函数形式:

1
2
3
torch.relu(x)
torch.sigmoid(x)
torch.tanh(x)

模块形式:

1
2
3
nn.ReLU()
nn.Sigmoid()
nn.Tanh()
1
2
3
4
5
6
model = nn.Sequential(
    nn.Linear(2, 4),
    nn.ReLU(),
    nn.Linear(4, 1),
    nn.Sigmoid()
)

六、损失函数

回归问题常用均方误差

1
loss_fn = nn.MSELoss()

二分类

1
2
3
4
5
6
7
8
model = nn.Sequential(
    nn.Linear(2, 4),
    nn.ReLU(),
    nn.Linear(4, 1),
    nn.Sigmoid()
)

loss_fn = nn.BCELoss()

更推荐的写法

1
2
3
4
5
6
7
model = nn.Sequential(
    nn.Linear(2, 4),
    nn.ReLU(),
    nn.Linear(4, 1)
)

loss_fn = nn.BCEWithLogitsLoss()

多分类

1
2
3
4
5
6
7
model = nn.Sequential(
    nn.Linear(10, 32),
    nn.ReLU(),
    nn.Linear(32, 3)
)

loss_fn = nn.CrossEntropyLoss()

七、优化器

1
2
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

八、PyTorch 标准训练三步

1
2
3
4
5
6
# 清空旧梯度
optimizer.zero_grad()
# 反向传播
loss.backward()
# 更新参数
optimizer.step()

九、一个完整的二分类例子

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
import torch
import torch.nn as nn

# 1. 准备数据
x_train = torch.tensor([
    [0., 0.],
    [0., 1.],
    [1., 0.],
    [1., 1.]
], dtype=torch.float32)

y_train = torch.tensor([
    [0.],
    [1.],
    [1.],
    [0.]
], dtype=torch.float32)

# 2. 定义模型
model = nn.Sequential(
    nn.Linear(2, 4),
    nn.ReLU(),
    nn.Linear(4, 1)
)

# 3. 定义损失函数和优化器
loss_fn = nn.BCEWithLogitsLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)

# 4. 训练
for epoch in range(1000):
    logits = model(x_train)
    loss = loss_fn(logits, y_train)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

# 5. 预测
with torch.inference_mode():
    logits = model(x_train)
    y_prob = torch.sigmoid(logits)
    y_pred = (y_prob >= 0.5).float()

print(y_prob)
print(y_pred)

十、训练模式和测试模式

训练时:

1
model.train()

测试时:

1
2
3
model.eval()
with torch.inference_mode():
    y_pred = model(x_test)

十一、GPU的基本用法

需要把模型和数据都移动到同一个设备

1
2
3
4
5
6
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

model = model.to(device)

x_train = x_train.to(device)
y_train = y_train.to(device)

十二、保存和加载模型

1
torch.save(model.state_dict(), "model.pth")
1
2
3
4
5
6
7
8
model = nn.Sequential(
    nn.Linear(2, 4),
    nn.ReLU(),
    nn.Linear(4, 1)
)

model.load_state_dict(torch.load("model.pth"))
model.eval()

十三、完整的PyTorch流程

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
import torch
import torch.nn as nn

# 数据
x_train = torch.tensor(x_train, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.float32)

# 模型
model = nn.Sequential(
    nn.Linear(2, 16),
    nn.ReLU(),
    nn.Linear(16, 1)
)

# 损失函数和优化器
loss_fn = nn.BCEWithLogitsLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 训练
for epoch in range(100):
    model.train()

    logits = model(x_train)
    loss = loss_fn(logits, y_train)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if epoch % 10 == 0:
        print(epoch, loss.item())

# 测试
model.eval()
with torch.inference_mode():
    logits = model(x_train)
    y_prob = torch.sigmoid(logits)
    y_pred = (y_prob >= 0.5).float()
本文由作者按照 CC BY 4.0 进行授权