Pytorch完整训练自己的数据集

更新时间:2023-08-02 00:32:09 阅读: 评论:0

Pytorch完整训练⾃⼰的数据集
在这节中,我们继续完成模型构建及其训练。可参考我之前写的:
⽂章⽬录
1 构建模型
本次实验采⽤ResNet模型。代码很简单,⽹上找下有很多,也可以⽤torchvision⾥⾯官⽅写的。
import torch
from torch import nn
import functional as F
class ResBlk(nn.Module):
"""
resnet block
"""
def__init__(lf, ch_in, ch_out, stride=1):
"""
:param ch_in:
:param ch_out:
"""
super(ResBlk, lf).__init__()#下⾯是瓶颈层
lf.bn2 = nn.BatchNorm2d(ch_out)
如何练出腹肌
nn.Conv2d(ch_in, ch_out, kernel_size=1, stride=stride),
nn.BatchNorm2d(ch_out))
def forward(lf, x):
"""
:param x: [b, ch, h, w]
四川博物馆:return:
"""
out = F.relu(lf.v1(x)))
out = lf.v2(out))
# short cut.
# extra module: [b, ch_in, h, w] => [b, ch_out, h, w]
# element-wi add:
out = lf.extra(x)+ out
out = F.relu(out)
return out
class ResNet18(nn.Module):#构建ResNet18模型
def__init__(lf, num_class):
super(ResNet18, lf).__init__()
nn.Conv2d(3,16, kernel_size=3, stride=3, padding=0),
nn.BatchNorm2d(16)
)
# followed 4 blocks
# [b, 16, h, w] => [b, 32, h ,w]
lf.blk1 = ResBlk(16,32, stride=3)
# [b, 32, h, w] => [b, 64, h, w]
lf.blk2 = ResBlk(32,64, stride=3)
# # [b, 64, h, w] => [b, 128, h, w]
lf.blk3 = ResBlk(64,128, stride=2)
# # [b, 128, h, w] => [b, 256, h, w]
# # [b, 128, h, w] => [b, 256, h, w]
lf.blk4 = ResBlk(128,256, stride=2)
# [b, 256, 7, 7]
lf.outlayer = nn.Linear(256*3*3, num_class)
def forward(lf, x):
"""
:param x:
:return:
"""
x = F.v1(x))
# [b, 64, h, w] => [b, 1024, h, w]
x = lf.blk1(x)
x = lf.blk2(x)
x = lf.blk3(x)
x = lf.blk4(x)
# print(x.shape)
x = x.view(x.size(0),-1)
x = lf.outlayer(x)
return x
上⾯可以单独保存⼀个模型py⽂件,命名为resnet.py
2 训练和验证模型
接下来就是训练模型
2.1 导⼊各种库
import torch
from torch import optim, nn
import visdom
import torchvision
from torch.utils.data import DataLoader
from pokemon import Pokemon
from resnet import ResNet18
2.2 超参数设置
batchsz =32
lr =1e-3
epochs =10
device = torch.device('cuda')
torch.manual_ed(1234)#为了⽅便以后能复现同样结果
viz = visdom.Visdom()
2.3 导⼊数据新语录
冲浪板
train_db = Pokemon('pokemon',224, mode='train')#创建训练数据对象
val_db = Pokemon('pokemon',224, mode='val')
test_db = Pokemon('pokemon',224, mode='test')
train_loader = DataLoader(train_db, batch_size=batchsz, shuffle=True, num_workers=4)
val_loader = DataLoader(val_db, batch_size=batchsz, num_workers=2)#num_workers多线程
test_loader = DataLoader(test_db, batch_size=batchsz, num_workers=2)#DataLoader来读取batch数据2.4开始训练模型
def main():
model = ResNet18(5).to(device)#把模型放在GPU上⾯
optimizer = optim.Adam(model.parameters(), lr=lr)#设置优化器
criteon = nn.CrossEntropyLoss()#设置损失函数
best_acc, best_epoch =0,0
global_step =0
viz.line([0],[-1], win='loss', opts=dict(title='loss'))#初始化 loss,⽅便可视化
viz.line([0],[-1], win='val_acc', opts=dict(title='val_acc'))
for epoch in range(epochs):
for step,(x, y)in enumerate(train_loader):
# x: [b, 3, 224, 224], y: [b]
x, y = x.to(device), y.to(device)
logits = model(x)
loss = criteon(logits, y)
<_grad()
loss.backward()
optimizer.step()
viz.line([loss.item()],[global_step], win='loss', update='append')#loss可视化
global_step +=1
情人诀
2.5 在训练时候,可以隔⼀段来验证模型
if epoch %2==0:
val_acc = evalute(model, val_loader)
if val_acc > best_acc:
best_epoch = epoch
best_acc = val_acc
torch.save(model.state_dict(),'best.mdl')# 保存模型权重
viz.line([val_acc],[global_step], win='val_acc',update='append')
2.6 保存最好的权重,并⽤来测试
print('best acc:', best_acc,'best epoch:', best_epoch)
model.load_state_dict(torch.load('best.mdl'))#加载最好的模型权重
print('loaded from ckpt!')
test_acc = evalute(model, test_loader)#验证模型,evalute需要我们⾃⼰写
print('test acc:', test_acc)
验证模型,evalute需要我们⾃⼰写:
七星瓢虫def evalute(model, loader):
model.eval()#必须要加⼊ model.eval() ,因为训练和测试BN不⼀致
correct =0
total =len(loader.datat)
for x, y in loader:
x, y = x.to(device), y.to(device)
_grad():#不需要计算梯度,所以加上不求导,验证集⼀定要加上这⼏句话
logits = model(x)
任职期满考核结果pred = logits.argmax(dim=1)
correct += torch.eq(pred, y).sum().float().item()
return correct / total
需要注意的是:ain()和 model.eval()不能漏掉,因为在测试的时候BN是需要⽤训练集的,需要区分开来。完整的训练流程就是这样,如果我们需要加上预训练模型,需要在上⾯修改下。
3 预训练模型训练
导⼊torchvision库
dels import resnet18
其他不变,将模型修改下:
# model = ResNet18(5).to(device) #不⽤预训练模型
trained_model = resnet18(pretrained=True)#采⽤预训练模型
model = nn.Sequential(*list(trained_model.children())[:-1],# [b, 512, 1, 1]
Flatten(),# [b, 512, 1, 1] => [b, 512]
nn.Linear(512,5)
).to(device)
# x = torch.randn(2, 3, 224, 224)
在上⾯代码中,由于任务不同,我们分类的数⽬不⼀样,需要修改⽹络最后⼀层。
*list(trained_model.children())[:-1]
trained_model.children()表⽰所有的层数,我们需要转化成list,然后⽤切⽚去掉最后⼀层,最后⽤*再合成⽹络结构。
4 可视化
如果是随机训练,打开visdom可以看到:
如果是⽤预训练模型来训练,可以看到:
可以看到加了预训练模型,准确率提升明显,且训练速度更快。因此在训练任务时候,预训练是有必要的。
5 下⼀步就是简单写⼀个⽹站,演⽰我们训练好的分类器。
可以看这⾥:小女孩编发
我们可以做⼀个⼩⽹页,显⽰我们图⽚分类的结果。

本文发布于:2023-08-02 00:32:09,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1104912.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:训练   模型   需要   结果   验证   设置   数据   加上
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图