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种方法相关推荐

  1. pytorch网络冻结的三种方法区别:detach、requires_grad、with_no_grad

    pytorch网络冻结的三种方法区别:detach.requires_grad.with_no_grad 文章目录 pytorch网络冻结的三种方法区别:detach.requires_grad.wi ...

  2. Pytorch训练速度更快的十七种方法

    来源: 不久前,Reddit 上一个帖子热度爆了.最主题的内容是关于如何加速 PyTorch 训练.作者是来自苏黎世联邦理工学院的计算机科学硕士生 LORENZ KUHN,文章向我们介绍了在使用 Py ...

  3. nn.Dataparallel pytorch 平行计算的两种方法

    1. nn.Dataparallel 多GPU加速训练 原理: 模型分别复制到每个卡中,然后把输入切片,分别放入每个卡中计算,然后再用第一块卡进行汇总求loss,反向传播更新参数. 第一块卡占用的内存 ...

  4. 《具体数学》学习笔记: 4.四种方法推导平方和公式

    四种方法推导平方和公式 序言: 连续自然数的平方和, Sn=∑k=0nk2=12+22+...+n2S_n = \sum_{k=0}^{n}{k^2} = 1^2 + 2^2 + ... + n^2S ...

  5. 速成pytorch学习——10天.训练模型的3种方法

    Pytorch通常需要用户编写自定义训练循环,训练循环的代码风格因人而异. 有3类典型的训练循环代码风格:脚本形式训练循环,函数形式训练循环,类形式训练循环. 下面以minist数据集的分类模型的训练 ...

  6. 【深度学习】卷积计算与训练模型的几种方法

    卷积计算 全连接层和卷积层的根本区别在于:全连接层(Dense层)从输入空间中学到的是全局模式,而卷积层学到的是局部模式. 因为这个特性,所以卷积神经网络有两个有趣的性质: 平移不变性:卷积神经网络在 ...

  7. 指南 | Pytorch定义网络的几种方法

    点上方计算机视觉联盟获取更多干货 仅作学术分享,不代表本公众号立场,侵权联系删除 转载于:作者 | ppgod @知乎(已授权) 来源 | https://zhuanlan.zhihu.com/p/8 ...

  8. 学累了之后重新进入学习状态的5种方法,让学习更轻松

    学习知识的过程是十分枯燥的,因此我们有时候会不想学习.但这只是问题的表象,造成这种表象的原因有很多,对应的解决方案也不尽相同.有的情况下,我们需要逼一逼自己,让自己能够坚持下去:但有些时候,我们应该理 ...

  9. Pytorch构建模型的3种方法

    这个地方一直是我思考的地方!因为学的代码太多了,构建的模型各有不同,这里记录一下! 可以使用以下3种方式构建模型: 1,继承nn.Module基类构建自定义模型. 2,使用nn.Sequential按 ...

最新文章

  1. list对oracle结果集排序了_文章推荐系统系列之基于 FTRL模型的在线排序
  2. java集成网站微信,微博,qq登录
  3. ## Spark学习之路(一)
  4. windows下python打开中文路径文件出现问题
  5. 数据结构实验之栈与队列十一:refresh的停车场
  6. 美团O2O排序解决方案——线上篇
  7. mfc制作登录界面mysql_MFC制作漂亮界面之登录界面
  8. [攻防世界 pwn]——get_shell
  9. c语言由声明部分,C语言期末复习.doc
  10. 怎么改wps表格中折线图的横坐标?
  11. Cookie和Session的知识
  12. 1、javascript的继承function
  13. Nginx源码分析 - 主流程篇 - 多进程实现(14)
  14. Hyper-V Windows 8.1 Windows Server 2012 R2 QA
  15. family album U.S.A 02
  16. 高分屏更改Adobe Premier CC UI界面字体大小
  17. 渗透测试常用端口利用总结
  18. 浅谈LBP原理和代码(基于Python)
  19. 重磅精品课程总有一门是你想要找的
  20. Xilinx Vivado复数乘法器Complex Multiplier IP核调用及其仿真

热门文章

  1. shiro550代码审计(巨详细)--加密部分
  2. 中小学计算机教师招聘考试题,2015中小学信息技术教师招聘考试题库(30套含答案)...
  3. java什么是局部变量_java局部变量是什么意思?Java中局部变量与成员变量有哪些区别?...
  4. 简化版的推特(Twitter)
  5. supervisor分组
  6. 使用Python制作漫画和小说电子书的方法总结
  7. yooasset+hybridclr在android,ios端热更新测试
  8. 实用口语(第24期):帮你搞懂日期的写法读法
  9. 删 卡尔 波普尔_卡尔波普尔与进化论的可证伪性
  10. selenium爬取上市公司全部行业及分行业股票行情数据