参考网址:

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
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#首先引入一大堆库
import torch
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear
import time


#在pytorch官网找合适的数据集
#下载数据用torchvision.datasets.xxx("下载目标文件名称",是否是训练集,是否下载,转换格式的函数)
train_data=torchvision.datasets.CIFAR10("dataset",train=True,download=True,
transform=torchvision.transforms.ToTensor())
test_data=torchvision.datasets.CIFAR10("dataset",train=False,download=True,
transform=torchvision.transforms.ToTensor())
#数据集的大小
train_data_size=len(train_data)
test_data_size=len(test_data)

#加载数据和一捆数据的大小,用DataLoader(下载的数据,一捆的大小)
train_dataloader=DataLoader(train_data,batch_size=64)
test_dataloader=DataLoader(test_data,batch_size=64)

#定义神经网络的模型,继承nn库里的Module模型
class Model(nn.Module):
def __init__(self):
super().__init__()#父类初始化
#用Sequential()串联要用到的层,pytorch官网有所有层的参数和用法,Ctrl+P可以查看函数的参数
self.model1 = Sequential(
Conv2d(3, 32, 5, 1,2),
MaxPool2d(2),
Conv2d(32, 32, 5, 1,2),
MaxPool2d(2),
Conv2d(32, 64, 5,1,2),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10)
)
#向前传播,Module自带的,要定义实现
def forward(self, x):
x = self.model1(x)
return x

model=Model()#创建模型的具体实例对象
#判断GPU是否能用
# 一般是模型、损失函数、数据可以调用.cuda()
if torch.cuda.is_available():
model=model.cuda()

#定义损失函数,pytorch官网找一个
loss_fn=nn.CrossEntropyLoss()
loss_fn=loss_fn.cuda()

#定义学习率
learning_rate=1e-2
#定义更新参数的函数,也是pytorch官网找一个
optimizer=torch.optim.SGD(model.parameters(),lr=learning_rate)

#训练的次数和测试的次数
total_train_step=0
total_test_step=0

#训练的总次数,不是越大越好,少了会欠拟合,多了会过拟合
epoch=30

writer=SummaryWriter("logs_train")#在tensorboard里画图

start_time=time.time()#纪录训练开始的时间

for i in range(epoch):
print("------第 {} 轮训练开始------".format(i+1))
model.train()#开启模型的训练模式
for data in train_dataloader:
imgs,targets=data#图像和标签
imgs=imgs.cuda()
targets=targets.cuda()
outputs=model(imgs)#会自动调用Module里的__call__函数和forwa函数
loss=loss_fn(outputs,targets)

optimizer.zero_grad()#梯度清0
loss.backward()#反向传播求梯度
optimizer.step()#梯度下降,更新参数

total_train_step+=1
if total_train_step %100 ==0:#打印阶段性的训练数据
end_time=time.time()
print(end_time-start_time)
print("训练次数:{},Loss:{}".format(total_train_step,loss.item()))
writer.add_scalar("train_loss",loss.item(),total_train_step)

model.eval()#开启测试模式
total_test_loss=0
total_accuracy=0
#用no_grad()就不会更新参数了
with torch.no_grad():
for data in test_dataloader:
imgs,targets=data
imgs=imgs.cuda()
targets=targets.cuda()
outputs=model(imgs)
loss=loss_fn(outputs,targets)
total_test_loss+=loss.item()
#'1'表示横向,‘0’表示纵向
accuracy=(outputs.argmax(1)==targets).sum()#统计预测正确的样本数量
total_accuracy+=accuracy

print("整体测试集上的Loss: {}",format(total_test_loss))
print("整体测试集上的正确率: {}",format(total_accuracy/test_data_size))
#画图到tensorboard上
#要在 Anaconda 的终端上激活pytorch环境后运行tensorboard --logdir=logs ,logs是创建的文件名
#增加函数图像
#writer.add_image是增加图片
writer.add_scalar("test_loss",total_test_loss,total_test_step)
writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)
total_test_step+= 1
#保存模型,这里是全部保存,不够安全,更好的方法是只保存参数
torch.save(model,"model_{}.pth".format(i))
print("模型已保存")

#不要忘了关闭
writer.close()



二、测试模型

随便找个图片来

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
import torch
import torchvision
from PIL import Image
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear

#标签
classes = [
'airplane', 'automobile', 'bird', 'cat', 'deer',
'dog', 'frog', 'horse', 'ship', 'truck'
]

image_path= "imgs/cat.png"#随便弄一个图片到创建的文件里
image=Image.open(image_path)
#png是4个通道,除了RGB3个通道,还有一个透明度通道,可以适应png、jpg各种图片的格式
image=image.convert("RGB")

#要转化成符合模型的参数的size
transform=torchvision.transforms.Compose([torchvision.transforms.Resize((32,32)),
torchvision.transforms.ToTensor()])


image=transform(image)
image=image.cuda()

#重新定义一遍,就不会在调用训练好的模型是很麻烦,不用import包含模型定义的文件
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()

self.model1 = Sequential(
Conv2d(3, 32, 5, 1,2),
MaxPool2d(2),
Conv2d(32, 32, 5, 1,2),
MaxPool2d(2),
Conv2d(32, 64, 5,1,2),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10)
)

def forward(self, x):
x = self.model1(x)
return x

#用load()选择训练好的模型加载,由于保存的不是是参数,所以weights_only=False
model=torch.load("model_29.pth",weights_only=False)

image=torch.reshape(image,(1,3,32,32))#改变图像的大小才可以传入模型
model.eval()
with torch.no_grad():
output=model(image)

#打印结果
print(output)
print(output.argmax(1))
tmp=output.argmax(1)
print(classes[tmp])



后面博主会逐个解析每个模块如何构建

不要忘了支持博主

Follow me(click here)