PyTorch - 快速指南


PyTorch - 简介

PyTorch 被定义为 Python 的开源机器学习库。它用于自然语言处理等应用。它最初是由Facebook人工智能研究小组开发的,Uber的Pyro概率编程软件就是建立在它的基础上的。

最初,PyTorch 是由 Hugh Perkins 开发的,作为基于 Torch 框架的 LusJIT 的 Python 包装器。PyTorch 有两个变体。

PyTorch 在 Python 中重新设计和实现了 Torch,同时为后端代码共享相同的核心 C 库。PyTorch 开发人员调整了此后端代码以高效运行 Python。他们还保留了基于 GPU 的硬件加速以及基于 Lua 的 Torch 的可扩展性功能。

特征

PyTorch 的主要特点如下:

简单的界面- PyTorch 提供易于使用的 API;因此它被认为是非常简单的操作并且在Python上运行。这个框架中的代码执行非常简单。

Python 用法- 该库被认为是 Pythonic,它与 Python 数据科学堆栈顺利集成。因此,它可以利用Python环境提供的所有服务和功能。

计算图- PyTorch 提供了一个出色的平台,可提供动态计算图。因此,用户可以在运行时更改它们。当开发人员不知道创建神经网络模型需要多少内存时,这非常有用。

PyTorch 因具有三个抽象级别而闻名,如下所示 -

  • 张量 - 在 GPU 上运行的命令式 n 维数组。

  • 变量 - 计算图中的节点。这存储数据和梯度。

  • 模块 - 将存储状态或可学习权重的神经网络层。

PyTorch 的优点

以下是 PyTorch 的优点 -

  • 很容易调试和理解代码。

  • 它与 Torch 一样包含许多层。

  • 它包含很多损失函数。

  • 它可以被视为 NumPy 对 GPU 的扩展。

  • 它允许构建结构依赖于计算本身的网络。

TensorFlow 与 PyTorch

我们将在下面研究 TensorFlow 和 PyTorch 之间的主要区别 -

火炬 TensorFlow

PyTorch 与 Facebook 中积极使用的基于 lua 的 Torch 框架密切相关。

TensorFlow 由 Google Brain 开发并在 Google 积极使用。

与其他竞争技术相比,PyTorch 相对较新。

TensorFlow 并不新鲜,被许多研究人员和行业专业人士视为随身工具。

PyTorch 以命令式和动态方式包含所有内容。

TensorFlow 包括静态图和动态图的组合。

PyTorch 中的计算图是在运行时定义的。

TensorFlow 不包含任何运行时选项。

PyTorch 包括针对移动和嵌入式框架的部署功能。

TensorFlow 更适合嵌入式框架。

PyTorch - 安装

PyTorch 是一种流行的深度学习框架。在本教程中,我们将“Windows 10”视为我们的操作系统。成功的环境设置步骤如下 -

步骤1

以下链接包含一个软件包列表,其中包括适用于 PyTorch 的软件包。

https://drive.google.com/drive/folders/0B-X0-FlSGfCYdTNldW02UGl4MXM

您需要做的就是下载相应的软件包并安装它,如以下屏幕截图所示 -

火炬

包

第2步

它涉及使用 Anaconda Framework 验证 PyTorch 框架的安装。

以下命令用于验证相同的内容 -

conda list
PyTorch框架

“Conda list”显示已安装的框架列表。

康达清单

突出显示的部分表明 PyTorch 已成功安装在我们的系统中。

神经网络的数学构建模块

数学在任何机器学习算法中都至关重要,它包含各种数学核心概念,以便以特定方式设计正确的算法。

下面提到了数学主题对于机器学习和数据科学的重要性 -

机器学习

现在,让我们关注机器学习的主要数学概念,从自然语言处理的角度来看,这很重要 -

向量

向量被认为是连续或离散的数字数组,由向量组成的空间称为向量空间。向量的空间维度可以是有限的,也可以是无限的,但据观察,机器学习和数据科学问题处理固定长度的向量。

矢量表示如下所示 -

temp = torch.FloatTensor([23,24,24.5,26,27.2,23.0])
temp.size()
Output - torch.Size([6])

在机器学习中,我们处理多维数据。因此,向量变得非常重要,并被视为任何预测问题陈述的输入特征。

标量

标量被称为具有仅包含一个值的零维度。当谈到 PyTorch 时,它不包括零维度的特殊张量;因此声明如下 -

x = torch.rand(10)
x.size()
Output - torch.Size([10])

矩阵

大多数结构化数据通常以表格或特定矩阵的形式表示。我们将使用一个名为 Boston House Price 的数据集,该数据集可以在 Python scikit-learn 机器学习库中轻松获得。

boston_tensor = torch.from_numpy(boston.data)
boston_tensor.size()
Output: torch.Size([506, 13])
boston_tensor[:2]
Output:
Columns 0 to 7
0.0063 18.0000 2.3100 0.0000 0.5380 6.5750 65.2000 4.0900
0.0273 0.0000 7.0700 0.0000 0.4690 6.4210 78.9000 4.9671
Columns 8 to 12
1.0000 296.0000 15.3000 396.9000 4.9800
2.0000 242.0000 17.8000 396.9000 9.1400

