一、Pytorch的建模流程

使用Pytorch实现神经网络模型的一般流程包括:

1,准备数据

2,定义模型

3,训练模型

4,评估模型

5,使用模型

6,保存模型。

对新手来说,其中最困难的部分实际上是准备数据过程。

我们在实践中通常会遇到的数据类型包括结构化数据,图片数据,文本数据,时间序列数据。

我们将分别以titanic生存预测问题,cifar2图片分类问题,imdb电影评论分类问题,国内新冠疫情结束时间预测问题为例,演示应用Pytorch对这四类数据的建模方法。

二、Pytorch的核心概念

Pytorch是一个基于Python的机器学习库。它广泛应用于计算机视觉,自然语言处理等深度学习领域。是目前和TensorFlow分庭抗礼的深度学习框架,在学术圈颇受欢迎。

它主要提供了以下两种核心功能:

1,支持GPU加速的张量计算。

2,方便优化模型的自动微分机制。

Pytorch的主要优点:

  • 简洁易懂:Pytorch的API设计的相当简洁一致。基本上就是tensor, autograd, nn三级封装。学习起来非常容易。有一个这样的段子,说TensorFlow的设计哲学是 Make it complicated, Keras 的设计哲学是 Make it complicated and hide it, 而Pytorch的设计哲学是 Keep it simple and stupid.

  • 便于调试:Pytorch采用动态图,可以像普通Python代码一样进行调试。不同于TensorFlow, Pytorch的报错说明通常很容易看懂。有一个这样的段子,说你永远不可能从TensorFlow的报错说明中找到它出错的原因。

  • 强大高效:Pytorch提供了非常丰富的模型组件,可以快速实现想法。并且运行速度很快。目前大部分深度学习相关的Paper都是用Pytorch实现的。有些研究人员表示,从使用TensorFlow转换为使用Pytorch之后,他们的睡眠好多了,头发比以前浓密了,皮肤也比以前光滑了。

俗话说,万丈高楼平地起,Pytorch这座大厦也有它的地基。

Pytorch底层最核心的概念是张量,动态计算图以及自动微分。

三、Pytorch的层次结构

本章我们介绍Pytorch中5个不同的层次结构:即硬件层,内核层,低阶API,中阶API,高阶API【torchkeras】。并以线性回归和DNN二分类模型为例,直观对比展示在不同层级实现模型的特点。

Pytorch的层次结构从低到高可以分成如下五层。

最底层为硬件层,Pytorch支持CPU、GPU加入计算资源池。

第二层为C++实现的内核。

第三层为Python实现的操作符,提供了封装C++内核的低级API指令,主要包括各种张量操作算子、自动微分、变量管理.
如torch.tensor,torch.cat,torch.autograd.grad,nn.Module.
如果把模型比作一个房子,那么第三层API就是【模型之砖】。

第四层为Python实现的模型组件,对低级API进行了函数封装,主要包括各种模型层,损失函数,优化器,数据管道等等。
如torch.nn.Linear,torch.nn.BCE,torch.optim.Adam,torch.utils.data.DataLoader.
如果把模型比作一个房子,那么第四层API就是【模型之墙】。

第五层为Python实现的模型接口。Pytorch没有官方的高阶API。为了便于训练模型,作者仿照keras中的模型接口,使用了不到300行代码,封装了Pytorch的高阶模型接口torchkeras.Model。如果把模型比作一个房子,那么第五层API就是模型本身,即【模型之屋】。

四、Pytorch的低阶API

Pytorch的低阶API主要包括张量操作,动态计算图和自动微分。

如果把模型比作一个房子,那么低阶API就是【模型之砖】。

在低阶API层次上,可以把Pytorch当做一个增强版的numpy来使用。

Pytorch提供的方法比numpy更全面,运算速度更快,如果需要的话,还可以使用GPU进行加速。

前面几章我们对低阶API已经有了一个整体的认识,本章我们将重点详细介绍张量操作和动态计算图。

张量的操作主要包括张量的结构操作和张量的数学运算。

张量结构操作诸如:张量创建,索引切片,维度变换,合并分割。

张量数学运算主要有:标量运算,向量运算,矩阵运算。另外我们会介绍张量运算的广播机制。

动态计算图我们将主要介绍动态计算图的特性,计算图中的Function,计算图与反向传播。

五、Pytorch的中阶API

