首页 > 技术知识 > 正文

【深度学习】基于Torch的Python开源机器学习库PyTorch概述

文章目录 1 PyTorch简介 2 环境搭建 3 Hello world! 3.1 Tensors (张量) 3.2 操作 4 GPU Tensor 5 前向传播与反向传播 1 PyTorch简介

要介绍PyTorch之前,不得不说一下Torch。Torch是一个有大量机器学习算法支持的科学计算框架,是一个与Numpy类似的张量(Tensor) 操作库,其特点是特别灵活,但因其采用了小众的编程语言是Lua,所以流行度不高,这也就有了PyTorch的出现。所以其实Torch是 PyTorch的前身,它们的底层语言相同,只是使用了不同的上层包装语言。

【深度学习】基于Torch的Python开源机器学习库PyTorch概述1 PyTorch是一个基于Torch的Python开源机器学习库,用于自然语言处理等应用程序。它主要由Facebookd的人工智能小组开发,不仅能够 实现强大的GPU加速,同时还支持动态神经网络,这一点是现在很多主流框架如TensorFlow都不支持的。 PyTorch提供了两个高级功能:

具有强大的GPU加速的张量计算(如Numpy)

包含自动求导系统的深度神经网络

除了Facebook之外,Twitter、GMU和Salesforce等机构都采用了PyTorch。

TensorFlow和Caffe都是命令式的编程语言,而且是静态的,首先必须构建一个神经网络,然后一次又一次使用相同的结构,如果想要改 变网络的结构,就必须从头开始。但是对于PyTorch,通过反向求导技术,可以让你零延迟地任意改变神经网络的行为,而且其实现速度 快。正是这一灵活性是PyTorch对比TensorFlow的最大优势。

另外,PyTorch的代码对比TensorFlow而言,更加简洁直观,底层代码也更容易看懂,这对于使用它的人来说理解底层肯定是一件令人激 动的事。

所以,总结一下PyTorch的优点:

支持GPU 灵活,支持动态神经网络 底层代码易于理解 命令式体验 自定义扩展

当然,现今任何一个深度学习框架都有其缺点,PyTorch也不例外,对比TensorFlow,其全面性处于劣势,目前PyTorch还不支持快速傅里 叶、沿维翻转张量和检查无穷与非数值张量;针对移动端、嵌入式部署以及高性能服务器端的部署其性能表现有待提升;其次因为这个框 架较新,使得他的社区没有那么强大,在文档方面其C库大多数没有文档。

2 环境搭建

我在学习中一般使用colab,建议大家和我一样。如下图

【深度学习】基于Torch的Python开源机器学习库PyTorch概述2

这里我就不多说了,很简单。

网上有其他教程。

【深度学习】基于Torch的Python开源机器学习库PyTorch概述3 3 Hello world!

PyTorch 是一个基于 Python 的科学计算包,主要定位两类人群:

NumPy 的替代品,可以利用 GPU 的性能进行计算。

深度学习研究平台拥有足够的灵活性和速度

3.1 Tensors (张量)

Tensors 类似于 NumPy 的 ndarrays ,同时 Tensors 可以使用 GPU 进行计算。

from __future__ import print_function import torch

构造一个5×3矩阵,不初始化。

x = torch.empty(5, 3) print(x)

构造一个随机初始化的矩阵:

x = torch.rand(5, 3) print(x)

构造一个矩阵全为 0,而且数据类型是 long.

Construct a matrix filled zeros and of dtype long:

x = torch.zeros(5, 3, dtype=torch.long) print(x)

【深度学习】基于Torch的Python开源机器学习库PyTorch概述4 构造一个张量,直接使用数据:

x = torch.tensor([5.5, 3]) print(x)

创建一个 tensor 基于已经存在的 tensor。

x = x.new_ones(5, 3, dtype=torch.double) # new_* methods take in sizes print(x) x = torch.randn_like(x, dtype=torch.float) # override dtype! print(x) # result has the same size

输出:

tensor([[ 1., 1., 1.],

[ 1., 1., 1.],

[ 1., 1., 1.],

[ 1., 1., 1.],

[ 1., 1., 1.]], dtype=torch.float64)

tensor([[-0.2183, 0.4477, -0.4053],

[ 1.7353, -0.0048, 1.2177],

[-1.1111, 1.0878, 0.9722],

[-0.7771, -0.2174, 0.0412],

[-2.1750, 1.3609, -0.3322]])

获取它的维度信息: print(x.size())

输出:

torch.Size([5, 3])

注意

torch.Size 是一个元组,所以它支持左右的元组操作。

3.2 操作

在接下来的例子中,我们将会看到加法操作。

加法: 方式 1 y = torch.rand(5, 3) print(x + y)

Out:

tensor([[-0.1859, 1.3970, 0.5236],

[ 2.3854, 0.0707, 2.1970],

[-0.3587, 1.2359, 1.8951],

[-0.1189, -0.1376, 0.4647],

[-1.8968, 2.0164, 0.1092]])

加法: 方式2 print(torch.add(x, y))

Out:

tensor([[-0.1859, 1.3970, 0.5236],

[ 2.3854, 0.0707, 2.1970],

[-0.3587, 1.2359, 1.8951],

[-0.1189, -0.1376, 0.4647],

[-1.8968, 2.0164, 0.1092]])

加法: 提供一个输出 tensor 作为参数

result = torch.empty(5, 3) torch.add(x, y, out=result) print(result)

加法: in-place

# adds x to y y.add_(x) print(y) 4 GPU Tensor

新建的Tensor对象默认存在于CPU内存中,在使用GPU进行计算的时候,只需要把Tensor拷贝到GPU memory中即可。第一种方法是使用cuda()函数:

x = x.cuda()

在使用cuda()的时候,如果机器没有检测到可用的GPU,会报错。自从PyTorch 0.4以来,一个新的函数to()被引入,所以现在的标准代码都会这样写:

device = torch.device(“cuda” if torch.cuda.is_available() else “cpu”)

x = x.to(device)这两行代码的意思是,如果检测到可用的GPU,就把x拷贝到GPU上,否则,x依旧保留在CPU内存中。这样避免了运行错误,在任何情况下程序都可以顺利执行。

5 前向传播与反向传播

在Tensorflow中,一组操作符构建了一个计算图,这个计算图固定的存储在了内存中。当你给placeholder放入具体数据的时候,计算图执行运算,更新参数。

这个过程相当于:你想吃面条,那么第一步你做了一个面条机,这个面条机一直在那里,不管你有没有面;当你有面了,把面扔进去,调节面条机的刀片(参数),做出你需要的面条来。

这个优点是建造面条机和做面条分开,你可以集中精力去设计一个很棒的面条机;缺点是当你做好了面条机,发现你的某个要求它达不到,你需要重做一个(重写一个网络)。

在PyTorch中,由于“所见即所得”,所以每一步运算都是在计算图上添砖加瓦。所谓的“动态”也就在这里,你可以随时增加一行代码,计算图就成了一个新的样子。

这个可以类比成造房子(主页菌想象力匮乏,大家凑合看……)你先建了一个平房,住了一段时间觉得不够用了,你不需要推翻重建,而是可以在上面直接加一层。第一层的房顶就是你盖第二层时候的“基础”(前端计算图的输出直接作为新的操作符的输入)。

所以在PyTorch中运行一个模型的时候,过程是这样的:

你:我想前向传播,这是数据

计算机:好的,构建计算图,计算结果,存储中间数据用于计算梯度

你:我想执行反向传播

计算机:好的,梯度计算完成,释放不再需要的中间数据和计算图,存储更新参数。

你:执行第二次前向传播

计算机:好的,重新构建计算图,计算结果,存储中间数据……

…… ……

你:训练好了,我想测试,开启测试模式,这是测试数据

计算机:构建计算图,前向传播计算输出,不存储中间结果,因为不需要计算梯度

存储中间数据计算梯度这个概念很重要哦。

猜你喜欢