PyTorch - 神经网络基础知识

神经网络的主要原理包括基本元素的集合,即人工神经元或感知器。它包括几个基本输入,例如 x1、x2….. xn,如果总和大于激活电位,则产生二进制输出。

样本神经元的示意图如下 -

样本神经元

生成的输出可以被视为具有激活势或偏置的加权和。

$$输出=\sum_jw_jx_j+偏差$$

典型的神经网络架构如下所述 -

神经网络架构

输入和输出之间的层称为隐藏层,层之间连接的密度和类型就是配置。例如,全连接配置将 L 层的所有神经元连接到 L+1 层的神经元。为了获得更明显的定位,我们可以仅将局部邻域(例如九个神经元)连接到下一层。图 1-9 展示了两个具有密集连接的隐藏层。

各种类型的神经网络如下 -

前馈神经网络

前馈神经网络包括神经网络家族的基本单元。这种类型的神经网络中的数据移动是通过现有的隐藏层从输入层到输出层。一层的输出作为输入层,对网络架构中任何类型的循环都有限制。

前馈神经网络

循环神经网络

循环神经网络是指数据模式在一段时间内发生相应变化的情况。在RNN中,同一层用于在指定的神经网络中接受输入参数并显示输出参数。

循环神经网络

可以使用 torch.nn 包构建神经网络。

构建神经网络

这是一个简单的前馈网络。它接受输入,将其逐层输入,最后给出输出。

在 PyTorch 的帮助下,我们可以使用以下步骤进行神经网络的典型训练过程 -

  • 定义具有一些可学习参数(或权重)的神经网络。
  • 迭代输入数据集。
  • 通过网络处理输入。
  • 计算损失(输出距离正确还有多远)。
  • 将梯度传播回网络参数。
  • 更新网络的权重,通常使用如下所示的简单更新
rule: weight = weight -learning_rate * gradient

机器学习的通用工作流程

如今人工智能的发展趋势更加明显。机器学习和深度学习构成了人工智能。下面提到的维恩图解释了机器学习和深度学习的关系。

关系机器学习

机器学习

机器学习是一门科学的艺术,它允许计算机按照设计和编程的算法运行。许多研究人员认为机器学习是迈向人类水平人工智能的最佳途径。它包括各种类型的模式,例如 -

  • 监督学习模式
  • 无监督学习模式

深度学习

深度学习是机器学习的一个子领域,其中相关算法受到称为人工神经网络的大脑结构和功能的启发。

通过监督学习或从标记数据和算法中学习,深度学习变得非常重要。深度学习中的每种算法都经历相同的过程。它包括输入的非线性变换的层次结构,并用于创建统计模型作为输出。

机器学习过程是使用以下步骤定义的 -

  • 识别相关数据集并准备进行分析。
  • 选择要使用的算法类型。
  • 根据所使用的算法构建分析模型。
  • 在测试数据集上训练模型,并根据需要进行修改。
  • 运行模型以生成测试分数。

PyTorch - 机器学习与深度学习

在本章中,我们将讨论机器学习和深度学习概念之间的主要区别。

数据量

机器学习适用于不同数量的数据,主要用于少量数据。另一方面,如果数据量快速增加,深度学习就会有效地工作。下图描述了机器学习和深度学习在数据量方面的工作原理 -

金额数据

硬件依赖性

与传统机器学习算法相反,深度学习算法的设计严重依赖于高端机器。深度学习算法执行大量的矩阵乘法运算,需要巨大的硬件支持。

特征工程

特征工程是将领域知识放入指定特征中以降低数据复杂性并形成对学习算法可见的模式的过程。

例如,传统的机器学习模式侧重于特征工程过程所需的像素和其他属性。深度学习算法专注于数据的高级特征。它减少了为每个新问题开发新特征提取器的任务。

PyTorch - 实现第一个神经网络

PyTorch 包含创建和实现神经网络的特殊功能。在本章中,我们将创建一个简单的神经网络,其中一个隐藏层开发单个输出单元。

我们将使用以下步骤使用 PyTorch 实现第一个神经网络 -

步骤1

首先,我们需要使用以下命令导入 PyTorch 库 -

import torch 
import torch.nn as nn

第2步

定义所有层和批量大小以开始执行神经网络,如下所示 -

# Defining input size, hidden layer size, output size and batch size respectively
n_in, n_h, n_out, batch_size = 10, 5, 1, 10

步骤3

由于神经网络包含输入数据的组合来获取各自的输出数据,因此我们将遵循与下面给出的相同的过程 -

# Create dummy input and target tensors (data)
x = torch.randn(batch_size, n_in)
y = torch.tensor([[1.0], [0.0], [0.0], 
[1.0], [1.0], [1.0], [0.0], [0.0], [1.0], [1.0]])

步骤4

借助内置函数创建顺序模型。使用以下代码行创建一个顺序模型 -

# Create a model
model = nn.Sequential(nn.Linear(n_in, n_h),
   nn.ReLU(),
   nn.Linear(n_h, n_out),
   nn.Sigmoid())

