深度学习的预测建模是现在的开发人员必须要了解的一项技能。
PyTorch是由Facebook开发和维护的主要的开源深度学习框架。
PyTorch的核心是一个数学库,可让你在基于图形k f 2 i 9 C 1的模型上执行高效的计算和自动微分。直接实现这一点是具有挑战性的,尽管值得庆幸的是,现代的PyTorch API提供了类和习语,使你可以轻松开发一套深度t - C ( : ` E -学习模型。
在本教程中,你将找到在PyTorch中开发深度学习模型的分步指南。
完成本教程后,你将知. I , x . R 5 a :道0 Q e:
- Torch和PyTorch之间的区别以及如何安装和确认PyTorch是否正常工作;
- PyTor9 B Q & , [ } Q Hch@ T ? z . u模型的五步生命周期以及如何定义,拟合和评估模型;
- 如何为回归,分类和预测建模任务开发PyTo= 8 F c Krch深度学习模型。
让我们开始吧:
PyTorch教程概述
本教程的重点是将PyTorch API用于常见的深度学习模型开发任务。在此,我? = A P们不会深入研究深度学习的数学和理论。
学习python深度学习的最好方法是实践,然后不断深入学习。看完本文后,你可以回头了解更多的理论v k 。
我将每个代码示例设计为使用最佳实践,并且是独立的,以便你可以将其直接复制并粘贴到项目中,并使其W D :适应你的特% : z ! g定需要。这将x r J y是一个很好的开始,而不是试图从官方文档U ^ H / Y % L T a单独找出API。
这是一个大型教程,因d i o K [ @ : q D此分为三个部,他们是:
1.如q 0 5 R ) 9 B O e何安装PyTorch?
- 什么是Torch和PyTorch?
- 如何安装PyTorch?
- 如何确认已安装好的PyTorch?
2.PyTorch深度学习模型生命周期步骤
- 第一步:j 6 ] v K @准备资料步骤
- 第二步:定义模型步骤
- 第三步:训练模型步骤
- 第四步:评估模型步骤
- 第五步:做出预测
3.如何开发PyTo8 2 9 ` : I & 2 |rch深度学习模型?
- 如何开发用于二进制分类的MLP
- 如何开发F @ i m用于多类分类的MLP
- 如何为回归开发MLP
- 如何开发用于图像分类的CNN
你可以使用Python进行深度学习!
最多需要60分钟,你就能学习完成本教程!
你不需要了解所有内容(至少现在还不了解)。你的目标是端对) | e + k `端地完j E t & , : 3 )成本教程并获得结果,你无需在第一遍就了解所有内容。如果E V 6 5 - J你在学习中遇到了很多问题,可以参考官方API文档,以了解你需要用到的功能。^ K z & x ] B K
你不+ L b - m需要先了解数学。数学是描述算法工作方式C ; A y的一种紧凑方式,特别是线性代数,概率和微积分的工2 p y s具。这些并不是你可以用来学w ~ P 习算法工作方式0 & D G ?的唯一工具。你还可以使用代码并探索具有不同输入和输出的算法行为。! 9 J ( #了解数学不会告诉你选择哪种算法或如何对其进行最佳配置。你只能通过精心控制的实验来发现这一点。
你不需知道算法的工作原理。^ h H P ; m了解限制以及如何配置深度学习算法非常重要。但是学习算法可能会在以后出现。你需要在很长一段时间内慢慢地建立这种算法知识。今天,从熟悉该平台开始。
你不需成为Python程序员。如果你是PytT i 3hon语言的新手,它的语法可能很直观+ z g f 。就像其他语言一样,专注于函5 ~ f r ( r x数调用(例如function())和赋值(例如a =“ b”)。这将为你提供大部分帮助。你是开发人员,你知道如何快速掌握语言的基础知识。
你不需成为深度学习专家。你可以了解各L K n X种算法的优点和局限性,并且可r m I 9 ( ~ 以阅读大量教程来深入学习深度学习项目的步骤。
1.如何安1 % q u装~ o G & ` U B fPyTorch
在本节中,您将发现什么e G p是PyTorch,如何安装以及如何确认PyTorch已正确安装。
1.1.什么是Torch和PyTorch?
PyTorch是由Facebook开发和维护的用G E 5于深度学习的开源Python库。
该项目于2016年开始,并迅速成为开发人员和研究人员的流行框架。
Torch(Torch7)是一个用C编写的用于深度学习的开源项目,通常通过Lua界面使用。这是PyTorch的前期项目,不再积极开发。PyTorch 在名称中包含“ T{ 8 7 B ^ corch ”,以“ Py ”前缀表示先前的炬管库,该前缀表示新项目的Python焦点。
PyTorch API简单灵活,使其成为学者和研究人员在开发新的深度学习模型和应o . b用程序时的最爱。广泛使用已导致针对特定应用程序(例如文本,计算机视觉和音频数据)进行了许多扩展,并且可能预先训练了可直接使用的模型。因此,它可能是学者使用的最受欢迎的库。
PyTorch的灵活性是以易用性为代价,特别是对于初学者来说,相比于诸如简化接口Ke; E : X ? sras。选择使用PyTorch而S r q 1 j _ w不是Keras会放弃一些易用性,更陡峭的学习曲线以及更多的代码以提供更大的灵活性,并且可能会使学术界更加活跃。
1.2.如何安装PyTorch
在安装PyTorch之前,请确保已安装Python,例如Python 3.6或更高版本。
如果你没有安装Python,则可以使用Anaconda安装它。本教程将向你展示如何:
- 如何使用Anaconda设置Python环境进行机器学习
有很多方法可以安装PyTorch开源深度学习库。
在你的工作站上安{ h N D装PyTorch的最[ 5 0 w } `常见,也许是最简单的方法是使用pip。
例如,在命令行上,你可以输入:
sudo pip install torch
深度学习最流行的应用也许是用于计算机视觉,而PyTorch计算机视觉软件包被称为k C b 7 4 i a + y“ torchvision”。
强烈建议安装torchvision,它可以按以下方式安装:
sudo pip install torchvisi U ! * e ` B ! qon
如果您更喜欢使用特定于平台或软件包管理器的. l _ k f $安装方法,则可以在. l A I w :下方链接查看f G z : L y 8 I安装说明的完整列表:
- PyTorch安装指南(hE H % Lttps://pytor& g @ 0 / v fch.org/get-started/locally/)
现在无需设置GPU。
本教程中的所有示例都可以在现代CPU上正常工作,如果要为GPU配置PyTC = h T J v Z V eorch,则可以在完成本教程后进行操作。
1.3.如何确认已安装PyTorch
一旦安装了P{ F VyTorch,重要的是确认该库已成功安装并且可以开始使用它。
不要跳过此步骤。
如果未正确安装PyTorch或在此步骤上引发错误,则以后R 4 i W L . ) H将无法运z c = O行示例。
创建一个名为version3 - 3 t Ls.py的新文件,并将m c F以下代码复制并粘贴到该文件中。
# 检查 pytorch 版本
import torch
print(toK n S Krch.__version__)
保存文件,然后打开命令行并将目录更改为保存文件的位置。
然后输入:
pythD r u t y U | Son versions.9 S y C R . B lpy
然后,你应该看到如下输出:
1.3.1
这确认PyTorch已正确安装,并且我们都使用d d O l相同的版本S ? *。
这也向你展示了如何从命令行运行Python脚本,我建议以这种方式从命令行运行所有代码,{ h 3 .而不是从笔记本或IDE运行Y e L S O ) n ?。
2. PyTorch深度学习模型生命周期
在本部分中,你将发现深度学习模型的生命y ` K周期以及可用于定义模型的PyTorch API。
模型具有生命周期,这一非常简单的知识为建模数据集和理) . g L N 2解PyTorch API提供了基础。
生命周期中的五个步骤如下:
- 1.准备数据。
- 2.定义模型。Q z s O D
- 3.训练模型。
- 4.评估模型。
- 5.做出@ - u L预测。
让我们依次仔细研究每个步骤。
注意:这是最n 8 * 3 y A m简单,最常见r h G s j或最惯用的方法,此外,还有很多其他方法可以使用PyTorch API来完成每个步骤。
步骤1:准备资料
第一步是加载并准备数据。
神经网络模型需要数字输入数据和数字输出数据。
你可以使用标准E a H的Python库来加载和准备表格数据,例如CSV文件。例如,Pandas可用于加载CSV文件,而scikit-learn的工具可用于编码分类数据,例如类标签。
PyTorch提供了Dataset# P H r L : g类,你可以扩展该类并对其进行自定义以加载数据集。
例如,你的数据集对T J z 0象的构造函数i J F可以加载你的数据t 7 b L @文件F e ; 0(例如CSV文件)。然后,你可以覆盖用于获取数据集长度(行或样本数)的__len __()函数,以及用于通过索引获取特定样本的__getitem __()函数。
加5 B C x s G )载数据集时,你还可以执行任何必需的转# D J换,例如缩放或编码。
下面提供了自定义数据集J * n 7 m F e类的框架。
# dataset definition
clas6 q F 2 @ e !s CSVDataset(DD . X uataset):
# load the dataset
def __init__(self, path):
# store the inputs anj ~ N ) x R $ vd outputs
self.X = ...
self.y = ...
# number of rows in t{ { , jhe dal ! Z Staset
def __W G ! ( / * 8len__(self):
return len(self.X)
# get a row at an index
def __getitem__(self, idx):
return [self.X[: t F ! l J z 9idx], s4 O ) / R S Y felf.y[idx]]
加载后,PyTorch将提供DataLoader类以在模型的训练` , ? ! D和评估期间导航数据集实例。
可以为训练数据集,测试数据集甚至} j [ J验证数据集创建一个DataLoader实例。
所述random_split()函数可以被用于将数据集分裂成训练集和测试集。拆分后,可以将数据集中的行的选择以及批处理大小以及是否应在每个时期重新整理数据,提供给DataL! Q #oader。
例如,我们可以通过传入数据集中行的选定样本来定义DataLoader。
...
# create the dataset
dataset = CSVDataset8 d I O $ ?(...)
# select rows from the dataset
train, test = random_split(] + H U v bdataset, [[...], [...]])
# create a9 5 c t { : a I 1 data loader for traS l *in and test sets
trai$ C M X } ` 5n_dl = DataLoader(train, batch_sizW g 7 % ye=32, shuffle=True)
test_dl = DataLoader(test, batch_size=1024) w f, shuffle=False)
定义后,就可以枚举DataLoader,每次迭代产生一批样品。
...
# train the model
for i, (inputs, targets) in en5 k C ( D 5 # 4umerate(train_dl):
...
步骤2:定义; 9 v f x z Z 2模型
下一步是定义t f n模型。
在PU @ PyTorch中定义模型的习惯用法涉及定义扩展Module类的类。
您的类f : s a 0 S H的构造函数定义模型的各层,而x } } e P D S ~ rforward()函数Y 4 1则是重写,它定义了如何通过模型的已定义各层转发输入。
许多层是可用的,诸如线性为完全连接层,Cw b 0 b + d Ionv2d卷积层,并且MaxPool2d为汇集层。
激活函数也可以定义为层,例如ReLU,Softmax和Sigmoid。
下面? / & : n b是一个具有一层的简单MLP模型的示例。
# model definition
class MLP(Module):
# define model elements
def __init__(self, n_inputs):
super(MLP,+ c p - + self).__init__()
self.layer = Linear(n_inputs, 1)
self.activation = Sigmoid()
# forward propagate input
def forward(self, X):
X = self.layer(X)
X = self.activation(Xu j c L B R)
retur8 l Y q mn X
给定图层的权重也可以在构造函数中定义该图层之后进行初始化。
常见示例包1 N #括XavieV n [ l 0 3 (r和He权重初始化方案。例G 2 w U O [如:
...
xavier_uniform_(self.lay/ ~ G Y r G q Ker.weight)
步骤3:训练模型
训练过程要求您定义损失函数和优化算法。
常见的损失函数包括:
- BCELoss:二进制分类的二进制交叉熵损失。
- CrossEntrB A h Q ^ e IopyLoss:用于多类分类的分类交叉熵损失D 2 ) C B % y。
- MSELoss:回归的均方损失。
有S [ K关一般损失函数的更多信息,可通过下方链接查看:
- 训练深度学习神经网络的& . s P X v Z损耗函数(, X T i C 4https://machinelX 1 _ a +earningmastery.com/loss-and-loss-functions-for-training-deep-learning-neural-networks/)
随机梯度下降用于优化,标准算法由SGD类) + &提供,尽管该算法的其他版K r i 8 ^ 3 K )本也可用,例如Adam。
# define the optimization
critZ x N $erion = MSELoss()
optimizer = SGD(model.parameters(), lr=0.01, momentum=0.9)
训A + M S k N 7练模型涉及枚举训练数据集的DataLom X & ~ 2ader。
首先,需要训练次数r z / : y q j &的循环。然后,对于微型批次,需要一个内部回路来进行随机梯度下降。
...
# enumerate epochs
for epoch in range(100):
# enumerate mini batches
for i, (inpu_ ^ S U r } w I (ts, targeB # f 0ts) in enumerate(train_dl):
...
对模型的每次更新都涉及相, 4 $ ) ] Y ;同的常规模式,其中包括:
- 清除最后的误差梯度。
- 输入通过模型的正向传递。
- 计算模型输出的损失。
- 通过模型反向传播错误。
- 更新模型以减少损失。
例如:
...
# clear the gr; W m ] Z e 1adients
optimizer.zero_grad()
# compute the model output
yhat =k [ Y K e | model(inputs)
# calculate loss
loss = criterion(yhat, targets)
# c ) O o # Ere, & ^ @ ^ Vdit assignment
loss.backward()
# update model weights
optimizer.step()
步骤4:评估模型
一旦模型适合,就可以在测试数据集上对其进行评估。
这可以通过将DataLoader用于测试数据集并收集测试集的预测,然后将预测与测试集的期望值进行比较并计算性能指标来实现。
...
for i, (inputs, targets) in enumerate(test_dl):
# evaluate the mos R 6 L Y h (del on the test set
yhat = model(inputs)
...
步骤5W C o L Z ^:做出预测
拟合模型可用于对新数据进行预测。
例如,你可能只有一张图像或一行数据,并且想要进行预测。
这要求你将数据包装在PyTorch TensoQ ? X $r数据结构中。
张量只是NumPy数组的PyTorM , M 3ch版本,用于保存数据。它还允许你在模型图中执行自动微分任务,例如在训练模型时调用back()。
预测也将是张量,尽管你x 4 P : 5 b . !可以通过从自动微8 i _ z 1分图中分离张量并调用NumPy函数来检索NumPy数组。
...
# convert row to data
row = Variable(Tensor([row]).float())
# ma6 $ E 8ke prediction
yhat = model(row)
# retrieve numpy array
yhat = yhat.detacS 2 A N L M Kh().numpyz I w % ] . W()
既然我们已经从高层次上熟悉了PyTorch API和模型生命周期,那么让我们看一下如何从头开始开发一些标准的深度学习模型。
3.如何开发PyTorch深度学习模型
在本节中,v H t v j你将发现如何使用标准的深度学习模型(包括多层感知器(MLP)和卷积神经网q s V / ;络(CN* l 4 } u C a ~ +N))来开发,评估和做出预测。
多层感知器模型(简称MLP)是标准的全连接神经网络模型。
它由节点层组成,其中每个节点连接到上一层的所有输出,每个节点的输出连接到下一层节点的所有输入。
MLP是具有一个或多个完全连接的层的模型。此模型适用于表格数据,即表格或电子表格中的数据,每个变量一列,每个变量一行。你可能需要使x 5 7 _ F a A E用MLP探索三个预测建模问题:二进制分类、多分类、回归。
让我k u 4 Y o 3 7 m {们针对每种@ 6 H n 8 H ;情况在真实数据集上拟合模型。
注意:本节中的模型有8 ` -效,但未优化,看看是否可以改善他们的! l 1 ( r c表现。
3.1.如何b J 2 | A ! } s开发用于二进制分l # ? g +类的MLP
我们将使用电离层二进制(两类)分类数m . @ z [ ] M据集来演示用5 g - j于二进制分类的MLP。
该数据集涉及预测大气层中是否存在某种结构或D a S / c 3 : ` H是否具有给定的雷达回波。
数据集将使用Pa` # ` ; Z o r v Endas自动下载H O M 5,更多信息可以_ t o l g o y Z通过下方链接查看。
- 电离层数据集(csv)(https://raw.githubusercontent.com/jbrownlee/Datasets/master/ionosphere.csv);
- 电离层数D K o 2 M @ &据集描述(https://raw.githubuserc{ P m ~ ~ontentJ Y B X x U /.@ 5 v gcom/jbrownlee/Datasets/master/ionosphere.names)。
我们将使用LabelEncode! y ` Or将字符串标签编码为整数值0和1。该模型将适合67%的数据,其余的33%将用于评l . e K x估,请使h 0 z ^ 6 p 1 Q用train_test_split()函数进行拆分。
将“ relu ”激活与“ He Uni- P 7 |form ”权重初始化一起使用是一个好习惯5 : A h [ K 1 Y X。在训练深度神经网络模型时,这种组合可以大大克服梯度消失的问题。有关ReLU的更多信息,可通过下方链接查看教程:
- 整流线性单元(ReLU! { P g P b u B h)的简要介绍(https://machinelearningmastery.co5 y t (m/rectified-linear-activation-function-for-deep-learning-neural-networks/)
该模型预测1类的可能性,并使用S型激活函数。该模型使用随机梯度下降法进行了优化,旨在最大程度地减少二进制交叉熵损失。
下面 X U } z列出了完整的示例。
# pytorch ml! j W 6 _ y l lp for binary classification
from numpI O U _ 3 My import vstack
from pandas import read_csv
from sklea| 1 X F P 7 z Mrn.prt l 4 a 9 weprocessing impora _ T Kt LabelEk a 1 ~ncoder
from sklearn.metrics import accuracy_score
f@ D ( = u J Drom torch.utils.data import Dataset
from torch.utils.data import DataLoader
from torch.utils.data import random_split
fromx n q torch import Tensor
frg J Nom torch.nn import Linear
from torch.nn is A Y s [ g D K vmport ReLU
from torch.nn imV | xport Sigmoid
from torch.nn import Module
from torch.opM F % Ltim import SGD
from torch.nn impo* 2 P + `rt BCELoss
from torch.nn.init import kaiming_uniform_
from torch.nI P G X gn.init import xavierx A x # C_uniform_
# dataset definition
class CSVData! A h Bset(Dataset):
#G e load the dataset
def __init__(s( t 5 ^ h eelf, path):
# load the csv file as a datafra~ U $ p g gme
df = read_csv(path, header=None)
# store the inputs and outputs
self.X = df.values[:, :-1]
self.y = df.value* v * g m g K ~ 4s[:, -1H h -]
# ensure in! o aput data is floats
self.X = self.X.astype(\'floh . 6 b ] | j 9 tat32\')
# label encode targ| ` 2 n Xet and ensure the values are floats
self.y = LabelEncoder().fit_transform(self.Z B | o O _ 0 ty)
self.y = self.y.astype(\'float320 c v L 5 1 B\')
self.y = self.y.reshape((len(self.y), 1))
# number of rows in the dataset
def __@ I =len__(self):
return len(self.X)
# get a rC b n 4ow at an index
def __getitem__(self, idx):
retuT U `rn [self.X[idx], self.y[idx]]
# get indexes for train and test rows
def get_splits(self, n_test=0.33):
# determine sizes
test_size = round(n_test * len(self.X))
train_size = len(selX n ) c %f.X) - test_siz; t h , 5 3 9 Xe
# calculate the split
return random_Q w e z H 5 Msplit(self+ 8 z ^, [train_size, test_size])
# model definition
class MLP(Module):
# define model elements
def __init__(self, n_in= I n F i r nputs):
super(MLP, self).__init__()
# input to first hin ) [ {dden layer
self.hidden1 = Linear(n_inputs, 10)
kaiming_uniform_(self.hidden1.weight, no- y Vnlinearity=\'relu\X x w m M ! c v z')
self.act1 = ReLU()
# sec[ & Kond hidden layer
self.hidden2 = Linear(10, 8)
kaiming_uniform_(self.hidden2.weight, nonlinearity=\'relu\')
self.act2 = ReLU()
# third hidden layer and output
self.hiddO S Aen3 = Linearn f / H *(8, 1)
xavier_T s [ A 7 t 8 ) Ouniform_(self.hi- b G 6 ~ r o F vdden3.wz { ] r ~ J r Reight)
self.act3 = Sigmoid()
# forwarG / : N % & { # /d propagate input
def forward(self, X):
# input to first hidden layer
X = self.hidden1(X)
X =r d M # Q z self.act1(X)
# second hidN d [ B 7den layer
X = self.hidden2(X)
X = self.act2(X)
# third hidden layer and output
X =J l d _ 3 [ 7 self.hidden3(X)
X = self.act3(X)
returu D &n X
# prepare the dataset
def prepare_data(path):
# load tB B X s m zhe das : 4 7taset
dataset = CSVDataset(path)
# calculate split
train, test = dataset.get_splits()
#Q n D d A j prepare data loaders
train_dl = DataLoader(train, batch_size=32, shuffle=True)
test_dl = DataLoQ I F V A C ^ Wader(test, batch_size=1024, shuffle=False)
reti e : r s vurn train_dl, test_dl
# train the model
def train_m$ j H ;odel(train_dl, model):
# define the optimization
criterion = BCELoss()
optimizer = SGD(i * o w G V - 9model.parametersb d O ! { @ ^ 6 K(), lr=0.01, momentum=0.9)
# enumerate epochs
for epoch in range(100):
# enumerate mini batches
for i, (inputs, targets) in enumerate(trai_ 6 { V j z 1n_dl):
# clear the grad% [ f * + 1 J 2ients
o# H zptimizer.zero_grad()
# compute the model output
yhat = modT t 2 _ pel(inputs)
# calculate loss
loss = criterion(yhat, targets)
# credit assignment
loss.backg W l A % = Zward()
# update model weights
optimizer.step()
# evaluate the model
def evaluate_model(test_dl, modev ; 4 Z o C al):
predictions, actuals =: k _ k o . 0 list(), list()
for i, (iY E , c ; x h 0 hnputs, tT ` 8 n $ 0argets) in enumerate(test_dl):
# evaluate the model on the test set
yhat = model(inputs)
# retrieve numpy array
yhat = yhat.detach().numpy()
actual = targets.numpy()
actual = actual.p 7 sreshape((len(actual), 1))
# round to class values
yhat = yhat.round(_ M ? e)
# store
predictions.append(yhat)
acd j h + 9 x w btuals.append(actual)
predictions, ~ 3 + x actuals = vstack(predictions), vstack(actuals)
# calculate accuracy
acc = accuracy_score(actuals, predictions)
return acc
# make a class preG g 5 ] ~ |diction for one row of data
def predict(row, model):
# convert row to data
row = Tensor([row])
# make pred4 + 6 !iction
yhat = model(row)
# retrieve n* n 5 l i R ! Tumpy array
yhat = yhat.detach().numpy()
return yhat
# prepare the data
path = \'https://raw.gith8 , B ( | Qubusercontent.com/jbrownlee/Datasets/master/ionoq q k { a /sphere.csv\'
train_dl, test_dl = prep? m * [ I Y { G uare_data(path)
print(len(train_dld [ F &.d) R } q S dataset), len(test_dl.dataset))
# define the netwo) 5 v m ^rk
model = MLP(34)
# train the model
train_model(train_dl^ 3 8 J a _ B, model)
# evy ? Z | Q )aluate the model
acc = evaluate_model(test_dl, mod_ 6 2 L Kel)
print(. - I = e a u\'Accuracy: %.3f\' % acc)
# make a single prediction (expect class=1)
row = [1,0,0.99539,-U e o ; . +0.05889,0.85243,0.02306,0.83398,-0.37708,1,0.03760,0.85243,-0.17755,0.59755,-0.44945,0.60536,-0.38223,0.84, ) j356,-0.38542,0.5828 ] Y Q V I12,-0.32192,0.56971,-0.29674 & A + b @ - N,0.36946/ D k K,-0.47357,0.56811,-0.51171,0.41078,-0.46168,0.21266,8 _ f n @-0.34090,0.42267,3 F 3 u ? _ ^-0.54487,0.18641,-0.45300]
yhah U O , +t = predict(y 2 sro@ t _ ? ( b 0 $w, model)
print(\'Predicted: %.3f (class=%d)\' % (yhat, ym Y ~ k &hat.round()))
运行示例首先报# X _ D T E Y 2 T告训练和测试数据集的形状,然后拟合模型并在测试数据集上对其进行评估。最后,对单行+ ~ y数据进行预测。
鉴于学习算法的随机性,你的具体结果会有所不同,可以尝试运行该示例几次。
在这种情况下,我们可以看到该模型实现了约94%的分类准确度,然后预测单行数据属于1类的概率为0.99。
235 116
Accuracy: 0.948
Predicted: 0.998 (class=1)
3.2.如何开发用于多类分类; s s的M[ v { NLP
我们将使用c ] b F ] A Z鸢尾花多类分类数据集来演示用于多类分类的MLP。
该问题涉及在给定花的度量的情况下预{ A Q u ;测鸢尾花的种类。
数据集将使用Pandas自动下载,但您可以在此处了解更多信息。
- 虹膜数据集(csv):https://raw.githubusercontent.coW N L r r s 4 9 8m/jbrownle) n 6 v | E 5 G ^e/Datasets/master/iris.csv;
- 虹膜数据集描述:https://raw.githubusercontent.com/jbrownlee/Datasets/master/iris.names。
鉴于它是一个多类分类,因此该模型在输出层中的每个类必须具有一个节点,并使用softmax激活函数。损失函数是交叉[ 1 W熵,它适合于整数编码的类标签(例如,一个类为0,下一类为1,等等)。
下面列出了在鸢尾花数据集上拟合和评估MLP的完整示例。
# pytorch mlp for multicl? Q v w 7 lass clas3 B isificationA ( 9 S p 2 M {
from numpy import vstack
from numpy import aG 0 $rgm5 j F 7 L Yax
from pandas import read_csv
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import accuracy_score
from torch import Tensor
from torch.utils.data import DaP ; X B l !taset
from torch.utils.data import DataLoader
from tori * ] Y c u # M #ch.utils.m T * k ~ L 6 mdata import random_split
from torch.nn import Linear
from torch.nn import ReLU
from torch.nn import Softmax
from torch.nn import Moduled P q 6 M {
from torch.optim impu S Port SGD
from torch.nn@ q h import CrossEntropyLoss
from torch.nn.init import k+ d K I 5aiming_uniform_
from torch.nn.init import xavier_uniform_
# dataset+ ) 5 _ definition
class CSVDataset(Dataset):
# load the dataset
def __init__(self, path):
# load the csv file as a dataframe
df = read_csv(path, header=None)
# store the inputs and outputs
self.X = df.values[:, :-1]
sel; e Yf.y = df.values[:, -1]
# ensur3 * V 9 S 4 W m 3e inG H = O w p Bput data is floats
self.X = self.X.astype(\'float32\')
# label encode target and ensure the valuex Z ) O O O H ds are floats
self.y = LabelE- & V @ Oncoder().fit_transform(self.y)
# number of rows in the dataset
def __len__(self):
return len(self.X)
# gf n n n = V E ret a row at an index
def __getitem__(self, idx):
return [self.X[idx], self.y[idx]]
# get indeZ 5 g B a B R qxes for train and test rows
def get_splits(self, n_test=0.33):
# determine sizes
test_size = round(n_test * len(self.X))
train_size = len(self.X) - te8 A g } T Q i Hst_size
# cR , + d ualculate the spli: $ P = + 5 y .t
return rando) 4 Y V M 9 J ^ 9m_split(h X qself| I I, [train_size,u 0 ; test_size])
# model definition+ ; 5 N ]
class MLP(Module):
# define m` d e k K S R 1 -odel elements
def __init__(self, n_inputs):
super(MLP,{ 4 # B n H X K V self).__init__()
# input to first hidden layer
self.hidden1 = Linear(n_inputs, 10)
kaiming_uniform_(self.hidden1.weiG u i ? Q 8 c T 6ght, nonlinearity=\'relu\')
self.l ; Xact1 = ReLU()
# second hidden layer
self.hidden2 = Li @ ( $inef . lar(10, 8)
kaimd - r ? ! Ving_uniform_$ s 1 : A 3 O K(self.hidden2.weig! q 2 # p Nht, nonlinearity=\'relu\')% h H ? D ; o +
self.act2 = ReLU()
# third hidden layer and outpu: ^ 8 ` 3 ,t
self.hiddeL m W = a f c I =n3 = Lq , j ? } } ~ / !inear(8, 3)
xavier_unifoB F K Y lrm_(self.hidden3.weight)
self.act3 = Softmax(dim=1)
# forward propagate input
def forward(self, X):
# input to first hidden layer
X = self.hidden1(X){ - m a
X = self.act1(X)
# second hidden layer
X = self.hidden2(: ~ g 5 q b YX)
X = self.act2(X)q ! ) R P y J
# output layer
X = self.hidden3(X)
X = self.act3(X)
return X
# prepare the dataset
defR J / E [ prepare_data(path):
# load the dataset
dataset = CSVDataset(path)
# calN J ^culate split
train, test = dataset.get_splits()M E D w d R
# prepare data loaders
train_dl = DataLoader(train, batch_size=32, shuffle=True)
test_dM G P ( wl = DataLoader(test, batch_size=1024, shuffle=FO / . = Zalse)
return train_dl, test_dl
# train the model
def train_model(train_dl, model):
# define the optimization
criterion = CrossEntropyLoss()
optimizer = SGD(model.parameters(), lr=0.01, momen; % # [ * | d ` 8tum=0.9)
# enumerC a # N J * : Kate epochs
for epoch inc M ; F ? = = 5 range(500)F S K z:
# enumerate min: 5 m E h 9 9 0i batches
for i, (inputs,e $ _ ~ i L _ targets) in enumerate(traiS X g u Tn_dl):
# clear t b p r O Yhe gradients
optimizer.zero_grad()
# compute th8 { ue model output
yhat = model(inputs)
# calculate loss
loss = criterio^ U 9n(yhat, targets)
# credi6 G y ( $t assignment
loss.backward()
# update model we7 ( I : 8 : @ights
optimizer.step()
# evaluate the model
deu ^ [fr v ~ # 5 6 { evaluate_model(test_dl, model):
predictions, actuals = list(), list()
for i, (inpu& & T A Kts, targets) in enumerate(test_dl):
# evaluate the model on the test set
yhat = model(inputs)
# retrih K ? 4 Z )eve numpy array
yhat = yhat.detach) D ` Z().numpy()
actual = targets.numY } z _py()
# convert to class) M A l laby R 0 Tels
yhate w g x = argmax(yhat, axis=1)
# reshape for stacking
actual = ac| , p }tual.U W m 8 i A r 7reshape((len(actual), 1)K ~ c ^ +)
yhat = yhr u e ~ ; h $at.reshape((len(yhat), 1))
# store
predictions.append(yhat)
actuals.append(actual)
predict+ ) A . D 7ions, actuals = vstack(predictions), vstack(actuals)
# calculate accuracy
acc = accuracy_score(actuals, predictions)
return acc
# make a class prediction for one row of data
def predict(row, model):
# convert row tE 1 J } } Y c U Vo data
row = Tensor([row])
# make prediction
yhat = model(row)
# retrieve numpy array
yhat = yhat.detach().numpy()
return yhat
# prepare the data
path = \'https://raw.githubusercontent.cb o & H r c 9om/jbrownlee/Datasets/master/iris.csv\'
train_dl, test_dl = prepare_data(path)
print(len(train_dl.datas( t ^ ( }et),& k ^ ` + len(X ^ 2 ! $ c ~ vtest_dl.dataset))
# define the ne, S D u 4 l e Qtwork
model = MLP(4)
# train the model
train_model(traR h ; U o Fin_dl, moU x 3 : ; Edel)
# evaluate the model
acc = evaluate_model(test_dl, model)
print(\'Accuracy: %.3f\' % acc)
# make a single prediction
row = [5.1,= ` C * t ; K3.5,1.4,C d J * :0.2]
yhat = predict(row, model)
print(\'Predicted: %s (class=%d)\' % (yhat, argmax(yhat)))
运行示例首先报告训练和测试数据集的形状,) } q然后拟合模型并在测试数据集上对其进行评估N ) { * ? B 4 W。最后,对单行数据进行预测。
在这种情况下,我们可以看到该模型实现E ~ - Q J v @ ?了约98%的分类精度,然后预测了属于每个类别的一行数据的概率,尽管类别0的概率最高。
100 50
Accuracy: 0.980
Predicted: [[9.5524162e-01 4.4516966e-02 2.4138369e-04]] (class=0)
3.3.如何为回归开发MLP
我们将使用波士顿住房回归数据集来演示用于回归预测建模的ML. g p (P。
这个问题涉及根据房屋和邻里的属性来预测房屋价值。
数据集将使用Pandas自动下载,你可, S B Y以通过下方链接了解更多数据集信息。
- 波士顿住房数据集(csv):https://raw.githubusercontent.com/jbrownle1 p B q z X 3 xe/Datasetsh 2 3/master/housing.csv
- 波士顿房屋数据集描述:https://raw.githubusercontent.com/jbrownlee/Datasets/maB [ * d ;ster/~ y Y k d g j 4 !housing.names
这是一个回归问题,涉及预测单个数值。因k m 6 i x H A O此,输出层具有单个节点,并使用默认或线性激活函数(无激活函数)。拟合模型时,均方误差(mse)损失最小。
回想一下,这是回归,] H 2 Q $ :而不是分类;因此,; c { - 2 : @ 4我们无法计算分类准确性。
- 机器学习中分类和回归之间的差异:https:/C 6 H L L d 1 ~/machinelH L g 5 c [earningmastery.com/classification-versus-reY Y S fgressio5 * b I 0n-in-machine-learning/
下面列出了在波士顿住房数据集中拟合和评估MLP的完整示例。
# pytorch mlp for regression
from numpy import vsta^ D : 2 b G Ack
from numpy import sqrt
from pandas import read_csv
from sklearn.metrics import m| 4 u j ) }ean_squared_error
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
from torch.utils.data import random_split
from torch import Tenso# ] , 0 * K 9r
fro5 n i *m torch.nn import LinearM 9 w H c
from torch.n M u O } 3 E | rn import SO w b ~ % v Yigmoid
from torch.nn import Module
from torch.optim import SGD
from torch.nn impo0 # ( A z 1rt MSELoss
from torch.nn.` z 2 m n ` 5init import xavier_uniform_
# dataset definition
class CSVDataset(Dataseo t V ( it):
# lc ) &oad the dataset
def __} E M Ainit__(self, path):
# load the csv file as a dataframe
df = read_csv(path, header % , ! I=None)
# store the inputs and outputs
self.X = df.B e Yvalues[:, :-1].astype(\'float32\')
self.y = df.valuese P E t ; R Q[:, -1].astype(z , h + p -\'float32\')
# ensure target has the right shape
self.y = self.s @ m y i ; * `y.reshape((len(self.y), 1))
# number of rows5 b K v in the dataset
def __len__(self):
return len(self.X)
# get a row at an index
def __getitem__(self, idx):
return [se# c r a U :lf.X[idx], self.y[idx]]
# get indexes for train and test rows
def get_splits(self, n_test=0.33):
# determine sizes
test_size =0 / e 6 2 . j { n round(n_test * len(( e +self.X))
train_size = len(self.X) - test_size
# calculate the split
return random_split(self, [train_size, test_size])
# model definition? X Q = F S P
class MLP(Module):
# define model elements
def __init__(self, n_inputs):
super(MLP, self).__init__()
# input to first hidden layer
self.hidden1 = Linear(n_inputs, 10)
xavier_uniform_(self.hidden1.weight)
self.act1 = Sigmoid()
# second hidden layer
self.hidden2 = Linear(10, 8)
xavier_uniform_(self.hidden2.weight)
self.act2 = Sigmoid()
# t@ M Z ` D 1 ohird hidden layer and output
self.hidden3 = Li| 2 V Z pnear(8, 1)
xaviem 0 Jr_uniform_(self.hidde _ Pn? ] f w %3.weight)
# forward propagate input
def forward(self, X):
# input to first hidden layer
X = self.hidden1(X)
X = self.act1(X)
# second hp c ( & l Hidden layer
X =h 3 i G self.hidd- I d Z ! Ken2(X)
X = self.act2(X)
# third hidden3 U ! @ S q layer andr g - y & k Q r * output
X = self.hidden3(X)Q g t %
return X
# prepare the dataset
def prepare_data(pathA d @ K):
# load the dataset
datay L set = CSVDataset(pk q w u / D kath)
# calculate split
train, test = dataset.get_splits()
# prepare data loaders
train_dl = DataW H | L + FLoader(train, batch) 9 + V_size=32, shuffleC _ q = z i p 5=True)
test_dl = DataLoader(test, batch_size=1024, shuffle=False)
return train_dl, test_dl
# train the model
def train_model(train_dl, model):
# define the optimization
criterion = MSELoss()
optimizer = SGD(mo) 9 z ( q d : ` idel.parameters(), lr=0.01, momentum=0.9)
# enumerate epochs
for epoch in range(100):
# enumerate mini batches
for i, (inputs, targetw + ! 2 P p ,s) in enumerate(train_dl):
# clear the gradientsp W $ V ! k - n P
optims N L L - Q _izer.zero_grad()
# compute the model output
yhat = model(inputs)
# calculate loss
loss = criterion(yha^ W 3t, targets)
# credit assignment
loss.backw$ } 2 `ard()
# update model weights
optimizer.step()
# evaluat| w * A d ] z Qe the model
def evaluate_model(test_dl, model):
predictii 0 E H I M eons, actuals = list(), list()
for i, (inputs, targey - A N E x =ts) in enumerate(test_dl):
# evaluate the model on the test set
yL q } P R 6 #hat = model(inputs)
# retrieve numpy array
yhat = yhat.detach().numpy()
actual = targets.numpy()
actual = actual.reshape((len(actual), 1))
# store
predictions.append(yhat)
aQ 8 Z t F M ; U rctuals.append(actual)
predictions, actuals = vstack(pret ~ x h Udictio? v _ R U l 6 L {ns), vstack(actuals)
# calculate mse
mse = mean_squared_error; , C O 9 A % 8 =(actualsU U R 9 Y M ] 6 x, predictions)
return mse
# make a class prediction for one row of data
def predict(row, model):
# convert r} , Vow to data
row = Tensor([row])
#u 5 H M G K F y make prediction
yhat = model(row)
#* o P I ? 5 [ retrieve numpy array
yhat = yhat.detach().numpy()
return yhat
# prepare the data
path = \'htA + W d S }tps://raw.githubuF v Fsercontent.com/jbrownlee/Datasets/master/housing.csv\'
train_dl, test_dl = prep) Q ?are_data(path)
print(len(train_dl.dataset), len(test_dl.dataset))
# define the network
model = MLP(13)
# train thei ] Z } O B h L model
train_model(train_dl, model)
# evj 7 i D S } 1 1 @aluate the mS ( ) E 6odey 1 } E 2 4l
mse = evaluate_model(test_dl^ _ a, model)
print(\'Q b O !MSE: %.3f,- E Z RMSE: %.3f\'K u ( / , C Z % A % (mse, sqrt(mse)))
# make a single prediction (expect class=1)
row = [0.00632,18.00,2.31j v +0,0,0.5380,6.5750,65.20,4.0900,1,296.0,15.30,396.90,4.98]
yhat = p~ E iredict(row, model)
print(\'Predicted: %.3. k g b 5 ^ / ^ Nf\' % yhat)
运行示例首先报告训练和测试数据集的形状8 m V W L S g,然后拟合模型并在测试数据集上对其进行评估。最后,对单行数据进行预测。
在这种情况下,我们可以看到该模型的MSE约为82,即RMSE约为9(单/ ] k P w位为千美元)。然后,针对单个示例预测值为21。
339 167
MSE: 82.576, RMSE: 9.087
Predicted: 21.909
3.4.如何开发用于图像分类的CNN
卷积神经网络(简称CNN3 Q h w ! b . E o)是一种专为图像输入而设计的网络。
它们由具有卷积层的模型组成,这些卷积层提取特征(称为特征图),并汇集将特H M 1 n G | ,征分解为最显着元素的层。
尽管CNN可以用于将图像作为输入的各种任务,但它们最适合图像分类任务。
流行的图像分类任务是MNIST手写数字分类。它涉及成l c h - y r ? & 8千上万个手写数字,必须将其分类为0到G O 8 8 S 2 -9之间的数字。
torchvision API提供了便捷功能,可以直接下载和加载此数据集。
下V } t 7面的示例加载数据集并绘制前几张图像。
# load mnist dataset in pytorch
from torA h e ^ ~ q G ech.utils.da| # q f % x L Jta importy i C DataLG Q G - 9 Voader
from torchvision.datasets import MNIST
froy . { ] k Hm torchvision.transforms import Compose
from torchvision.tran[ H Fsforms impor] G ! } D - . { Bt ToTensor
from matplotlib import pyplot
# define location to save or load the dataset
path = \'~/.torch/datasets/mnist\'
# define the transforms to apply to the data
trans = Compose([ToTensor()])
# download and define the datasets
train = MNIST(path, train=True, download=True, transform=trans)
test = MNI( S G C = ~ST(path, trainC Q *=False, download=True, transform=trans)
# define how to enumerate the datasets
train_dl = DataLos 3 : ` x } Bader(train, batch_size=32, shuffle=True)
test_dl = DataLoader(test, batch_s/ s b {ize=32, shuffle=True)
# get one batch of images
i, (inputs, targets) = next(enumerate(train_dl))
# plot some images
for i in range(25):
# de0 n + D / ,fine subplot
pyplot.subplot(5, 5, i+1)$ F Z
# plot raw piB i 1 = * d sxel data
pyplot.imshow(inputs[i][0], cmapS 6 N + K R m a=\'gray\')
# show the figure
pyplot.show()
运行示例将加载MNIST数据集,然后汇总默认的训练和测试数据集。
Tri R ? sain: X=(60000, 28, 28), y=(60000,)
Test: X=(10000, 28, 28), y=(10000,)
然后创建一个图,显示训练数据集中的手写图像示例网格。
MNIST数据集中的手写数字图
我们可以训练CNN模型对MNIST数据集中的图像进行分类。
请注意,图像是灰度像素数据的数组,因此,在将图像用作模型的输入之前,必须向数据添加通道尺寸。
最好将像素值从默认范围0-255缩放为零平均值,标准偏差为1。有关缩放像素值的更多信息,可通过下方p o D N C 链接了解:
- 如何手动z p [缩放图像K ; - P /像素数据以进行深度学习:https://machinelearningmast2 @ Q /ery.com/how-to-manually-scale-a o W + k `i( R H C 2mage-pixel-data-for-deep-learning/
下面列出了在MNIST数据集上拟合和评估CNN模型的完整示例。
# pytorch cnn for multiclass classification
from numpy import vstack
from numpy import argmax
from pandas import read_csv
frF G 9 T D D [ somG & l = sklearn! } q.metrics import ac4 : g X + 5curacy_score
from torchvision.datasets import MNIt ] s j X - -ST
from torchvision.transforms import5 w # ~ # Compose
from torcb d t j J e [hvision.transforms import ToTensor
from torchvision.transforms import Normalize
froM 0 @ !m torch.utils.data import Data^ m m 3 p d JLoader
from torch.nn import Conv2d
from torch.nn import MaxPool2d
from torch.nn im{ $ 5 , = m ] } Tport Linear
from torch.nn import ReLU
from torch.nn import Softmax
froa @ s _ } k y pm torch.nn import Module
from torch.optl w , k & k I dim import SGD
from torch.nn import CrossEntro: z S ] } C $ kpyLoss
from to| . 8 C 5 B Q U 7rz # Q 8 ( nch.nn.init import kaiming_uniform_
from torch.nn.init import xavier_uniform_
# model d! N : } {efinition
class CNN(Module):
# define model elements
def __inG : R T ` } r ,it__(self/ ( l e f f . W, n_channels):
sh 9 K rupA x ! Y W f M ~er(CNN, self).__init9 N ~ x : k__()
# inputW b w Y Y 0 h F B to first hidden layer
self.hidden1 = Conv2d(n_channels, 32, (3,4 Q ] @ . u v3))o T b
kaiming_uniform_(self.hidden1.weight, nonlinearity=\q { u w m J'relu\')
self.act1 = ReLU()
# first pooe } ] W Aling layer
self.pool1 = MaxPol g * B 5 Rol2d((2,2), stride=(2,2))
# second hidden layer
self.hidden2 = Conv2d(32, 32, (3,3))
kaiming_uniform_(self.hidden2.weight, nonlinearity=\'relu\')
self.act2 = ReLU()
# second pooling layer
self.pool2 = MaxPool2d((2,2),] e F s H $ + F stride=(2,2))
# fully connected layer
self.hidden3 = Linear(5*5*32, 100)
kaimin& z b 0g_uniform_(self.hidden3.t B [ d )weight, non@ H _linearity=\'relu\')
self.act3 = ReLU()
# output layer
self ` L s . O.hiddef c } ; *n4 = Linear(100, 10)
xavier_uniform_(self.hidden4.weight)
self.act4 = Softmax(dim=I 7 1 u1)
# forward propagate input
def for1 D + Z B ^ TwaN [ 3 j - d E -rd(self, X):
# inp3 F ~ ` h Kut to] R d 6 d z ( first hidden layer
X = self.hidden1(X)
X = self.act1(X)
X = self.pool1(X)
# second hidden layer
X = self.hidden2(X)
X = sel Z b W ` e 6f.7 5 ( } P Dact2(X)
X = self.pool2(X)
# flatten
Xy U _ _ B / L = X.view(-1t N e [ 9 - 7 r, 4*4*50)
# third hidden layer
X = self.hidden3(X)
X = self.act3(X)
# output layer
X = self.hidden4(X)
X = self.act4(X)
return X
# prepare the d
本文系本站编辑转载,文章版权归原作者所有,内容为作者个人观点,转载目的在于传递更多信息,并不代表本站赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请与本站联系,本站将在第一时间删除内容!