我们将主要介绍Pytorch的如下中阶API

  • 数据管道

  • 模型层

  • 损失函数

  • TensorBoard可视化

如果把模型比作一个房子,那么中阶API就是【模型之墙】。

六、Pytorch的高阶API

Pytorch没有官方的高阶API。一般通过nn.Module来构建模型并编写自定义训练循环。

为了更加方便地训练模型,作者编写了仿keras的Pytorch模型接口:torchkeras, 作为Pytorch的高阶API。

本章我们主要详细介绍Pytorch的高阶API如下相关的内容。

  • 构建模型的3种方法(继承nn.Module基类,使用nn.Sequential,辅助应用模型容器)

  • 训练模型的3种方法(脚本风格,函数风格,torchkeras.Model类风格)

  • 使用GPU训练模型(单GPU训练,多GPU训练)

1-1,结构化数据建模流程范例

import os
import datetime#打印时间
def printbar():nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')print("\n"+"=========="*8 + "%s"%nowtime)#mac系统上pytorch和matplotlib在jupyter中同时跑需要更改环境变量
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE" 

一,准备数据

titanic数据集的目标是根据乘客信息预测他们在Titanic号撞击冰山沉没后能否生存。

结构化数据一般会使用Pandas中的DataFrame进行预处理。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import torch
from torch import nn
from torch.utils.data import Dataset,DataLoader,TensorDatasetdftrain_raw = pd.read_csv('/home/kesci/input/data6936/data/titanic/train.csv')
dftest_raw = pd.read_csv('/home/kesci/input/data6936/data/titanic/test.csv')
dftrain_raw.head(10)

字段说明:

  • Survived:0代表死亡,1代表存活【y标签】
  • Pclass:乘客所持票类,有三种值(1,2,3) 【转换成onehot编码】
  • Name:乘客姓名 【舍去】
  • Sex:乘客性别 【转换成bool特征】
  • Age:乘客年龄(有缺失) 【数值特征,添加“年龄是否缺失”作为辅助特征】
  • SibSp:乘客兄弟姐妹/配偶的个数(整数值) 【数值特征】
  • Parch:乘客父母/孩子的个数(整数值)【数值特征】
  • Ticket:票号(字符串)【舍去】
  • Fare:乘客所持票的价格(浮点数,0-500不等) 【数值特征】
  • Cabin:乘客所在船舱(有缺失) 【添加“所在船舱是否缺失”作为辅助特征】
  • Embarked:乘客登船港口:S、C、Q(有缺失)【转换成onehot编码,四维度 S,C,Q,nan】

利用Pandas的数据可视化功能我们可以简单地进行探索性数据分析EDA(Exploratory Data Analysis)。

label分布情况

%matplotlib inline
%config InlineBackend.figure_format = 'png'
ax = dftrain_raw['Survived'].value_counts().plot(kind = 'bar',figsize = (12,8),fontsize=15,rot = 0)
ax.set_ylabel('Counts',fontsize = 15)
ax.set_xlabel('Survived',fontsize = 15)
plt.show()

%matplotlib inline
%config InlineBackend.figure_format = 'png'
ax = dftrain_raw['Age'].plot(kind = 'hist',bins = 20,color= 'purple',figsize = (12,8),fontsize=15)ax.set_ylabel('Frequency',fontsize = 15)
ax.set_xlabel('Age',fontsize = 15)
plt.show()

下面为正式的数据预处理

def preprocessing(dfdata):dfresult= pd.DataFrame()#PclassdfPclass = pd.get_dummies(dfdata['Pclass'])dfPclass.columns = ['Pclass_' +str(x) for x in dfPclass.columns ]dfresult = pd.concat([dfresult,dfPclass],axis = 1)#SexdfSex = pd.get_dummies(dfdata['Sex'])dfresult = pd.concat([dfresult,dfSex],axis = 1)#Agedfresult['Age'] = dfdata['Age'].fillna(0)dfresult['Age_null'] = pd.isna(dfdata['Age']).astype('int32')#SibSp,Parch,Faredfresult['SibSp'] = dfdata['SibSp']dfresult['Parch'] = dfdata['Parch']dfresult['Fare'] = dfdata['Fare']#Carbindfresult['Cabin_null'] =  pd.isna(dfdata['Cabin']).astype('int32')#EmbarkeddfEmbarked = pd.get_dummies(dfdata['Embarked'],dummy_na=True)dfEmbarked.columns = ['Embarked_' + str(x) for x in dfEmbarked.columns]dfresult = pd.concat([dfresult,dfEmbarked],axis = 1)return(dfresult)x_train = preprocessing(dftrain_raw).values
y_train = dftrain_raw[['Survived']].valuesx_test = preprocessing(dftest_raw).values
y_test = dftest_raw[['Survived']].valuesprint("x_train.shape =", x_train.shape )
print("x_test.shape =", x_test.shape )print("y_train.shape =", y_train.shape )
print("y_test.shape =", y_test.shape )