步骤5

在梯度下降优化器的帮助下构建损失函数,如下所示 -

Construct the loss function
criterion = torch.nn.MSELoss()
# Construct the optimizer (Stochastic Gradient Descent in this case)
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01)

步骤6

使用给定的代码行通过迭代循环实现梯度下降模型 -

# Gradient Descent
for epoch in range(50):
   # Forward pass: Compute predicted y by passing x to the model
   y_pred = model(x)

   # Compute and print loss
   loss = criterion(y_pred, y)
   print('epoch: ', epoch,' loss: ', loss.item())

   # Zero gradients, perform a backward pass, and update the weights.
   optimizer.zero_grad()

   # perform a backward pass (backpropagation)
   loss.backward()

   # Update the parameters
   optimizer.step()

步骤7

生成的输出如下 -

epoch: 0 loss: 0.2545787990093231
epoch: 1 loss: 0.2545052170753479
epoch: 2 loss: 0.254431813955307
epoch: 3 loss: 0.25435858964920044
epoch: 4 loss: 0.2542854845523834
epoch: 5 loss: 0.25421255826950073
epoch: 6 loss: 0.25413978099823
epoch: 7 loss: 0.25406715273857117
epoch: 8 loss: 0.2539947032928467
epoch: 9 loss: 0.25392240285873413
epoch: 10 loss: 0.25385022163391113
epoch: 11 loss: 0.25377824902534485
epoch: 12 loss: 0.2537063956260681
epoch: 13 loss: 0.2536346912384033
epoch: 14 loss: 0.25356316566467285
epoch: 15 loss: 0.25349172949790955
epoch: 16 loss: 0.25342053174972534
epoch: 17 loss: 0.2533493936061859
epoch: 18 loss: 0.2532784342765808
epoch: 19 loss: 0.25320762395858765
epoch: 20 loss: 0.2531369626522064
epoch: 21 loss: 0.25306645035743713
epoch: 22 loss: 0.252996027469635
epoch: 23 loss: 0.2529257833957672
epoch: 24 loss: 0.25285571813583374
epoch: 25 loss: 0.25278574228286743
epoch: 26 loss: 0.25271597504615784
epoch: 27 loss: 0.25264623761177063
epoch: 28 loss: 0.25257670879364014
epoch: 29 loss: 0.2525072991847992
epoch: 30 loss: 0.2524380087852478
epoch: 31 loss: 0.2523689270019531
epoch: 32 loss: 0.25229987502098083
epoch: 33 loss: 0.25223103165626526
epoch: 34 loss: 0.25216227769851685
epoch: 35 loss: 0.252093642950058
epoch: 36 loss: 0.25202515721321106
epoch: 37 loss: 0.2519568204879761
epoch: 38 loss: 0.251888632774353
epoch: 39 loss: 0.25182053446769714
epoch: 40 loss: 0.2517525553703308
epoch: 41 loss: 0.2516847252845764
epoch: 42 loss: 0.2516169846057892
epoch: 43 loss: 0.2515493929386139
epoch: 44 loss: 0.25148195028305054
epoch: 45 loss: 0.25141456723213196
epoch: 46 loss: 0.2513473629951477
epoch: 47 loss: 0.2512802183628082
epoch: 48 loss: 0.2512132525444031
epoch: 49 loss: 0.2511464059352875

PyTorch - 神经网络到功能块

训练深度学习算法涉及以下步骤 -

  • 构建数据管道
  • 构建网络架构
  • 使用损失函数评估架构
  • 使用优化算法优化网络架构权重

训练特定的深度学习算法是将神经网络转换为功能块的确切要求,如下所示 -

功能块

对于上图,任何深度学习算法都涉及获取输入数据,构建相应的架构,其中包括嵌入其中的一堆层。

如果观察上图,您会发现使用损失函数来评估神经网络权重优化的准确性。

PyTorch - 术语

在本章中,我们将讨论 PyTorch 中一些最常用的术语。

PyTorch NumPy

PyTorch 张量与 NumPy 数组相同。张量是一个 n 维数组,对于 PyTorch,它提供了许多对这些张量进行操作的函数。

PyTorch 张量通常利用 GPU 来加速其数值计算。这些在 PyTorch 中创建的张量可用于将两层网络拟合到随机数据。用户可以手动实现网络的前向和后向传递。

变量和 Autograd

使用 autograd 时,网络的前向传递将定义一个计算图- 图中的节点将是张量,边将是从输入张量生成输出张量的函数。

PyTorch 张量可以创建为变量对象,其中变量表示计算图中的节点。

动态图

静态图很好,因为用户可以预先优化图。如果程序员一遍又一遍地重复使用相同的图,那么当一遍又一遍地重新运行相同的图时,可以维护这种可能成本高昂的前期优化。

它们之间的主要区别在于,Tensor Flow 的计算图是静态的,而 PyTorch 使用动态计算图。

优化包

PyTorch 中的 optim 包抽象了优化算法的思想,该算法以多种方式实现,并提供了常用优化算法的说明。这可以在导入语句中调用。

