速成pytorch学习——1天
一、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天相关推荐
- 速成pytorch学习——11天. 使用GPU训练模型
深度学习的训练过程常常非常耗时,一个模型训练几个小时是家常便饭,训练几天也是常有的事情,有时候甚至要训练几十天. 训练过程的耗时主要来自于两个部分,一部分来自数据准备,另一部分来自参数迭代. 当数据准 ...
- 速成pytorch学习——7天模型层layers
深度学习模型一般由各种模型层组合而成. torch.nn中内置了非常丰富的各种模型层.它们都属于nn.Module的子类,具备参数管理功能. 例如: nn.Linear, nn.Flatten, nn ...
- 速成pytorch学习——5天nn.functional 和 nn.Module
一,nn.functional 和 nn.Module 前面我们介绍了Pytorch的张量的结构操作和数学运算中的一些常用API. 利用这些张量的API我们可以构建出神经网络相关的组件(如激活函数,模 ...
- 速成pytorch学习——3天自动微分机制
神经网络通常依赖反向传播求梯度来更新网络参数,求梯度过程通常是一件非常复杂而容易出错的事情. 而深度学习框架可以帮助我们自动地完成这种求梯度运算. Pytorch一般通过反向传播 backward 方 ...
- 速成pytorch学习——10天.训练模型的3种方法
Pytorch通常需要用户编写自定义训练循环,训练循环的代码风格因人而异. 有3类典型的训练循环代码风格:脚本形式训练循环,函数形式训练循环,类形式训练循环. 下面以minist数据集的分类模型的训练 ...
- 速成pytorch学习——8天损失函数
一般来说,监督学习的目标函数由损失函数和正则化项组成.(Objective = Loss + Regularization) Pytorch中的损失函数一般在训练模型时候指定. 注意Pytorch中内 ...
- 速成pytorch学习——6天Dataset和DataLoader
Pytorch通常使用Dataset和DataLoader这两个工具类来构建数据管道. Dataset定义了数据集的内容,它相当于一个类似列表的数据结构,具有确定的长度,能够用索引获取数据集中的元素. ...
- 速成pytorch学习——4天中阶API示范
使用Pytorch的中阶API实现线性回归模型和和DNN二分类模型. Pytorch的中阶API主要包括各种模型层,损失函数,优化器,数据管道等等. 一,线性回归模型 1,准备数据 import nu ...
- 速成pytorch学习——2天
Pytorch的基本数据结构是张量Tensor.张量即多维数组.Pytorch的张量和numpy中的array很类似. 本节我们主要介绍张量的数据类型.张量的维度.张量的尺寸.张量和numpy数组等基 ...
最新文章
- java双等号和equals_Java中的 equals和双等号,你懂吗?
- docker 容器占用内存_如何限制Docker容器的内存
- 收集国内著名互联网公司前端/UED部门的blog,方便学习交流
- Makefile 实际用例分析(一) ------- 比较通用的一种架构
- 将列表转成数组_漫画 | 什么是散列表(哈希表)?
- ubuntu报错:E: 仓库 “http://ppa.launchpad.net/docky-core/ppa/ubuntu bionic Release” 没有 Release 文件
- sgrdb mysql_GreatDB数据库在HA架构的单调度集群模式下如何手动后台启停?
- main的方法是Java_Java中的main()方法
- 图书管理系统C语言程序设计课程,vs c语言图书管理平台课程设计_图书管理平台c语言程序设计_c语言课程设计 图书管理系统...
- 世界上最狠最毒的动物是什么?
- Python之 类属性和类方法
- apache php的权限,Unix上的Apache PHP写权限
- 层次分析法在matlab上的实现
- 每天学习写论文——Day24 光说不练假把式,毕设就是第一步
- 划词翻译—多种翻译平台集合体积不足1mb——QTranslate
- 美团外卖红包,商超生鲜红包,饿了么红包天天领,果蔬抢特价,大额满减券,返利优惠券源代码
- 【mysql】mysql数据备份与恢复
- 爬取我爱我家租房信息时 问题总结(付代码)
- linux报错Loading mirror speeds from cached hostfile解决方法
- Java实现抽奖功能