使用DataLoader和TensorDataset封装成可以迭代的数据管道。

dl_train = DataLoader(TensorDataset(torch.tensor(x_train).float(),torch.tensor(y_train).float()),shuffle = True, batch_size = 8)
dl_valid = DataLoader(TensorDataset(torch.tensor(x_test).float(),torch.tensor(y_test).float()),shuffle = False, batch_size = 8)
# 测试数据管道
for features,labels in dl_train:print(features,labels)break

二,定义模型

使用Pytorch通常有三种方式构建模型:使用nn.Sequential按层顺序构建模型,继承nn.Module基类构建自定义模型,继承nn.Module基类构建模型并辅助应用模型容器进行封装。

此处选择使用最简单的nn.Sequential,按层顺序模型。

def create_net():net = nn.Sequential()net.add_module("linear1",nn.Linear(15,20))net.add_module("relu1",nn.ReLU())net.add_module("linear2",nn.Linear(20,15))net.add_module("relu2",nn.ReLU())net.add_module("linear3",nn.Linear(15,1))net.add_module("sigmoid",nn.Sigmoid())return netnet = create_net()
print(net)

!pip install torchkeras
!pip install prettytable
!pip install datetime
from torchkeras import summary
summary(net,input_shape=(15,))

三,训练模型

Pytorch通常需要用户编写自定义训练循环,训练循环的代码风格因人而异。

有3类典型的训练循环代码风格:脚本形式训练循环,函数形式训练循环,类形式训练循环。

此处介绍一种较通用的脚本形式。

from sklearn.metrics import accuracy_scoreloss_func = nn.BCELoss()
optimizer = torch.optim.Adam(params=net.parameters(),lr = 0.01)
metric_func = lambda y_pred,y_true: accuracy_score(y_true.data.numpy(),y_pred.data.numpy()>0.5)
metric_name = "accuracy"
epochs = 10
log_step_freq = 30dfhistory = 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...')

四,评估模型

我们首先评估一下模型在训练集和验证集上的效果

dfhistory 

%matplotlib inline
%config InlineBackend.figure_format = 'svg'import matplotlib.pyplot as pltdef plot_metric(dfhistory, metric):train_metrics = dfhistory[metric]val_metrics = dfhistory['val_'+metric]epochs = range(1, len(train_metrics) + 1)plt.plot(epochs, train_metrics, 'bo--')plt.plot(epochs, val_metrics, 'ro-')plt.title('Training and validation '+ metric)plt.xlabel("Epochs")plt.ylabel(metric)plt.legend(["train_"+metric, 'val_'+metric])plt.show()
plot_metric(dfhistory,"loss")

五,使用模型

#预测概率
y_pred_probs = net(torch.tensor(x_test[0:10]).float()).data
y_pred_probs

#预测类别
y_pred = torch.where(y_pred_probs>0.5,torch.ones_like(y_pred_probs),torch.zeros_like(y_pred_probs))
y_pred

六,保存模型

Pytorch 有两种保存模型的方式,都是通过调用pickle序列化方法实现的。

第一种方法只保存模型参数。

第二种方法保存完整模型。

推荐使用第一种,第二种方法可能在切换设备和目录的时候出现各种问题。

1,保存模型参数(推荐)

torch.save(net.state_dict(), "./data/net_parameter.pkl")net_clone = create_net()
net_clone.load_state_dict(torch.load("./data/net_parameter.pkl"))net_clone.forward(torch.tensor(x_test[0:10]).float()).data

2,保存完整模型(不推荐)

torch.save(net, './data/net_model.pkl')
net_loaded = torch.load('./data/net_model.pkl')
net_loaded(torch.tensor(x_test[0:10]).float()).data

