pytorch小土堆

学习链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14

1.哔哩哔哩视频
https://www.bilibili.com/video/BV1hE411t7RN?p=18&spm_id_from=pageDriver&vd_source=f2ebbaf7e4283edae08088dbbbaff299

2.pytorch官网
https://pytorch.org/docs/stable/generated/torch.nn.functional.conv2d.html#torch.nn.functional.conv2d

3.小土堆的资料链接
土堆B站视频课件:https://pan.baidu.com/wap/init?surl=moZb_eKmVCcRHS49IPKHQw#/ 提取码:t3st

4.我自己电脑是tuduipytorch2环境(python3.8)

5.配置pytorch用的链接里面的11.3版本
https://blog.csdn.net/weixin_45334223/article/details/128772572?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168974940216800227485583%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168974940216800227485583&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~top_positive~default-2-128772572-null-null.268^v1^control&utm_term=%E5%AE%89%E8%A3%85pytorch&spm=1018.2226.3001.4450

p16神经网络的基本骨架(nn.Module)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

import torch
from torch import nn

class Tudui(nn.Module):
def __init__(self):
super().__init__() #重写父类

def forward(self, input):
output = input + 1 #计数
return output

tudui = Tudui()
x = torch.tensor(1.0)
output = tudui(x)
print(output)


p17卷积操作

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

import torch
import torch.nn.functional as F

#输入图像 5*5
input=torch.tensor([[1,2,0,3,1],
[0,1,2,3,1],
[1,2,1,0,0],
[5,2,3,1,1],
[2,1,0,1,1]])
#卷积核 3*3
kernel=torch.tensor([1,2,1],
[0,1,0],
[2,1,0])

#将输入图像更改为1个数据1个通道 高度5宽度5 input要求为(minibatch,in_channels,iH,iW)
input=torch.reshape(input,(1,1,5,5))
kernel=kernel.reshape(input,(1,1,3,3))

print(input.shape)
print(kernel.shape)

#步长为1 就是每次移动一位
output=F.conv2d(input,kernel,stride=1)
print(output)

output2=F.conv2d(input,kernel,stride=2)
print(output2)

#填充为1
output3=F.conv2d(input,kernel,stride=1,padding=1)
print(output3)


p18卷积层

动画
https://github.com/vdumoulin/conv_arithmetic/blob/master/README.md

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