多重处理

多处理支持相同的操作,以便所有张量在多个处理器上工作。队列会将其数据移至共享内存中,并且仅将句柄发送到另一个进程。

PyTorch - 加载数据

PyTorch 包含一个名为 torchvision 的包,用于加载和准备数据集。它包括两个基本功能,即 Dataset 和 DataLoader,有助于数据集的转换和加载。

数据集

数据集用于从给定数据集中读取和转换数据点。下面提到了要实现的基本语法 -

trainset = torchvision.datasets.CIFAR10(root = './data', train = True,
   download = True, transform = transform)

DataLoader 用于对数据进行混洗和批处理。它可用于与多处理工作线程并行加载数据。

trainloader = torch.utils.data.DataLoader(trainset, batch_size = 4,
   shuffle = True, num_workers = 2)

示例:加载 CSV 文件

我们使用 Python 包 Panda 来加载 csv 文件。原始文件具有以下格式:(图像名称,68 个地标 - 每个地标都有 ax, y 坐标)。

landmarks_frame = pd.read_csv('faces/face_landmarks.csv')

n = 65
img_name = landmarks_frame.iloc[n, 0]
landmarks = landmarks_frame.iloc[n, 1:].as_matrix()
landmarks = landmarks.astype('float').reshape(-1, 2)

PyTorch - 线性回归

在本章中,我们将重点介绍使用 TensorFlow 实现线性回归的基本示例。逻辑回归或线性回归是一种用于分类离散类别的监督机器学习方法。本章的目标是建立一个模型,用户可以通过该模型预测预测变量与一个或多个自变量之间的关系。

这两个变量之间的关系被认为是线性的,即,如果 y 是因变量,x 被认为是自变量,那么两个变量的线性回归关系将如下所示:

Y = Ax+b

接下来,我们将设计一种线性回归算法,它使我们能够理解下面给出的两个重要概念 -

  • 成本函数
  • 梯度下降算法

线性回归的示意图如下

解释结果

$$Y=ax+b$$

  • a的值为斜率。

  • b的值是y − 截距

  • r相关系数

  • r 2相关系数

线性回归方程的图形视图如下 -

解读结果

以下步骤用于使用 PyTorch 实现线性回归 -

步骤1

使用以下代码导入在 PyTorch 中创建线性回归所需的包 -

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import seaborn as sns
import pandas as pd
%matplotlib inline

sns.set_style(style = 'whitegrid')
plt.rcParams["patch.force_edgecolor"] = True

第2步

使用可用数据集创建单个训练集,如下所示 -

m = 2 # slope
c = 3 # interceptm = 2 # slope
c = 3 # intercept
x = np.random.rand(256)

noise = np.random.randn(256) / 4

y = x * m + c + noise

df = pd.DataFrame()
df['x'] = x
df['y'] = y

sns.lmplot(x ='x', y ='y', data = df)
单人训练

步骤3

使用 PyTorch 库实现线性回归,如下所述 -

import torch
import torch.nn as nn
from torch.autograd import Variable
x_train = x.reshape(-1, 1).astype('float32')
y_train = y.reshape(-1, 1).astype('float32')

class LinearRegressionModel(nn.Module):
   def __init__(self, input_dim, output_dim):
      super(LinearRegressionModel, self).__init__()
      self.linear = nn.Linear(input_dim, output_dim)

   def forward(self, x):
      out = self.linear(x)
      return out
input_dim = x_train.shape[1]
output_dim = y_train.shape[1]
input_dim, output_dim(1, 1)
model = LinearRegressionModel(input_dim, output_dim)
criterion = nn.MSELoss()
[w, b] = model.parameters()

def get_param_values():
   return w.data[0][0], b.data[0]

def plot_current_fit(title = ""):
plt.figure(figsize = (12,4))
plt.title(title)
plt.scatter(x, y, s = 8)
w1 = w.data[0][0]
b1 = b.data[0]
x1 = np.array([0., 1.])
y1 = x1 * w1 + b1
plt.plot(x1, y1, 'r', label = 'Current Fit ({:.3f}, {:.3f})'.format(w1, b1))
plt.xlabel('x (input)')
plt.ylabel('y (target)')
plt.legend()
plt.show()
plot_current_fit('Before training')

生成的图如下 -

绘图生成

PyTorch - 卷积神经网络

深度学习是机器学习的一个分支,被研究人员认为是近几十年来迈出的关键一步。深度学习实现的示例包括图像识别和语音识别等应用。

下面给出了深度神经网络的两种重要类型 -

  • 卷积神经网络
  • 循环神经网络。

在本章中,我们将重点关注第一类,即卷积神经网络(CNN)。

卷积神经网络

卷积神经网络旨在通过多层阵列处理数据。这种类型的神经网络用于图像识别或人脸识别等应用。

CNN 与任何其他普通神经网络的主要区别在于,CNN 将输入作为二维数组并直接对图像进行操作,而不是像其他神经网络那样专注于特征提取。

CNN 的主要方法包括解决识别问题。谷歌和Facebook等顶级公司已经投资了识别项目的研发项目,以更快地完成活动。