速成pytorch学习——1天相关推荐

  1. 速成pytorch学习——11天. 使用GPU训练模型

    深度学习的训练过程常常非常耗时,一个模型训练几个小时是家常便饭,训练几天也是常有的事情,有时候甚至要训练几十天. 训练过程的耗时主要来自于两个部分,一部分来自数据准备,另一部分来自参数迭代. 当数据准 ...

  2. 速成pytorch学习——7天模型层layers

    深度学习模型一般由各种模型层组合而成. torch.nn中内置了非常丰富的各种模型层.它们都属于nn.Module的子类,具备参数管理功能. 例如: nn.Linear, nn.Flatten, nn ...

  3. 速成pytorch学习——5天nn.functional 和 nn.Module

    一,nn.functional 和 nn.Module 前面我们介绍了Pytorch的张量的结构操作和数学运算中的一些常用API. 利用这些张量的API我们可以构建出神经网络相关的组件(如激活函数,模 ...

  4. 速成pytorch学习——3天自动微分机制

    神经网络通常依赖反向传播求梯度来更新网络参数,求梯度过程通常是一件非常复杂而容易出错的事情. 而深度学习框架可以帮助我们自动地完成这种求梯度运算. Pytorch一般通过反向传播 backward 方 ...

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

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

  6. 速成pytorch学习——8天损失函数

    一般来说,监督学习的目标函数由损失函数和正则化项组成.(Objective = Loss + Regularization) Pytorch中的损失函数一般在训练模型时候指定. 注意Pytorch中内 ...

  7. 速成pytorch学习——6天Dataset和DataLoader

    Pytorch通常使用Dataset和DataLoader这两个工具类来构建数据管道. Dataset定义了数据集的内容,它相当于一个类似列表的数据结构,具有确定的长度,能够用索引获取数据集中的元素. ...

  8. 速成pytorch学习——4天中阶API示范

    使用Pytorch的中阶API实现线性回归模型和和DNN二分类模型. Pytorch的中阶API主要包括各种模型层,损失函数,优化器,数据管道等等. 一,线性回归模型 1,准备数据 import nu ...

  9. 速成pytorch学习——2天

    Pytorch的基本数据结构是张量Tensor.张量即多维数组.Pytorch的张量和numpy中的array很类似. 本节我们主要介绍张量的数据类型.张量的维度.张量的尺寸.张量和numpy数组等基 ...

最新文章

  1. java双等号和equals_Java中的 equals和双等号,你懂吗?
  2. docker 容器占用内存_如何限制Docker容器的内存
  3. 收集国内著名互联网公司前端/UED部门的blog,方便学习交流
  4. Makefile 实际用例分析(一) ------- 比较通用的一种架构
  5. 将列表转成数组_漫画 | 什么是散列表(哈希表)?
  6. ubuntu报错:E: 仓库 “http://ppa.launchpad.net/docky-core/ppa/ubuntu bionic Release” 没有 Release 文件
  7. sgrdb mysql_GreatDB数据库在HA架构的单调度集群模式下如何手动后台启停?
  8. main的方法是Java_Java中的main()方法
  9. 图书管理系统C语言程序设计课程,vs c语言图书管理平台课程设计_图书管理平台c语言程序设计_c语言课程设计 图书管理系统...
  10. 世界上最狠最毒的动物是什么?
  11. Python之 类属性和类方法
  12. apache php的权限,Unix上的Apache PHP写权限
  13. 层次分析法在matlab上的实现
  14. 每天学习写论文——Day24 光说不练假把式,毕设就是第一步
  15. 划词翻译—多种翻译平台集合体积不足1mb——QTranslate
  16. 美团外卖红包,商超生鲜红包,饿了么红包天天领,果蔬抢特价,大额满减券,返利优惠券源代码
  17. 【mysql】mysql数据备份与恢复
  18. 爬取我爱我家租房信息时 问题总结(付代码)
  19. linux报错Loading mirror speeds from cached hostfile解决方法
  20. Java实现抽奖功能

热门文章

  1. 以太坊上Dex交易量环比下降15%
  2. AttributeError: 'Request' object has no attribute 'is_xhr' 报错的解决办法
  3. 原型化系统---失物招领APP
  4. kubernetes(k8s)-介绍2
  5. 使用SQLyog连接MySQL数据库
  6. 事后分析报告(M2阶段)
  7. MVC自学系列之四(MVC模型-Models)
  8. Layout_weight实践效果小结
  9. 【品味人生】毕业十年有感,给年轻人的一点忠告
  10. 三顺,因为你,我笑了。