Pytorch 简明教程
PyTorch - Introduction
PyTorch 被定义为 Python 的开放源代码机器学习库。它用于自然语言处理等应用。它最初是由 Facebook 人工智能研究小组开发的,并且 Uber 公司基于此构建了用于概率编程的 Pyro 软件。
最初,PyTorch 是由 Hugh Perkins 开发的,它基于 Torch 框架充当 LusJIT 的 Python 封装器。PyTorch 有两个变体。
PyTorch 在 Python 中重新设计并实现了 Torch,同时共享后端代码相同的核心 C 库。PyTorch 开发人员调整了此后端代码以便高效运行 Python。他们也保留了基于 GPU 的硬件加速以及使基于 Lua 的 Torch 变得可扩展的功能。
Features
PyTorch 的主要功能如下 -
Easy Interface - PyTorch 提供 easy to use API;因此它被认为非常简单易用,并且在 Python 中运行。在此框架中执行代码相当容易。
Python usage - 此库被认为是 Pythonic,能与 Python 数据科学堆栈平滑地集成。因此,它可以利用 Python 环境提供的所有服务和功能。
Computational graphs - PyTorch 提供了提供动态计算图的出色平台。因此,用户可以在运行时更改它们。当开发人员不知道为创建神经网络模型需要多少内存时,这非常有用。
PyTorch 以其具有以下三个抽象级别而闻名:
-
张量——在 GPU 上运行的强制 n 维数组。
-
变量——计算图中的节点。存储数据和梯度。
-
模块——神经网络层,存储状态或可学习权重。
Advantages of PyTorch
以下是 PyTorch 的优势:
-
代码易于调试和理解。
-
它包含许多层,例如 Torch。
-
它包含许多损失函数。
-
它可被视为 NumPy 对 GPU 的扩展。
-
它允许构建结构依赖于计算本身的网络。
TensorFlow vs. PyTorch
我们将在下面了解 TensorFlow 和 PyTorch 之间的主要差异:
PyTorch |
TensorFlow |
PyTorch 与基于 lua 的 Torch 框架密切相关,后者在 Facebook 中被积极使用。 |
TensorFlow 由 Google Brain 开发,并在 Google 中积极使用。 |
与其他竞争技术相比,PyTorch 相对较新。 |
TensorFlow 并不新,许多研究人员和行业专业人士都将其视为必备工具。 |
PyTorch 以命令式和动态方式包含所有内容。 |
TensorFlow 将静态和动态图结合在一起。 |
PyTorch 中的计算图在运行时定义。 |
TensorFlow 不包含任何运行时选项。 |
PyTorch 包含针对移动设备和嵌入式框架的部署功能。 |
TensorFlow 更加适合嵌入式框架。 |
Mathematical Building Blocks of Neural Networks
数学在任何机器学习算法中都至关重要,并且包括各种数学核心概念,以便以特定方式设计正确的算法。
下面提到了数学主题对机器学习和数据科学的重要性:
现在,我们重点关注机器学习的主要数学概念,这些概念从自然语言处理的角度来看很重要:
Vectors
向量被认为是连续或离散的数字数组,而包含向量的空间称为向量空间。向量的空间维度可以是有限的也可以是无限的,但观察到机器学习和数据科学问题处理的是固定长度向量。
向量表示如下所示:
temp = torch.FloatTensor([23,24,24.5,26,27.2,23.0])
temp.size()
Output - torch.Size([6])
在机器学习中,我们处理多维数据。因此,向量变得非常关键,并被认为是任何预测问题陈述的输入特征。
Scalars
标量被认为具有仅包含一个值的零维。当涉及 PyTorch 时,它不包括具有零维度的特殊张量;因此,声明将如下进行:
x = torch.rand(10)
x.size()
Output - torch.Size([10])
Matrices
大多数结构化数据通常以表格或特定矩阵的形式表示。我们将使用称为 Boston House Prices 的数据集,该数据集在 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 - Neural Network Basics
神经网络的主要原则包括一系列基本元素,即人工神经元或感知器。它包含几个基本输入,例如 x1、x2……xn,如果和大于激活电位,则它将产生一个二进制输出。
示例神经元的示意图如下所示 −
生成的输出可以看作是具有激活电位或偏差的加权和。
Output=\sum_jw_jx_j+Bias
典型的神经网络架构如下所示 −
输入和输出之间的层被称为隐藏层,而层之间的连接密度和类型就是配置。例如,一个完全连接的配置具有层 L 的所有神经元连接到层 L+1 的神经元。为了获得更明显的局部化,我们可以仅连接一个局部邻域,例如九个神经元,到下一层。图 1-9 说明了两个具有密集连接的隐藏层。
神经网络的各种类型如下 −
Feedforward Neural Networks
前馈神经网络包括神经网络系列的基本单元。这种类型神经网络中数据的运动是从输入层到输出层,通过当前隐藏层进行的。一层输出作为输入层,对网络架构中的任何类型的循环进行了限制。
Recurrent Neural Networks
循环神经网络用于在一段时间内数据模式随之改变的情况。在 RNN 中,应用同一层接受输入参数并在指定神经网络中显示输出参数。
可以使用 torch.nn 包构建神经网络。
它是一个简单的前馈网络。它获取输入,将其逐层馈送到多个层,然后最终给出输出。
借助 PyTorch,我们可以为神经网络使用以下步骤进行典型的训练程序 −
-
定义一些可学习参数(或权重)的神经网络。
-
在输入数据集上进行迭代。
-
通过网络处理输入。
-
计算损失(输出与正确的相差多远)。
-
将梯度反向传播到网络的参数中。
-
更新网络的权重,通常使用提供如下一个简单更新项
rule: weight = weight -learning_rate * gradient
Universal Workflow of Machine Learning
PyTorch - Implementing First Neural Network
PyTorch 包含了创建和实现神经网络的特殊功能。在本章中,我们将创建一个具有一个隐藏层和一个输出单元的简单神经网络。
我们将使用以下步骤使用 PyTorch 实现第一个神经网络 −
Step 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
Step 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]])
Step 4
借助内置函数创建一个顺序模型。使用以下代码行创建一个顺序模型 −
# Create a model
model = nn.Sequential(nn.Linear(n_in, n_h),
nn.ReLU(),
nn.Linear(n_h, n_out),
nn.Sigmoid())
Step 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)
Step 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()
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 - Neural Networks to Functional Blocks
训练深度学习算法涉及以下步骤:
-
Building a data pipeline
-
Building a network architecture
-
使用损失函数评估架构
-
使用优化算法优化网络架构权重
针对特定深度学习算法的训练是将神经网络转换成功能模块的精确要求,如下所示 −
针对上述图表,任何深度学习算法都涉及获取输入数据,构建各自的架构,其中包括嵌入了大量层。
如果你观察上述图表,则精确度是使用损失函数来评估的,根据神经网络的权重来进行优化。
PyTorch - Terminologies
在本章中,我们将讨论 PyTorch 中一些最常用的术语。
PyTorch NumPy
PyTorch 张量与 NumPy 数组相同。张量是一个 n 维数组,对于 PyTorch,它提供了许多函数来操作这些张量。
通常,PyTorch 张量利用 GPU 加速其数值计算。这些在 PyTorch 中创建的张量可用于将双层神经网络拟合到随机数据。用户可以手动实现通过网络的前向和反向传递。
Variables and Autograd
使用自动微分时,网络的前向传递将定义一个 computational graph - 图中的节点将是张量,边将是生成输入张量的输出张量的函数。
PyTorch 张量可以创建为变量对象,其中变量表示计算图中的节点。
PyTorch - Loading Data
PyTorch 包含一个名为 torchvision 的包,用于加载和准备数据集。它包括两个基本函数:Dataset 和 DataLoader,它们有助于转换和加载数据集。
Dataset
Dataset 用于从给定数据集中读取和转换数据点。要实现的基本语法如下所示 −
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)
Example: Loading CSV File
我们使用 Python 包 Panda 加载 csv 文件。原始文件具有以下格式:(图像名称,68 个地标 - 每个地标具有 x、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 - Linear Regression
在本章中,我们将重点介绍使用 TensorFlow 实现线性回归的基本示例。逻辑回归或线性回归是一种监督式机器学习方法,用于对离散类别顺序进行分类。我们在本章的目标是构建一个模型,用户可以通过它预测预测变量和一个或多个自变量之间的关系。
这两个变量之间的关系被认为是线性的,即,如果 y 是因变量且 x 被认为是自变量,那么两个变量的线性回归关系将看起来像下面提到的方程式:
Y = Ax+b
接下来,我们将设计一个线性回归算法,它使我们能够理解下面给出的两个重要概念:
-
Cost Function
-
Gradient Descent Algorithms
线性回归的示意图如下:
Interpreting the result
Y=ax+b
-
@ {s0} 的值为斜率。
-
b 的值为 y − intercept 。
-
r 是 correlation coefficient 。
-
r2 是 correlation coefficient 。
线性回归方程的图形视图如下:
使用 PyTorch 实现线性回归,采用以下步骤:
Step 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
Step 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)
Step 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 - Convolutional Neural Network
深度学习是机器学习的一个分支,被视为过去几十年间研究人员采取的一个关键步骤。深度学习应用的示例包括图像识别和语音识别的应用。
以下给出了两种重要类型的深度神经网络 −
-
Convolutional Neural Networks
-
Recurrent Neural Networks.
在本章中,我们将重点关注第一种,即卷积神经网络 (CNN)。
Convolutional Neural Networks
卷积神经网络被设计为通过多层数组来处理数据。此类神经网络被用于诸如图像识别或面部识别的应用。
CNN 和任何其他普通神经网络之间的主要区别在于,CNN 将输入作为二维数组并直接对图像进行操作,而不是关注于其他神经网络重点关注的特征提取。
CNN 的主要方法包括针对识别问题的解决方案。谷歌和 Facebook 等顶尖公司已经对识别项目的研发项目进行了投资,以更快的速度完成活动。
每个卷积神经网络都包括三个基本想法 −
-
Local respective fields
-
Convolution
-
Pooling
让我们详细了解每个术语。
Local Respective Fields
CNN 利用存在于输入数据中的空间相关性。神经网络中的每个并发层都连接到一些输入神经元。这个特定区域被称为局部感受野。它只关注于隐含神经元。隐含神经元将处理所提及区域内的输入数据,而不会意识到特定边界外部的变化。
生成局部感受野的图表表示如下 −
Convolution
在以上图中,我们观察到每个连接都会通过与一个层到另一个层的运动相关的连接学习一个隐含神经元的权重。在此,单个神经元会不时地执行一次转变。此过程被称为“卷积”。
从输入层到隐含特征图的连接映射被定义为“共享权重”,而包含的偏差被称为“共享偏差”。
Implementation of PyTorch
使用 PyTorch 创建卷积神经网络要使用以下步骤。
Step 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)
Step 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 - Recurrent Neural Network
递归神经网络是一种面向深度学习的算法,采用顺序方法。在神经网络中,我们总是假设每个输入和输出都与所有其他层无关。这类神经网络被称为递归,因为它们以顺序方式执行数学计算,逐个完成任务。
下图说明了递归神经网络的完整方法和工作原理——
在上图中,c1、c2、c3 和 x1 被视为包含一些隐藏输入值的输入,即 h1、h2 和 h3,提供 o1 的相应输出。我们现在将重点放在实施 PyTorch 以借助递归神经网络创建正弦波。
在训练期间,我们将以一次一个数据点的方式对模型遵循训练方法。输入序列 x 由 20 个数据点组成,并且目标序列被认为与输入序列相同。
Step 1
导入必要的包以使用以下代码实现递归神经网络——
import torch
from torch.autograd import Variable
import numpy as np
import pylab as pl
import torch.nn.init as init
Step 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 是所需的目标序列。
Step 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)
Step 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)
Step 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])
PyTorch - Datasets
在本章中,我们将重点介绍 torchvision.datasets 及其各种类型。PyTorch 包含以下数据集加载器 −
-
MNIST
-
COCO (Captioning and Detection)
数据集包括下面给出的两种主要类型的函数 −
-
Transform − 一个获取图像并返回标准内容的修改版本的功能。这些可以与变换一起构成。
-
Target_transform − 一个获取目标并进行转换的功能。例如,获取标题字符串并返回世界索引的张量。
MNIST
以下是由 MNIST 数据集生成的示例代码 -
dset.MNIST(root, train = TRUE, transform = NONE,
target_transform = None, download = FALSE)
参数如下:
-
root - 数据集的根目录,已处理的数据位于此处。
-
train - True = 训练集,False = 测试集
-
download - True = 从互联网下载数据集并将它放在根目录中。
COCO
这需要安装 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 - Introduction to Convents
卷积网络主要关于从头开始构建 CNN 模型。网络架构将包含以下步骤的组合 -
-
Conv2d
-
MaxPool2d
-
Rectified Linear Unit
-
View
-
Linear Layer
Training the Model
训练模型的过程与图像分类问题相同。以下代码片段完成了在给定数据集上训练模型的过程 -
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}})
该方法包括用于训练和验证的不同逻辑。使用不同模式的主要原因有两个 -
-
在训练模式下,丢弃会删除一定百分比的值,而这在验证或测试阶段不应该发生。
-
对于训练模式,我们要计算梯度并更改模型参数的值,但在测试或验证阶段不需要反向传播。
PyTorch - Training a Convent from Scratch
在本章中,我们将重点从头创建一个模型。这推断出使用 torch 创建一个特定的模型或样本神经网络。
Step 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
Step 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)
Step 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 - Feature Extraction in Convents
卷积神经网络包括一个主要功能, extraction 。以下步骤用于实现卷积神经网络的特征提取。
Step 1
导入相应模型以使用“PyTorch”创建特征提取模型。
import torch
import torch.nn as nn
from torchvision import models
Step 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 - Visualization of Convents
在本章中,我们将在变量的帮助下,把重点放在数据可视化模型上。要通过常规神经网络获得可视化的理想图片,需要以下步骤。
Step 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
Step 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)
PyTorch - Sequence Processing with Convents
在本章中,我们提出了一种替代方法,该方法依赖于跨两个序列的单个 2D 卷积神经网络。我们网络的每一层都根据到目前为止生成的输出序列重新编码源标记。因此,类似注意力的特性在整个网络中都是普遍存在的。
在这里,我们将重点关注 creating the sequential network with specific pooling from the values included in dataset 。此过程也最适用于“图像识别模块”。
创建具有卷积的序列处理模型,按照以下步骤使用 PyTorch -
Step 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
Step 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)
Step 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 - Word Embedding
在本章中,我们将理解著名的词嵌入模型 - word2vec。Word2vec 模型用于在相关模型组的帮助下生成词嵌入。Word2vec 模型使用纯 C 代码实现,梯度是手动计算的。
PyTorch 中 word2vec 模型的实现如下所述 -
Step 1
按照以下说明实现词嵌入中的库 -
import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F
Step 2
使用称为 word2vec 的类实现单词嵌入的跳跃图模型。它包含 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)