每个卷积神经网络都包含三个基本思想 -

  • 本地所属领域
  • 卷积
  • 池化

让我们详细了解每个术语。

当地各自领域

CNN 利用输入数据中存在的空间相关性。神经网络的并发层中的每个层都连接一些输入神经元。这个特定区域称为局部感受野。它只关注隐藏的神经元。隐藏神经元将处理上述字段内的输入数据,而不会意识到特定边界之外的变化。

生成局部各自字段的图表示如下 -

当地各自领域

卷积

在上图中,我们观察到每个连接都会学习隐藏神经元的权重,并与从一层到另一层的移动相关联。在这里,各个神经元不时地进行转换。这个过程称为“卷积”。

从输入层到隐藏特征图的连接映射被定义为“共享权重”,其中包含的偏差称为“共享偏差”。

池化

卷积神经网络使用池化层,池化层紧接在 CNN 声明之后。它将用户的输入作为特征图,该特征图由卷积网络产生并准备压缩的特征图。池化层有助于使用前一层的神经元创建层。

PyTorch 的实现

以下步骤用于使用 PyTorch 创建卷积神经网络。

步骤1

导入创建简单神经网络所需的包。

from torch.autograd import Variable
import torch.nn.functional as F

第2步

创建一个具有卷积神经网络批量表示的类。输入 x 的批量形状的尺寸为 (3, 32, 32)。

class SimpleCNN(torch.nn.Module):
   def __init__(self):
      super(SimpleCNN, self).__init__()
      #Input channels = 3, output channels = 18
      self.conv1 = torch.nn.Conv2d(3, 18, kernel_size = 3, stride = 1, padding = 1)
      self.pool = torch.nn.MaxPool2d(kernel_size = 2, stride = 2, padding = 0)
      #4608 input features, 64 output features (see sizing flow below)
      self.fc1 = torch.nn.Linear(18 * 16 * 16, 64)
      #64 input features, 10 output features for our 10 defined classes
      self.fc2 = torch.nn.Linear(64, 10)

步骤3

计算第一个卷积大小从 (3, 32, 32) 到 (18, 32, 32) 变化的激活。

维度的大小从 (18, 32, 32) 更改为 (18, 16, 16)。重塑神经网络输入层的数据维度,使其大小从 (18, 16, 16) 变为 (1, 4608)。

回想一下,-1 从另一个给定维度推断出该维度。

def forward(self, x):
   x = F.relu(self.conv1(x))
   x = self.pool(x)
   x = x.view(-1, 18 * 16 *16)
   x = F.relu(self.fc1(x))
   #Computes the second fully connected layer (activation applied later)
   #Size changes from (1, 64) to (1, 10)
   x = self.fc2(x)
   return(x)

PyTorch - 循环神经网络

循环神经网络是一种面向深度学习的算法,遵循顺序方法。在神经网络中,我们总是假设每个输入和输出都独立于所有其他层。这些类型的神经网络被称为循环神经网络,因为它们以顺序方式执行数学计算,完成一项又一项任务。

下图详细说明了循环神经网络的完整方法和工作原理 -

循环神经网络Ex

在上图中,c1、c2、c3 和 x1 被视为输入,其中包括一些隐藏输入值,即 h1、h2 和 h3,分别传递 o1 的输出。我们现在将重点关注如何实现 PyTorch 在循环神经网络的帮助下创建正弦波。

在训练期间,我们将遵循一种每次使用一个数据点对模型进行训练的方法。输入序列x由20个数据点组成,目标序列被认为与输入序列相同。

步骤1

使用以下代码导入实现循环神经网络所需的包 -

import torch
from torch.autograd import Variable
import numpy as np
import pylab as pl
import torch.nn.init as init

第2步

我们将设置模型超参数,输入层的大小设置为 7。将有 6 个上下文神经元和 1 个输入神经元用于创建目标序列。

dtype = torch.FloatTensor
input_size, hidden_size, output_size = 7, 6, 1
epochs = 300
seq_length = 20
lr = 0.1
data_time_steps = np.linspace(2, 10, seq_length + 1)
data = np.sin(data_time_steps)
data.resize((seq_length + 1, 1))

x = Variable(torch.Tensor(data[:-1]).type(dtype), requires_grad=False)
y = Variable(torch.Tensor(data[1:]).type(dtype), requires_grad=False)

我们将生成训练数据,其中 x 是输入数据序列,y 是所需的目标序列。

步骤3

使用零均值正态分布在循环神经网络中初始化权重。W1 将代表接受输入变量,w2 将代表生成的输出,如下所示 -

w1 = torch.FloatTensor(input_size, 
hidden_size).type(dtype)
init.normal(w1, 0.0, 0.4)
w1 = Variable(w1, requires_grad = True)
w2 = torch.FloatTensor(hidden_size, output_size).type(dtype)
init.normal(w2, 0.0, 0.3)
w2 = Variable(w2, requires_grad = True)

步骤4

现在,创建一个唯一定义神经网络的前馈函数非常重要。