import torch
import torchvision
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torch import nn
dataset=torchvision.datasets.CIFAR10("../data",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloader=DataLoader(dataset,batch_size=64)

class Tudui(nn.Module):
def __init__(self):
super(Tudui,self).__init__() #重写父类
self.conv1=Conv2d(in_channels=3,out_channels=6,kernel_size=3,stride=1,padding=0) #设置一个卷积层

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

tudui=Tudui()
print(tudui) #conv1:conv2d(3,6,kernel_size=(3,3),stride=(1,1))

for data in dataloader:
imgs,target=data
output=tudui(imgs) #把数据集的照片放进去
#图片开始的格式
print(imgs.shape) #【64,4,32,32】
#图片最终的格式
print(output.shape)#【64,3,30,30】


p19最大池化层

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

import torch
from torch import nn
from torch.nn import MaxPool2d

#输入图像 5*5
input=torch.tensor([[1,2,0,3,1],
[0,1,2,3,1],
[1,2,1,0,0],
[5,2,3,1,1],
[2,1,0,1,1]],dtype=torch.float32)

input = torch.reshape(input, (-1, 1, 5, 5)) #-1就是根据其他设置,自动计算
print(input)
print(input.shape)

class Tudui(nn.Module):
def __init__(self):
super(Tudui,self).__init__() #重写父类
#池化层就是减少参数 让模型更简略更小
self.maxpool1=MaxPool2d(kernel_size=3,ceil_mode=True) #设置一个池化层 ceil_mode=True能够保证不够池化核大小的时候可以出结果

def forward(self,input):
output=self.maxpool1(input)
return output

tudui=Tudui()
output=tudui(input)
print(output)


p20非线性激活

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

#主要介绍relu和sigmoid
import torch
from torch import nn
from torch.nn import ReLU, Sigmoid

input=torch.tensor([[1,-0.5],
[-1,3]])

input=torch.reshape(input,(-1,1,2,2))
print(input)
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
self.relu1 = ReLU()
self.sigmoid1 = Sigmoid()

def forward(self, input):
output = self.relu1(input)
#output = self.sigmoid1(input)
return output

tudui = Tudui()
output=tudui(input)
print(output)


p21线性层和其它层介绍

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

import torch
import torchvision
from torch import nn
from torch.nn import Linear
from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10("../data", train=False, transform=torchvision.transforms.ToTensor(),
download=True)

dataloader = DataLoader(dataset, batch_size=64)

class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
self.linear1 = Linear(196608, 10) #输入 输出

def forward(self, input):
output = self.linear1(input) #经过线性层
return output

tudui = Tudui()

for data in dataloader:
imgs, targets = data
print(imgs.shape)
output = torch.flatten(imgs) #展开成一行
print(output.shape)
output = tudui(output)
print(output.shape)


p22实战和sequential的使用

要参考的模型图:

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

import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
#from torch.utils.tensorboard import SummaryWriter

class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
#直接做成一个系列
self.model1 = Sequential(
Conv2d(in_channels=3, out_channels=32,kernel_size=5, padding=2), #padding=2是根据输入输出的HW公式推出来 输入3个通道 输出维度32池化核5*5
MaxPool2d(2), #默认池化层的stride步长=池化核维度
Conv2d(in_channels=32, out_channels=32,kernel_size=5, padding=2), #padding=2是根据输入输出的HW公式推出来 输入32个通道 输出维度32 池化核5*5
MaxPool2d(2), #默认池化层的stride步长=池化核维度
Conv2d(in_channels=32, out_channels=64,kernel_size=5, padding=2), #padding=2是根据输入输出的HW公式推出来 输入32个通道 输出维度64 池化核5*5
MaxPool2d(2), #默认池化层的stride步长=池化核维度
Flatten(), #展开
Linear(1024, 64), #展开之后64*4*4=1024个 一共有64个
Linear(64, 10) #展开之后64个 一共10个
)

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

@初始化看看
tudui = Tudui()
print(tudui)

#假设有一个
input = torch.ones((64, 3, 32, 32)) #相当于64张图 每张图有3个通道 32*32的
output = tudui(input)
print(output.shape)

#可视化
#writer = SummaryWriter("../logs_seq")
#writer.add_graph(tudui, input)
#writer.close()


p23损失函数(误差)和反向传播(计算误差提供可以优化的点)

两种损失函数和交叉熵

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

import torch
from torch.nn import L1Loss
from torch import nn

#输入和目标
inputs = torch.tensor([1, 2, 3], dtype=torch.float32)
targets = torch.tensor([1, 2, 5], dtype=torch.float32)
#规定想要的输入和目标的结果
inputs = torch.reshape(inputs, (1, 1, 1, 3)) #1个样本 通道为1 宽度为1*3
targets = torch.reshape(targets, (1, 1, 1, 3))

loss=L1Loss()
result=loss(inputs,targets) #tensor(0.6667)
print(result) #[(1-1)+(2-2)+(5-3)]/3

loss2=nn.MSELoss()
result2=loss2(inputs,targets) #tensor(1.3333)
print(result2) #[(1-1)+(2-2)+(5-3)^2]/3

#交叉熵
#使用在分类问题时候,有很多个类别
x=torch.tensor([0.1, 0.2, 0.3])
y=torch.tensor([1])
x=torch.reshape(x,(1, 3)) #3类
loss_cross=nn.CrossEntropyLoss()
result3=loss_cross(x,y) #tensor(1.1019)
print(result3)

带网络的

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

import torchvision
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear
from torch.utils.data import DataLoader

#数据集
dataset = torchvision.datasets.CIFAR10("../data", train=False, transform=torchvision.transforms.ToTensor(),
download=True)

dataloader = DataLoader(dataset, batch_size=1)

class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
#直接做成一个系列
self.model1 = Sequential(
Conv2d(in_channels=3, out_channels=32,kernel_size=5, padding=2), #padding=2是根据输入输出的HW公式推出来 输入3个通道 输出维度32池化核5*5
MaxPool2d(2), #默认池化层的stride步长=池化核维度
Conv2d(in_channels=32, out_channels=32,kernel_size=5, padding=2), #padding=2是根据输入输出的HW公式推出来 输入32个通道 输出维度32 池化核5*5
MaxPool2d(2), #默认池化层的stride步长=池化核维度
Conv2d(in_channels=32, out_channels=64,kernel_size=5, padding=2), #padding=2是根据输入输出的HW公式推出来 输入32个通道 输出维度64 池化核5*5
MaxPool2d(2), #默认池化层的stride步长=池化核维度
Flatten(), #展开
Linear(1024, 64), #展开之后64*4*4=1024个 一共有64个
Linear(64, 10) #展开之后64个 一共10个
)

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

#交叉熵
loss = nn.CrossEntropyLoss()
tudui = Tudui()
for data in dataloader:
imgs, targets = data
outputs = tudui(imgs)
result_loss = loss(outputs, targets)
print(result_loss)
print("ok")


p24优化器(让loss变小)

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

import torch.optim
import torchvision
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear
from torch.utils.data import DataLoader

#数据集
dataset = torchvision.datasets.CIFAR10("../data", train=False, transform=torchvision.transforms.ToTensor(),
download=True)

dataloader = DataLoader(dataset, batch_size=1)

class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
#直接做成一个系列
self.model1 = Sequential(
Conv2d(in_channels=3, out_channels=32,kernel_size=5, padding=2), #padding=2是根据输入输出的HW公式推出来 输入3个通道 输出维度32池化核5*5
MaxPool2d(2), #默认池化层的stride步长=池化核维度
Conv2d(in_channels=32, out_channels=32,kernel_size=5, padding=2), #padding=2是根据输入输出的HW公式推出来 输入32个通道 输出维度32 池化核5*5
MaxPool2d(2), #默认池化层的stride步长=池化核维度
Conv2d(in_channels=32, out_channels=64,kernel_size=5, padding=2), #padding=2是根据输入输出的HW公式推出来 输入32个通道 输出维度64 池化核5*5
MaxPool2d(2), #默认池化层的stride步长=池化核维度
Flatten(), #展开
Linear(1024, 64), #展开之后64*4*4=1024个 一共有64个
Linear(64, 10) #展开之后64个 一共10个
)

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

#交叉熵
loss = nn.CrossEntropyLoss()
tudui = Tudui()

#设置优化器
optim=torch.optim.SGD(tudui.parameters(),lr=0.01) #入门设置两个参数 模型参数和学习速率

for epoch in range(20): #套循环
wucha=0.0
for data in dataloader:
imgs, targets = data
outputs = tudui(imgs)
result_loss = loss(outputs, targets)

#增加优化器的部分
optim.zero_grad() #每次循环梯度清0
result_loss.backward() #获取每个data计算grad
optim.step() #进行优化 -->最终将loss差距变小
#计算每一轮误差优化多少
wucha=wucha+result_loss

print(result_loss)


p25现有模型

使用和修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

import torchvision
from torch import nn

vgg16_false = torchvision.models.vgg16(pretrained=False) #会下载到c盘 我的到C:\Users\larkkkkkkk\.cache\torch\hub\checkpoints
vgg16_true = torchvision.models.vgg16(pretrained=True)

print(vgg16_true)

train_data = torchvision.datasets.CIFAR10('./data', train=True, transform=torchvision.transforms.ToTensor(),
download=True)

#修改点!!!
# (6): Linear(in_features=4096, out_features=1000, bias=True)

#要么加一层线性层输出10
vgg16_true.add_module('add_Linear',nn.Linear(1000,10)) #在原来的classifier外面加
#vgg16_true.classifier.add_module('add_Linear',nn.Linear(1000,10)) #在原来的classifier里面加
print(vgg16_true)

#要么将输出层改为10
vgg16_false.classifier[6]=nn.Linear(4096,10)
print(vgg16_false)

p26保存

保存方法1(模型结构+模型参数)

1
2
3
4
5
6
7
8

import torch
import torchvision

vgg16= torchvision.models.vgg16(pretrained=False) #会下载到c盘 我的到C:\Users\larkkkkkkk\.cache\torch\hub\checkpoints

#保存
torch.save(vgg16,"vgg16_method1.pth") #模型结构+模型参数

保存方法2(模型参数)

1
2
3
4
5
6
7
8

import torch
import torchvision

vgg16= torchvision.models.vgg16(pretrained=False) #会下载到c盘 我的到C:\Users\larkkkkkkk\.cache\torch\hub\checkpoints

#保存
torch.save(vgg16.state_dict(),"vgg16_method2.pth") #模型参数 是字典形式!!!!

p26读取

读取方法1(load)

1
2
3
4
5
6

import torch
import torchvision
##读取方式1
model=torch.load("vgg16_method1.pth")
print(model)

读取方法2(考虑字典形式)

1
2
3
4
5
6
7
8
9
10
11
12

import torch
import torchvision

#读取方式2
vgg16=torchvision.models.vgg16(pretrained=False)
vgg16.load_state_dict(torch.load("vgg16_method2.pth"))
print(vgg16)
print("-----------------------------------------------------------------")
#如果不使用加载dict 那么输出就是字典形式
model2=torch.load("vgg16_method2.pth")
print(model2)


p27完整模型训练套路

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

import torchvision
from torch.utils.tensorboard import SummaryWriter
from model import * # 引入model.py里的模型
from torch import nn
from torch.utils.data import DataLoader

# 1.数据集
##1.1准备数据集
train_data = torchvision.datasets.CIFAR10(root="../data", train=True, transform=torchvision.transforms.ToTensor(),
download=True)
test_data = torchvision.datasets.CIFAR10(root="../data", train=False, transform=torchvision.transforms.ToTensor(),
download=True)
##1.2查看数据集内容
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练集长度:", train_data_size) # 训练集长度: 50000
print("测试集长度:", test_data_size) # 测试集长度: 10000
##1.3加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

# 2.创建网络模型
tudui = Tudui() # 引用model.py文件下的模型
##2.1损失函数
loss_fn = nn.CrossEntropyLoss()
##2.2优化器(反向传播时候用)
optimizer = torch.optim.SGD(tudui.parameters(), lr=0.01)

# 3.训练网络
##3.1记录训练的次数
total_train_step = 0
##3.2记录测试的次数
total_test_step = 0
##3.3训练的轮数
epoch = 10

# 添加tensorboard
writer = SummaryWriter("./logs_train")

for i in range(epoch):
print("-------第 {} 轮训练开始-------".format(i + 1))
# 训练
tudui.train() #有些特殊层需要调用(一般写上去也没事)
for data in train_dataloader:
imgs, targets = data # 图片和标签
outputs = tudui(imgs)
loss = loss_fn(outputs, targets)

# 优化器
optimizer.zero_grad() # 每一轮梯度清0
loss.backward() # 反向传播 计算出要优化的值
optimizer.step() # 优化器优化

total_train_step = total_train_step + 1
if total_train_step % 100 == 0:
print("训练次数:{}, Loss: {}".format(total_train_step, loss.item()))
writer.add_scalar("train_loss", loss.item(), total_train_step)

# 测试
tudui.eval() #有些特殊层需要调用(一般写上去也没事)
total_test_loss = 0 #整体loss
total_accuracy = 0 #整体准确率
with torch.no_grad(): #在训练之后没有梯度了才可以进循环
for data in test_dataloader:
imgs, targets = data # 图片和标签
outputs = tudui(imgs)
# 一部分数据的损失
loss = loss_fn(outputs, targets)
total_test_loss = total_test_loss + loss.item() # 每次损失增加
accuracy = (outputs.argmax(1) == targets).sum() #整体准确率 用argmax可以判断[False,True].sum()=1
total_accuracy = total_accuracy + accuracy

print("整体测试集上的Loss: {}".format(total_test_loss))
print("整体测试集上的正确率: {}".format(total_accuracy / test_data_size))
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 = total_test_step + 1

torch.save(tudui, "tudui_{}.pth".format(i))
print("模型已保存")

writer.close()


p30利用GPU训练

1
2
 
在上一轮的代码中添加gpu训练

两者的区别和加入的位置:

.cuda()

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

import torchvision
from torch.utils.tensorboard import SummaryWriter
from model import * # 引入model.py里的模型
from torch import nn
from torch.utils.data import DataLoader

# 1.数据集
##1.1准备数据集
train_data = torchvision.datasets.CIFAR10(root="../data", train=True, transform=torchvision.transforms.ToTensor(),
download=True)
test_data = torchvision.datasets.CIFAR10(root="../data", train=False, transform=torchvision.transforms.ToTensor(),
download=True)
##1.2查看数据集内容
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练集长度:", train_data_size) # 训练集长度: 50000
print("测试集长度:", test_data_size) # 测试集长度: 10000
##1.3加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

# 2.创建网络模型
##2.1搭建神经网络
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
self.model = nn.Sequential(
nn.Conv2d(3, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, 5, 1, 2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64 * 4 * 4, 64),
nn.Linear(64, 10)
)

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

tudui = Tudui() # 引用model.py文件下的模型
tudui=tudui.cuda()

##2.2损失函数
loss_fn = nn.CrossEntropyLoss()
loss_fn=loss_fn.cuda()

##2.3优化器(反向传播时候用)
optimizer = torch.optim.SGD(tudui.parameters(), lr=0.01)


# 3.训练网络
##3.1记录训练的次数
total_train_step = 0
##3.2记录测试的次数
total_test_step = 0
##3.3训练的轮数
epoch = 10

# 添加tensorboard
writer = SummaryWriter("./logs_train")

for i in range(epoch):
print("-------第 {} 轮训练开始-------".format(i + 1))
# 训练
tudui.train() #有些特殊层需要调用(一般写上去也没事)
for data in train_dataloader:
imgs, targets = data # 图片和标签
imgs=imgs.cuda()
targets=targets.cuda()
outputs = tudui(imgs)
loss = loss_fn(outputs, targets)

# 优化器
optimizer.zero_grad() # 每一轮梯度清0
loss.backward() # 反向传播 计算出要优化的值
optimizer.step() # 优化器优化

total_train_step = total_train_step + 1
if total_train_step % 100 == 0:
print("训练次数:{}, Loss: {}".format(total_train_step, loss.item()))
writer.add_scalar("train_loss", loss.item(), total_train_step)

# 测试
tudui.eval() #有些特殊层需要调用(一般写上去也没事)
total_test_loss = 0 #整体loss
total_accuracy = 0 #整体准确率
with torch.no_grad():
for data in test_dataloader:
imgs, targets = data # 图片和标签
imgs = imgs.cuda()
targets = targets.cuda()
outputs = tudui(imgs)
# 一部分数据的损失
loss = loss_fn(outputs, targets)
total_test_loss = total_test_loss + loss.item() # 每次损失增加
accuracy = (outputs.argmax(1) == targets).sum() #整体准确率 用argmax可以判断[False,True].sum()=1
total_accuracy = total_accuracy + accuracy

print("整体测试集上的Loss: {}".format(total_test_loss))
print("整体测试集上的正确率: {}".format(total_accuracy / test_data_size))
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 = total_test_step + 1

torch.save(tudui, "tudui_{}.pth".format(i))
print("模型已保存")

writer.close()

更改位置:

.torch.device(“cuda:0”)

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

import torchvision
from torch.utils.tensorboard import SummaryWriter
from model import * # 引入model.py里的模型
from torch import nn
from torch.utils.data import DataLoader

#设置GPU
device=torch.device("cuda:0") #要考虑有几张卡

# 1.数据集
##1.1准备数据集
train_data = torchvision.datasets.CIFAR10(root="../data", train=True, transform=torchvision.transforms.ToTensor(),
download=True)
test_data = torchvision.datasets.CIFAR10(root="../data", train=False, transform=torchvision.transforms.ToTensor(),
download=True)
##1.2查看数据集内容
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练集长度:", train_data_size) # 训练集长度: 50000
print("测试集长度:", test_data_size) # 测试集长度: 10000
##1.3加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

# 2.创建网络模型
##2.1搭建神经网络
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
self.model = nn.Sequential(
nn.Conv2d(3, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, 5, 1, 2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64 * 4 * 4, 64),
nn.Linear(64, 10)
)

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

tudui = Tudui() # 引用model.py文件下的模型
#tudui=tudui.cuda()
tudui=tudui.to(device)

##2.2损失函数
loss_fn = nn.CrossEntropyLoss()
#loss_fn=loss_fn.cuda()
loss_fn=loss_fn.to(device)

##2.3优化器(反向传播时候用)
optimizer = torch.optim.SGD(tudui.parameters(), lr=0.01)


# 3.训练网络
##3.1记录训练的次数
total_train_step = 0
##3.2记录测试的次数
total_test_step = 0
##3.3训练的轮数
epoch = 10

# 添加tensorboard
writer = SummaryWriter("./logs_train")

for i in range(epoch):
print("-------第 {} 轮训练开始-------".format(i + 1))
# 训练
tudui.train() #有些特殊层需要调用(一般写上去也没事)
for data in train_dataloader:
imgs, targets = data # 图片和标签
#imgs=imgs.cuda()
#targets=targets.cuda()
imgs=imgs.to(device)
targets=targets.to(device)
outputs = tudui(imgs)
loss = loss_fn(outputs, targets)

# 优化器
optimizer.zero_grad() # 每一轮梯度清0
loss.backward() # 反向传播 计算出要优化的值
optimizer.step() # 优化器优化

total_train_step = total_train_step + 1
if total_train_step % 100 == 0:
print("训练次数:{}, Loss: {}".format(total_train_step, loss.item()))
writer.add_scalar("train_loss", loss.item(), total_train_step)

# 测试
tudui.eval() #有些特殊层需要调用(一般写上去也没事)
total_test_loss = 0 #整体loss
total_accuracy = 0 #整体准确率
with torch.no_grad():
for data in test_dataloader:
imgs, targets = data # 图片和标签
# imgs=imgs.cuda()
# targets=targets.cuda()
imgs = imgs.to(device)
targets = targets.to(device)
outputs = tudui(imgs)
# 一部分数据的损失
loss = loss_fn(outputs, targets)
total_test_loss = total_test_loss + loss.item() # 每次损失增加
accuracy = (outputs.argmax(1) == targets).sum() #整体准确率 用argmax可以判断[False,True].sum()=1
total_accuracy = total_accuracy + accuracy

print("整体测试集上的Loss: {}".format(total_test_loss))
print("整体测试集上的正确率: {}".format(total_accuracy / test_data_size))
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 = total_test_step + 1

torch.save(tudui, "tudui_{}.pth".format(i))
print("模型已保存")

writer.close()

更改位置:


p32完整模型验证套路

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
import torch
import torchvision
from PIL import Image
from torch import nn

#读取图片
image_path = "./imgs/dog.png"
image = Image.open(image_path)
print(image) #<PIL.PngImagePlugin.PngImageFile image mode=RGB size=1053x825 at 0x26FB60DF880>


#png格式是四个通道,除了RGB以外还有一个透明度通道
image=image.convert('RGB')#保留其颜色通道

transform = torchvision.transforms.Compose([torchvision.transforms.Resize((32, 32)), #网络输入是32*32维
torchvision.transforms.ToTensor()])
image=transform(image)
print(image.shape) #torch.Size([3, 32, 32])

#模型
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
self.model = nn.Sequential(
nn.Conv2d(3, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, 5, 1, 2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64*4*4, 64),
nn.Linear(64, 10)
)

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

model = torch.load("tudui_29_gpu.pth", map_location=torch.device('cpu'))
#print(model)

#开始验证
#输入时候记得设置batch_size
image = torch.reshape(image, (1, 3, 32, 32))
model.eval() #有些特殊层需要

with torch.no_grad():
output = model(image)
print("预测结果是:",output)

print("最大的可能是:",output.argmax(1))


×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 学习链接
  2. 2. p16神经网络的基本骨架(nn.Module)
  3. 3. p17卷积操作
  4. 4. p18卷积层
  5. 5. p19最大池化层
  6. 6. p20非线性激活
  7. 7. p21线性层和其它层介绍
  8. 8. p22实战和sequential的使用
  9. 9. p23损失函数(误差)和反向传播(计算误差提供可以优化的点)
    1. 9.1. 两种损失函数和交叉熵
    2. 9.2. 带网络的
  10. 10. p24优化器(让loss变小)
  11. 11. p25现有模型
    1. 11.1. 使用和修改
    2. 11.2. p26保存
      1. 11.2.1. 保存方法1(模型结构+模型参数)
      2. 11.2.2. 保存方法2(模型参数)
    3. 11.3. p26读取
      1. 11.3.1. 读取方法1(load)
      2. 11.3.2. 读取方法2(考虑字典形式)
  12. 12. p27完整模型训练套路
  13. 13. p30利用GPU训练
    1. 13.1. .cuda()
    2. 13.2. .torch.device(“cuda:0”)
  14. 14. p32完整模型验证套路
,