Pytorch学习-训练模型的3种方法
pytorch通常需要用户编写自定义训练循环,训练循环的代码风格因人而异。
有3类典型的训练循环代码风格:脚本形式训练循环,函数形式训练循环,类形式训练循环。
下面以minist数据集的分类模型的训练为例,演示这3种训练模型的风格。
准备数据
import torch
from torch import nn
from torchkeras import summary,Model import torchvision
from torchvision import transforms
transform = transforms.Compose([transforms.ToTensor()])ds_train = torchvision.datasets.MNIST(root="./data/minist/",train=True,download=True,transform=transform)
ds_valid = torchvision.datasets.MNIST(root="./data/minist/",train=False,download=True,transform=transform)dl_train = torch.utils.data.DataLoader(ds_train, batch_size=128, shuffle=True, num_workers=4)
dl_valid = torch.utils.data.DataLoader(ds_valid, batch_size=128, shuffle=False, num_workers=4)print(len(ds_train))
print(len(ds_valid))
输出
60000
10000
显示部分数据:
%matplotlib inline
%config InlineBackend.figure_format = 'svg'#查看部分样本
from matplotlib import pyplot as plt plt.figure(figsize=(8,8))
for i in range(9):img,label = ds_train[i]img = torch.squeeze(img)ax=plt.subplot(3,3,i+1)ax.imshow(img.numpy())ax.set_title("label = %d"%label)ax.set_xticks([])ax.set_yticks([])
plt.show()
net = nn.Sequential()
net.add_module("conv1",nn.Conv2d(in_channels=1,out_channels=32,kernel_size = 3))
net.add_module("pool1",nn.MaxPool2d(kernel_size = 2,stride = 2))
net.add_module("conv2",nn.Conv2d(in_channels=32,out_channels=64,kernel_size = 5))
net.add_module("pool2",nn.MaxPool2d(kernel_size = 2,stride = 2))
net.add_module("dropout",nn.Dropout2d(p = 0.1))
net.add_module("adaptive_pool",nn.AdaptiveMaxPool2d((1,1)))
net.add_module("flatten",nn.Flatten())
net.add_module("linear1",nn.Linear(64,32))
net.add_module("relu",nn.ReLU())
net.add_module("linear2",nn.Linear(32,10))print(net)
输出
Sequential((conv1): Conv2d(1, 32, kernel_size=(3, 3), stride=(1, 1))(pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(conv2): Conv2d(32, 64, kernel_size=(5, 5), stride=(1, 1))(pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(dropout): Dropout2d(p=0.1, inplace=False)(adaptive_pool): AdaptiveMaxPool2d(output_size=(1, 1))(flatten): Flatten()(linear1): Linear(in_features=64, out_features=32, bias=True)(relu): ReLU()(linear2): Linear(in_features=32, out_features=10, bias=True)
)
summary(net,input_shape=(1,32,32))
import datetime
import numpy as np
import pandas as pd
from sklearn.metrics import accuracy_scoredef accuracy(y_pred,y_true):y_pred_cls = torch.argmax(nn.Softmax(dim=1)(y_pred),dim=1).datareturn accuracy_score(y_true,y_pred_cls)loss_func = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(params=net.parameters(),lr = 0.01)
metric_func = accuracy
metric_name = "accuracy"
epochs = 3
log_step_freq = 100dfhistory = pd.DataFrame(columns = ["epoch","loss",metric_name,"val_loss","val_"+metric_name])
print("Start Training...")
nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print("=========="*8 + "%s"%nowtime)for epoch in range(1,epochs+1): # 1,训练循环-------------------------------------------------net.train()loss_sum = 0.0metric_sum = 0.0step = 1for step, (features,labels) in enumerate(dl_train, 1):# 梯度清零optimizer.zero_grad()# 正向传播求损失predictions = net(features)loss = loss_func(predictions,labels)metric = metric_func(predictions,labels)# 反向传播求梯度loss.backward()optimizer.step()# 打印batch级别日志loss_sum += loss.item()metric_sum += metric.item()if step%log_step_freq == 0: print(("[step = %d] loss: %.3f, "+metric_name+": %.3f") %(step, loss_sum/step, metric_sum/step))# 2,验证循环-------------------------------------------------net.eval()val_loss_sum = 0.0val_metric_sum = 0.0val_step = 1for val_step, (features,labels) in enumerate(dl_valid, 1):with torch.no_grad():predictions = net(features)val_loss = loss_func(predictions,labels)val_metric = metric_func(predictions,labels)val_loss_sum += val_loss.item()val_metric_sum += val_metric.item()# 3,记录日志-------------------------------------------------info = (epoch, loss_sum/step, metric_sum/step, val_loss_sum/val_step, val_metric_sum/val_step)dfhistory.loc[epoch-1] = info# 打印epoch级别日志print(("\nEPOCH = %d, loss = %.3f,"+ metric_name + \" = %.3f, val_loss = %.3f, "+"val_"+ metric_name+" = %.3f") %info)nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')print("\n"+"=========="*8 + "%s"%nowtime)print('Finished Training...')
二,函数风格
该风格在脚本形式上作了简单的函数封装。
class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.layers = nn.ModuleList([nn.Conv2d(in_channels=1,out_channels=32,kernel_size = 3),nn.MaxPool2d(kernel_size = 2,stride = 2),nn.Conv2d(in_channels=32,out_channels=64,kernel_size = 5),nn.MaxPool2d(kernel_size = 2,stride = 2),nn.Dropout2d(p = 0.1),nn.AdaptiveMaxPool2d((1,1)),nn.Flatten(),nn.Linear(64,32),nn.ReLU(),nn.Linear(32,10)])def forward(self,x):for layer in self.layers:x = layer(x)return x
net = Net()
print(net)
summary(net,input_shape=(1,32,32))
import datetime
import numpy as np
import pandas as pd
from sklearn.metrics import accuracy_scoredef accuracy(y_pred,y_true):y_pred_cls = torch.argmax(nn.Softmax(dim=1)(y_pred),dim=1).datareturn accuracy_score(y_true,y_pred_cls)model = net
model.optimizer = torch.optim.SGD(model.parameters(),lr = 0.01)
model.loss_func = nn.CrossEntropyLoss()
model.metric_func = accuracy
model.metric_name = "accuracy"
def train_step(model,features,labels):# 训练模式,dropout层发生作用model.train()# 梯度清零model.optimizer.zero_grad()# 正向传播求损失predictions = model(features)loss = model.loss_func(predictions,labels)metric = model.metric_func(predictions,labels)# 反向传播求梯度loss.backward()model.optimizer.step()return loss.item(),metric.item()@torch.no_grad()
def valid_step(model,features,labels):# 预测模式,dropout层不发生作用model.eval()predictions = model(features)loss = model.loss_func(predictions,labels)metric = model.metric_func(predictions,labels)return loss.item(), metric.item()# 测试train_step效果
features,labels = next(iter(dl_train))
train_step(model,features,labels)
def train_model(model,epochs,dl_train,dl_valid,log_step_freq):metric_name = model.metric_namedfhistory = pd.DataFrame(columns = ["epoch","loss",metric_name,"val_loss","val_"+metric_name]) print("Start Training...")nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')print("=========="*8 + "%s"%nowtime)for epoch in range(1,epochs+1): # 1,训练循环-------------------------------------------------loss_sum = 0.0metric_sum = 0.0step = 1for step, (features,labels) in enumerate(dl_train, 1):loss,metric = train_step(model,features,labels)# 打印batch级别日志loss_sum += lossmetric_sum += metricif step%log_step_freq == 0: print(("[step = %d] loss: %.3f, "+metric_name+": %.3f") %(step, loss_sum/step, metric_sum/step))# 2,验证循环-------------------------------------------------val_loss_sum = 0.0val_metric_sum = 0.0val_step = 1for val_step, (features,labels) in enumerate(dl_valid, 1):val_loss,val_metric = valid_step(model,features,labels)val_loss_sum += val_lossval_metric_sum += val_metric# 3,记录日志-------------------------------------------------info = (epoch, loss_sum/step, metric_sum/step, val_loss_sum/val_step, val_metric_sum/val_step)dfhistory.loc[epoch-1] = info# 打印epoch级别日志print(("\nEPOCH = %d, loss = %.3f,"+ metric_name + \" = %.3f, val_loss = %.3f, "+"val_"+ metric_name+" = %.3f") %info)nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')print("\n"+"=========="*8 + "%s"%nowtime)print('Finished Training...')return dfhistory
epochs = 3
dfhistory = train_model(model,epochs,dl_train,dl_valid,log_step_freq = 100)
三,类风格
此处使用torchkeras中定义的模型接口构建模型,并调用compile方法和fit方法训练模型。
使用该形式训练模型非常简洁明了。推荐使用该形式。
class CnnModel(nn.Module):def __init__(self):super().__init__()self.layers = nn.ModuleList([nn.Conv2d(in_channels=1,out_channels=32,kernel_size = 3),nn.MaxPool2d(kernel_size = 2,stride = 2),nn.Conv2d(in_channels=32,out_channels=64,kernel_size = 5),nn.MaxPool2d(kernel_size = 2,stride = 2),nn.Dropout2d(p = 0.1),nn.AdaptiveMaxPool2d((1,1)),nn.Flatten(),nn.Linear(64,32),nn.ReLU(),nn.Linear(32,10)])def forward(self,x):for layer in self.layers:x = layer(x)return x
model = torchkeras.Model(CnnModel())
print(model)
model.summary(input_shape=(1,32,32))
from sklearn.metrics import accuracy_scoredef accuracy(y_pred,y_true):y_pred_cls = torch.argmax(nn.Softmax(dim=1)(y_pred),dim=1).datareturn accuracy_score(y_true.numpy(),y_pred_cls.numpy())model.compile(loss_func = nn.CrossEntropyLoss(),optimizer= torch.optim.Adam(model.parameters(),lr = 0.02),metrics_dict={"accuracy":accuracy})
dfhistory = model.fit(3,dl_train = dl_train, dl_val=dl_valid, log_step_freq=100)
Pytorch学习-训练模型的3种方法相关推荐
- pytorch网络冻结的三种方法区别:detach、requires_grad、with_no_grad
pytorch网络冻结的三种方法区别:detach.requires_grad.with_no_grad 文章目录 pytorch网络冻结的三种方法区别:detach.requires_grad.wi ...
- Pytorch训练速度更快的十七种方法
来源: 不久前,Reddit 上一个帖子热度爆了.最主题的内容是关于如何加速 PyTorch 训练.作者是来自苏黎世联邦理工学院的计算机科学硕士生 LORENZ KUHN,文章向我们介绍了在使用 Py ...
- nn.Dataparallel pytorch 平行计算的两种方法
1. nn.Dataparallel 多GPU加速训练 原理: 模型分别复制到每个卡中,然后把输入切片,分别放入每个卡中计算,然后再用第一块卡进行汇总求loss,反向传播更新参数. 第一块卡占用的内存 ...
- 《具体数学》学习笔记: 4.四种方法推导平方和公式
四种方法推导平方和公式 序言: 连续自然数的平方和, Sn=∑k=0nk2=12+22+...+n2S_n = \sum_{k=0}^{n}{k^2} = 1^2 + 2^2 + ... + n^2S ...
- 速成pytorch学习——10天.训练模型的3种方法
Pytorch通常需要用户编写自定义训练循环,训练循环的代码风格因人而异. 有3类典型的训练循环代码风格:脚本形式训练循环,函数形式训练循环,类形式训练循环. 下面以minist数据集的分类模型的训练 ...
- 【深度学习】卷积计算与训练模型的几种方法
卷积计算 全连接层和卷积层的根本区别在于:全连接层(Dense层)从输入空间中学到的是全局模式,而卷积层学到的是局部模式. 因为这个特性,所以卷积神经网络有两个有趣的性质: 平移不变性:卷积神经网络在 ...
- 指南 | Pytorch定义网络的几种方法
点上方计算机视觉联盟获取更多干货 仅作学术分享,不代表本公众号立场,侵权联系删除 转载于:作者 | ppgod @知乎(已授权) 来源 | https://zhuanlan.zhihu.com/p/8 ...
- 学累了之后重新进入学习状态的5种方法,让学习更轻松
学习知识的过程是十分枯燥的,因此我们有时候会不想学习.但这只是问题的表象,造成这种表象的原因有很多,对应的解决方案也不尽相同.有的情况下,我们需要逼一逼自己,让自己能够坚持下去:但有些时候,我们应该理 ...
- Pytorch构建模型的3种方法
这个地方一直是我思考的地方!因为学的代码太多了,构建的模型各有不同,这里记录一下! 可以使用以下3种方式构建模型: 1,继承nn.Module基类构建自定义模型. 2,使用nn.Sequential按 ...
最新文章
- list对oracle结果集排序了_文章推荐系统系列之基于 FTRL模型的在线排序
- java集成网站微信,微博,qq登录
- ## Spark学习之路(一)
- windows下python打开中文路径文件出现问题
- 数据结构实验之栈与队列十一:refresh的停车场
- 美团O2O排序解决方案——线上篇
- mfc制作登录界面mysql_MFC制作漂亮界面之登录界面
- [攻防世界 pwn]——get_shell
- c语言由声明部分,C语言期末复习.doc
- 怎么改wps表格中折线图的横坐标?
- Cookie和Session的知识
- 1、javascript的继承function
- Nginx源码分析 - 主流程篇 - 多进程实现(14)
- Hyper-V Windows 8.1 Windows Server 2012 R2 QA
- family album U.S.A 02
- 高分屏更改Adobe Premier CC UI界面字体大小
- 渗透测试常用端口利用总结
- 浅谈LBP原理和代码(基于Python)
- 重磅精品课程总有一门是你想要找的
- Xilinx Vivado复数乘法器Complex Multiplier IP核调用及其仿真
热门文章
- shiro550代码审计(巨详细)--加密部分
- 中小学计算机教师招聘考试题,2015中小学信息技术教师招聘考试题库(30套含答案)...
- java什么是局部变量_java局部变量是什么意思?Java中局部变量与成员变量有哪些区别?...
- 简化版的推特(Twitter)
- supervisor分组
- 使用Python制作漫画和小说电子书的方法总结
- yooasset+hybridclr在android,ios端热更新测试
- 实用口语(第24期):帮你搞懂日期的写法读法
- 删 卡尔 波普尔_卡尔波普尔与进化论的可证伪性
- selenium爬取上市公司全部行业及分行业股票行情数据