def forward(input, context_state, w1, w2):
   xh = torch.cat((input, context_state), 1)
   context_state = torch.tanh(xh.mm(w1))
   out = context_state.mm(w2)
   return (out, context_state)

步骤5

下一步是开始循环神经网络正弦波实现的训练过程。外循环迭代每个循环,内循环迭代序列的元素。在这里,我们还将计算均方误差 (MSE),这有助于预测连续变量。

for i in range(epochs):
   total_loss = 0
   context_state = Variable(torch.zeros((1, hidden_size)).type(dtype), requires_grad = True)
   for j in range(x.size(0)):
      input = x[j:(j+1)]
      target = y[j:(j+1)]
      (pred, context_state) = forward(input, context_state, w1, w2)
      loss = (pred - target).pow(2).sum()/2
      total_loss += loss
      loss.backward()
      w1.data -= lr * w1.grad.data
      w2.data -= lr * w2.grad.data
      w1.grad.data.zero_()
      w2.grad.data.zero_()
      context_state = Variable(context_state.data)
   if i % 10 == 0:
      print("Epoch: {} loss {}".format(i, total_loss.data[0]))

context_state = Variable(torch.zeros((1, hidden_size)).type(dtype), requires_grad = False)
predictions = []

for i in range(x.size(0)):
   input = x[i:i+1]
   (pred, context_state) = forward(input, context_state, w1, w2)
   context_state = context_state
   predictions.append(pred.data.numpy().ravel()[0])

步骤6

现在,是时候按照需要的方式绘制正弦波了。

pl.scatter(data_time_steps[:-1], x.data.numpy(), s = 90, label = "Actual")
pl.scatter(data_time_steps[1:], predictions, label = "Predicted")
pl.legend()
pl.show()

输出

上述过程的输出如下 -

正弦波

PyTorch - 数据集

在本章中,我们将更多地关注torchvision.datasets及其各种类型。PyTorch 包括以下数据集加载器 -

  • MNIST
  • COCO(字幕和检测)

数据集包括下面给出的两种类型的函数中的大多数 -

  • Transform - 一个接受图像并返回标准内容的修改版本的函数。这些可以与变换组合在一起。

  • Target_transform - 一个获取目标并对其进行转换的函数。例如,接受标题字符串并返回世界索引的张量。

MNIST

以下是 MNIST 数据集的示例代码 -

dset.MNIST(root, train = TRUE, transform = NONE, 
target_transform = None, download = FALSE)

参数如下 -

  • root - 存在已处理数据的数据集的根目录。

  • train - True = 训练集,False = 测试集

  • download - True = 从互联网下载数据集并将其放入根目录中。

可可

这需要安装 COCO API。以下示例用于演示使用 PyTorch 的数据集的 COCO 实现 -

import torchvision.dataset as dset
import torchvision.transforms as transforms
cap = dset.CocoCaptions(root = ‘ dir where images are’, 
annFile = ’json annotation file’,
transform = transforms.ToTensor())
print(‘Number of samples: ‘, len(cap))
print(target)

实现的输出如下 -

Number of samples: 82783
Image Size: (3L, 427L, 640L)

PyTorch - 修道院简介

Convents 就是从头开始构建 CNN 模型。网络架构将包含以下步骤的组合 -

  • 转换2d
  • 最大池2d
  • 修正线性单元
  • 看法
  • 线性层

训练模型

训练模型的过程与图像分类问题相同。以下代码片段完成了在提供的数据集上训练模型的过程 -

