1. PyTorch简介
1.1 什么是PyTorch
PyTorch 是一个基于 Python 的科学计算包,主要用途有两个:
- 作为Numpy的替代,可利用GPU性能进行计算;
- 作为深度学习开发平台,提供很高的灵活性和速度。
PyTorch是Torch7团队开发的。Torch是一个开源科学计算框架,可以追溯到2002年纽约大学的项目。Torch的核心在于在构建深度神经网络及其优化和训练,为图像,语音,视频处理以及大规模机器学习问题提供快速高效的计算方案。为了追求更高的速度,灵活性和可扩展性,Torch采用Lua作为它的开发语言,但lua语言的受众比较局限。为了满足当今业界里Python先行(Python First)的原则,PyTorch应运而生,由Facebook人工智能研究员(FAIR)于2017年在GitHub上开源。顾名思义,PyTorch使用python作为开发语言,近年来和tensorflow, keras, caffe等热门框架一起,成为深度学习开发的主流平台之一。
1.2 为什么选择PyTorch
PyTorch作为一个深度学习开发平台有许多独到的优点,经常和Google的Tensorflow一起作为比较。
(1)简洁性
PyTorch的设计追求最少的封装,尽量避免重复造轮子。PyTorch的设计遵循张量(tensor)→变量(variable)→神经网络模块(nn.Module) 三个由低到高的抽象层次,而且这三个抽象之间联系紧密,可以同时进行修改和操作。不像Tensorflow中定义了许多全新而复杂的变量,如tensor, layer, graph, operation, layer, variable等。对于新手来说,PyTorch更加直观,更容易深入API来理解底层代码。
(2)动态计算
这是PyTorch别于Tensorflow, caffe等框架最大的一点。神经网络在运行时定义创建,并且可以随时查看训练中的tensor值,快速学习网络。PyTorch通过变量的自动反向求导机制,可以零延迟地改变神经网络的学习行为。
P.S. 在今年推出的Tensorflow2.0中,已经将Eager Execurion变为默认执行模式,由编写静态计算图转向动态计算图。
(3)活跃的社区
Facebook, twitter, Nvidia等知名企业都在使用PyTorch。PyTorch拥有完整的技术文档,开发人员亲自维护的论坛 (https://discuss.pytorch.org/),供用户交流和学习。FAIR的开发支持使PyTorch可以获得及时的更新与维护,保证了PyTorch用户的用户体验。
(4)受众越来越广
近年来,各类深度学习问题都有利用PyTorch实现的解决方案在GitHub上开源。同时也有许多新发表的论文采用PyTorch作为论文实现的工具,PyTorch正在成为最流行的深度学习开源框架之一。
2. PyTorch的安装
2.1 配置Python
笔者采用Linux16.04系统,选择系统自带的python3.5作为开发语言。
2.2 通过命令行安装PyTorch
这里选择PyTorch1.0稳定版本,在官网有命令行下载教程。由于自己的笔记本上没有英伟达的GPU,只能选择cpu版本进行安装。
pip3 install https://download.pytorch.org/whl/cpu/torch-1.0.1.post2-cp35-cp35m-linux_x86_64.whl
pip3 install torchvision
不同操作系统的Pytorch安装方法见官网:https://pytorch.org/get-started/locally/
3. PyTorch基础概念
3.1 PyTorch的基本背景
PyTorch是一个建立在Torch基础上的包,它主要提供两个高级功能:
(1)类似numpy的抽象方法来表征的张量(tensor)运算,并且可以使用GPU加速。
(2)包含自动求导系统的深度神经网络
3.2 PyTorch的基本元素
(1)张量(Tensor)
张量是PyTorch中最基本的元素,相当于numpy.ndarray
. 两者的运算方式也如出一辙,在PyTorch中也可以相互转化。
(2)变量(Variable)
Tensor是PyTorch中对numpy.ndarray
的完美替代品,但搭建神经网络时,还需要variable来构建计算图。Variable是对tensor的封装,是一个存放会变化的值的地理位置,这个值就是tensor。每个variable有3个属性:
variable.data
: variable中tensor的值;
variable.grad
:variable中tensor的梯度;
variable.gradfn
:指向Function对象,用于反向传播的梯度计算之用。
(3)神经网络模块(nn.Module)
nn
是PyTorch中专门为神经网络设计的借口。nn.Module
是nn
中一个重要的类,的含各种网络层的定义以及前向传播(forward pass)的方法。在定义自己的神经网络时,需要继承nn.Module
类,并实现自己的forward
方法
4. 通用代码实现流程
以PyTorch为例,一个常规的深度学习代码开发流程如下:
4.1 安装并导入相关的深度学习库
import torch
from torch.autograd import variable
import torch.nn
4.2 数据获取和预处理
准备好需要使用的训练数据和测试数据,并进行相应的预处理,如归一化,零均值,图片剪切,翻转等等
import torch.data.Dataloader as Dataloader
import torchvision
torch.data.Dataloader
是PyTorch中读取数据的重要接口,将数据接口的输入按照batch size封装成Tensor,后续再包装成variable即可作为网络的输入,起到数据和模型输入间承上启下的作用。
torchvision
是独立于PyTorch的关于图像操作的库,包括常用数据集的下载,常用的神经网络模型(如AlexNet, VGG, ResNet等),基本的图形操作(随机切割,旋转等)。
4.3 定义神经网络
神经网络的定义需要继承torch.nn.Module
类,包括初始化__init__(self)
和自定义的前向传播层forward(self, x)
(1)__init__(self)
:放置有可学习参数的层,如卷积层,全连接层等
(2)forward(self, x)
:输入x,按照前向传播算法,使用卷积等操作来得到神经网络最终的输出。
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.hidden = torch.nn.Linear(1, 20) # 隐藏层
self.predict = torch.nn.Linear(20, 1) # 输出层
def forward(self, x):
x = F.relu(self.hidden(x)) # 隐藏层的激活函数
x = self.predict(x) # 线性输出层
return x
net = Net(n_feature=2, n_hidden=10, n_output=2)
4.4 定义损失函数(loss function)和优化器(optimizer)
损失函数用来衡量网络预测的输出和实际标签值之间的差距。通过反向传播的计算,通过优化器提供的方式来调整神经网络的参数。
loss_func = torch.nn.CrossEntropyLoss() #损失函数
optimizer = torch.optim.SGD(net.parameters(), lr=0.02) #优化器
4.5 训练网络
训练网络的目的是通过最小化误差的方法来调整网络的参数,使得网络可以对输入数据进行准确的预测。包括如下的步骤:
(1)获取训练数据和标签:
(2)前向传播
(3)计算损失函数
(4)清零优化器
(5)反向传播并更新参数
torch_dataset = Data.TensorDataset(X, Y) # (1) 获取训练数据
loader = Data.DataLoader(dataset=torch_dataset, \
batch_size=BATCH_SIZE, shuffle=True, num_workers=2,) # (1) 封装数据
for t in range(100):
out = net(x) # (2) 前向传播
loss = loss_func(out, y) # (3) 计算损失函数
optimizer.zero_grad() # (4) 清空优化器
loss.backward() # (5) 误差反向传播, 计算参数更新值
optimizer.step() # (5) 更新网络参数
4.5 测试网络
将测试数据输入网络的到相应的预测输出,和真实输出作比较,并评估预测效果。
prediction = net(x_test)