def fit(epoch,model,data_loader,phase 
= 'training',volatile = False):
   if phase == 'training':
      model.train()
   if phase == 'training':
      model.train()
   if phase == 'validation':
      model.eval()
   volatile=True
   running_loss = 0.0
   running_correct = 0
   for batch_idx , (data,target) in enumerate(data_loader):
      if is_cuda:
         data,target = data.cuda(),target.cuda()
         data , target = Variable(data,volatile),Variable(target)
      if phase == 'training':
         optimizer.zero_grad()
         output = model(data)
         loss = F.nll_loss(output,target)
         running_loss + = 
         F.nll_loss(output,target,size_average = 
         False).data[0]
         preds = output.data.max(dim = 1,keepdim = True)[1]
         running_correct + = 
         preds.eq(target.data.view_as(preds)).cpu().sum()
         if phase == 'training':
            loss.backward()
            optimizer.step()
   loss = running_loss/len(data_loader.dataset)
   accuracy = 100. * running_correct/len(data_loader.dataset)
   print(f'{phase} loss is {loss:{5}.{2}} and {phase} accuracy is {running_correct}/{len(data_loader.dataset)}{accuracy:{return loss,accuracy}})

该方法包括用于训练和验证的不同逻辑。使用不同模式有两个主要原因 -

  • 在训练模式下,dropout 会删除一定百分比的值,这在验证或测试阶段不应发生。

  • 对于训练模式,我们计算梯度并更改模型的参数值,但在测试或验证阶段不需要反向传播。

PyTorch - 从头开始​​训练修道院

在本章中,我们将重点关注从头开始创建一座修道院。这推断使用 torch 创建相应的修道院或样本神经网络。

步骤1

使用相应的参数创建必要的类。参数包括具有随机值的权重。

class Neural_Network(nn.Module):
   def __init__(self, ):
      super(Neural_Network, self).__init__()
      self.inputSize = 2
      self.outputSize = 1
      self.hiddenSize = 3
      # weights
      self.W1 = torch.randn(self.inputSize, 
      self.hiddenSize) # 3 X 2 tensor
      self.W2 = torch.randn(self.hiddenSize, self.outputSize) # 3 X 1 tensor

第2步

使用 sigmoid 函数创建函数的前馈模式。

def forward(self, X):
   self.z = torch.matmul(X, self.W1) # 3 X 3 ".dot" 
   does not broadcast in PyTorch
   self.z2 = self.sigmoid(self.z) # activation function
   self.z3 = torch.matmul(self.z2, self.W2)
   o = self.sigmoid(self.z3) # final activation 
   function
   return o
   def sigmoid(self, s):
      return 1 / (1 + torch.exp(-s))
   def sigmoidPrime(self, s):
      # derivative of sigmoid
      return s * (1 - s)
   def backward(self, X, y, o):
      self.o_error = y - o # error in output
      self.o_delta = self.o_error * self.sigmoidPrime(o) # derivative of sig to error
      self.z2_error = torch.matmul(self.o_delta, torch.t(self.W2))
      self.z2_delta = self.z2_error * self.sigmoidPrime(self.z2)
      self.W1 + = torch.matmul(torch.t(X), self.z2_delta)
      self.W2 + = torch.matmul(torch.t(self.z2), self.o_delta)

步骤3

创建如下所述的训练和预测模型 -

def train(self, X, y):
   # forward + backward pass for training
   o = self.forward(X)
   self.backward(X, y, o)
def saveWeights(self, model):
   # Implement PyTorch internal storage functions
   torch.save(model, "NN")
   # you can reload model with all the weights and so forth with:
   # torch.load("NN")
def predict(self):
   print ("Predicted data based on trained weights: ")
   print ("Input (scaled): \n" + str(xPredicted))
   print ("Output: \n" + str(self.forward(xPredicted)))

PyTorch - 修道院中的特征提取

卷积神经网络包括一个主要特征:提取。以下步骤用于实现卷积神经网络的特征提取。

步骤1

导入各自的模型,使用“PyTorch”创建特征提取模型。

import torch
import torch.nn as nn
from torchvision import models

第2步

创建一个可以在需要时调用的特征提取器类。

class Feature_extractor(nn.module):
   def forward(self, input):
      self.feature = input.clone()
      return input
new_net = nn.Sequential().cuda() # the new network
target_layers = [conv_1, conv_2, conv_4] # layers you want to extract`
i = 1
for layer in list(cnn):
   if isinstance(layer,nn.Conv2d):
      name = "conv_"+str(i)
      art_net.add_module(name,layer)
      if name in target_layers:
         new_net.add_module("extractor_"+str(i),Feature_extractor())
      i+=1
   if isinstance(layer,nn.ReLU):
      name = "relu_"+str(i)
      new_net.add_module(name,layer)
   if isinstance(layer,nn.MaxPool2d):
      name = "pool_"+str(i)
      new_net.add_module(name,layer)
new_net.forward(your_image)
print (new_net.extractor_3.feature)

PyTorch - 修道院的可视化

在本章中,我们将重点讨论借助约定的数据可视化模型。要使用传统神经网络获得完美的可视化图像,需要执行以下步骤。

步骤1

导入对于传统神经网络的可视化很重要的必要模块。

import os
import numpy as np
import pandas as pd
from scipy.misc import imread
from sklearn.metrics import accuracy_score

import keras
from keras.models import Sequential, Model
from keras.layers import Dense, Dropout, Flatten, Activation, Input
from keras.layers import Conv2D, MaxPooling2D
import torch

第2步

要阻止训练和测试数据的潜在随机性,请调用相应的数据集,如下面的代码所示 -

seed = 128
rng = np.random.RandomState(seed)
data_dir = "../../datasets/MNIST"
train = pd.read_csv('../../datasets/MNIST/train.csv')
test = pd.read_csv('../../datasets/MNIST/Test_fCbTej3.csv')
img_name = rng.choice(train.filename)
filepath = os.path.join(data_dir, 'train', img_name)
img = imread(filepath, flatten=True)

步骤3

使用以下代码绘制必要的图像以获得以完美方式定义的训练和测试数据 -

pylab.imshow(img, cmap ='gray')
pylab.axis('off')
pylab.show()

输出显示如下 -

训练

PyTorch - 使用 Convent 进行序列处理

在本章中,我们提出了一种替代方法,该方法依赖于跨两个序列的单个二维卷积神经网络。我们网络的每一层都会根据迄今为止生成的输出序列重新编码源令牌。因此,类似注意力的属性在整个网络中普遍存在。

在这里,我们将专注于根据 dataset 中包含的值创建具有特定池化的顺序网络。这个过程在“图像识别模块”中也得到了最好的应用。

顺序网络

以下步骤用于使用 PyTorch 创建带有约定的序列处理模型 -

步骤1

使用约定导入执行序列处理所需的模块。

import keras 
from keras.datasets import mnist 
from keras.models import Sequential 
from keras.layers import Dense, Dropout, Flatten 
from keras.layers import Conv2D, MaxPooling2D 
import numpy as np

第2步

使用以下代码执行必要的操作,以相应的顺序创建模式 -

batch_size = 128 
num_classes = 10 
epochs = 12
# input image dimensions 
img_rows, img_cols = 28, 28
# the data, split between train and test sets 
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(60000,28,28,1) 
x_test = x_test.reshape(10000,28,28,1)
print('x_train shape:', x_train.shape) 
print(x_train.shape[0], 'train samples') 
print(x_test.shape[0], 'test samples')
y_train = keras.utils.to_categorical(y_train, num_classes) 
y_test = keras.utils.to_categorical(y_test, num_classes)

步骤3

编译模型并拟合上述传统神经网络模型中的模式,如下所示 -

model.compile(loss = 
keras.losses.categorical_crossentropy, 
optimizer = keras.optimizers.Adadelta(), metrics = 
['accuracy'])
model.fit(x_train, y_train, 
batch_size = batch_size, epochs = epochs, 
verbose = 1, validation_data = (x_test, y_test)) 
score = model.evaluate(x_test, y_test, verbose = 0) 
print('Test loss:', score[0]) 
print('Test accuracy:', score[1])

生成的输出如下 -

神经网络模型

PyTorch - 词嵌入

在本章中,我们将了解著名的词嵌入模型——word2vec。Word2vec 模型用于在一组相关模型的帮助下生成词嵌入。Word2vec模型是用纯C代码实现的,并且手动计算梯度。

以下步骤解释了 PyTorch 中 word2vec 模型的实现 -

步骤1

在词嵌入中实现库,如下所述 -

import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F

第2步

使用名为 word2vec 的类实现词嵌入的 Skip Gram 模型。它包括emb_size、emb_dimension、u_embedding、v_embedding类型的属性。

class SkipGramModel(nn.Module):
   def __init__(self, emb_size, emb_dimension):
      super(SkipGramModel, self).__init__()
      self.emb_size = emb_size
      self.emb_dimension = emb_dimension
      self.u_embeddings = nn.Embedding(emb_size, emb_dimension, sparse=True)
      self.v_embeddings = nn.Embedding(emb_size, emb_dimension, sparse = True)
      self.init_emb()
   def init_emb(self):
      initrange = 0.5 / self.emb_dimension
      self.u_embeddings.weight.data.uniform_(-initrange, initrange)
      self.v_embeddings.weight.data.uniform_(-0, 0)
   def forward(self, pos_u, pos_v, neg_v):
      emb_u = self.u_embeddings(pos_u)
      emb_v = self.v_embeddings(pos_v)
      score = torch.mul(emb_u, emb_v).squeeze()
      score = torch.sum(score, dim = 1)
      score = F.logsigmoid(score)
      neg_emb_v = self.v_embeddings(neg_v)
      neg_score = torch.bmm(neg_emb_v, emb_u.unsqueeze(2)).squeeze()
      neg_score = F.logsigmoid(-1 * neg_score)
      return -1 * (torch.sum(score)+torch.sum(neg_score))
   def save_embedding(self, id2word, file_name, use_cuda):
      if use_cuda:
         embedding = self.u_embeddings.weight.cpu().data.numpy()
      else:
         embedding = self.u_embeddings.weight.data.numpy()
      fout = open(file_name, 'w')
      fout.write('%d %d\n' % (len(id2word), self.emb_dimension))
      for wid, w in id2word.items():
         e = embedding[wid]
         e = ' '.join(map(lambda x: str(x), e))
         fout.write('%s %s\n' % (w, e))
def test():
   model = SkipGramModel(100, 100)
   id2word = dict()
   for i in range(100):
      id2word[i] = str(i)
   model.save_embedding(id2word)         

步骤3

实现main方法,使词嵌入模型以正确的方式显示。

if __name__  ==  '__main__':
   test()

PyTorch - 递归神经网络

深度神经网络具有独特的功能,可以实现机器学习理解自然语言过程的突破。据观察,这些模型大多数将语言视为单词或字符的平面序列,并使用一种称为循环神经网络或 RNN 的模型。

许多研究人员得出的结论是,通过短语的层次树可以最好地理解语言。这种类型包含在考虑特定结构的递归神经网络中。

PyTorch 有一个特定的功能,有助于使这些复杂的自然语言处理模型变得更加容易。它是一个功能齐全的各种深度学习框架,对计算机视觉有强大的支持。

递归神经网络的特点

  • 递归神经网络的创建方式包括将同一组权重应用于不同的图状结构。

  • 按拓扑顺序遍历节点。

  • 这类网络是通过自动微分的逆向模式来训练的。

  • 自然语言处理包括递归神经网络的特殊情况。

  • 该递归神经张量网络包括树中的各种组合功能节点。

递归神经网络的示例如下所示 -

递归神经张量网络