深度学习之30分钟快速入门PyTorch(附学习资源推荐)

Posted 我是管小亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度学习之30分钟快速入门PyTorch(附学习资源推荐)相关的知识,希望对你有一定的参考价值。

目录

1、Pytorch简介

1.0 如何使用本教程

别有心理压力,只要跟着我一步一步来,你会发现其实并没有想像中的那么困难。当然,如果你看完了这篇教程之后,发现自己明白了很多,却又几乎什么都记不得,那也是很正常的——我认为,这里只是让你明白基本的原理和怎么应用,以后你还需要多练习,多使用,才能熟练掌握pytorch的使用。

最重要的是——请给我30分钟,不会让你失望的 😃

1.1 PyTorch由来

当前深度学习的框架有很多,其中较为出名的是Google的TensorFlow、Facebook的PyTorch,还有就是百度的paddlepaddle,TensorFlow的地位在目前看来确实是举足轻重的,社区的庞大也是它非常火的原因,paddlepaddle作为国产的框架之光,我个人的期待还是很高的,有兴趣的可以看一下paddlepaddle的介绍——【PaddlePaddle】百度深度学习平台PaddlePaddle:等待你我一起划桨的AI大船

因为TensorFlow和paddlepaddle比较相似,所以很多人都会拿Facebook的PyTorch和Google的Tensorflow进行比较。但是我们今天的主角是PyTorch,说到PyTorch其实应该先说Torch

1.2 Torch简介

Torch英译中:火炬

  1. What is the relationship between PyTorch and Torch?

A Tensor library like Numpy, unlike Numpy it has strong GPU support. Lua is a wrapper for Torch (Yes! you need to have a good understanding of Lua), and for that you will need LuaRocks package manager.

Torch是一个与Numpy类似的张量(Tensor)操作库,与Numpy不同的是Torch对GPU支持的很好,Lua是Torch的上层包装。

  1. Roadmap for torch and pytorch

Torch is not going anywhere. PyTorch and Torch use the same C libraries that contain all the performance: TH, THC, THNN, THCUNN and they will continue to be shared.
We still and will have continued engineering on Torch itself, and we have no immediate plan to remove that.

PyTorch和Torch使用包含所有相同性能的C库:TH, THC, THNN, THCUNN,并且它们将继续共享这些库。

这样的回答就很明确了,其实PyTorch和Torch都使用的是相同的底层,只是使用了不同的上层包装语言。

1.3 重新认识PyTorch

  1. 维基百科PyTorch

PyTorch is an open source machine learning library for Python, based on Torch, used for applications such as natural language processing. It is primarily developed by Facebook’s artificial-intelligence research group, and Uber’s “Pyro” software for probabilistic programming is built on it.

PyTorch是一个基于Torch的Python开源机器学习库,用于自然语言处理等应用程序。 它主要由Facebook的人工智能研究小组开发。Uber的"Pyro"也是使用的这个库。

  1. GitHub PyTorch

PyTorch is a Python package that provides two high-level features:
Tensor computation (like NumPy) with strong GPU acceleration
Deep neural networks built on a tape-based autograd system
You can reuse your favorite Python packages such as NumPy, SciPy and Cython to extend PyTorch when needed.

PyTorch是一个Python包,提供两个高级功能:

  • 具有强大的GPU加速的张量计算(如NumPy)
  • 包含自动求导系统的的深度神经网络
  • 您可以重用您最喜欢的Python包,如NumPy、SciPy和Cython,以便在需要时扩展PyTorch。

1.4 PyTorch和Tensorflow的对比

没有好的框架,只有合适的框架。

一般开源项目的热度指标从 GitHub 可以略见一斑,PyTorch 的数据是这样的(截止19.8.23):

  • star(可以认为是技术人的点赞)有31004人;

  • forks(想要自己基于此做修改)有7586人;

  • commits(代码总共的更新次数)有20095次;

  • contributors(代码贡献者)有1139个。

  • star(可以认为是技术人的点赞)有132923人;

  • forks(想要自己基于此做修改)有76885人;

  • commits(代码总共的更新次数)有63438次;

  • contributors(代码贡献者)有2153个。

结果似乎不言而喻了,TensorFlow的热度确实要远远高与PyTorch,这篇知乎文章有个简单的对比。

但是技术是发展的,知乎上的对比是发布于 2017-08-20的,比如Tensorflow在1.5版的时候就引入了Eager Execution机制实现了动态图,PyTorch的可视化,windows支持,沿维翻转张量等问题都已经不是问题了。

1.5 总结

  • PyTorch算是相当简洁优雅且高效快速的框架
  • 设计追求最少的封装,尽量避免重复造轮子
  • 算是所有的框架中面向对象设计的最优雅的一个,设计最符合人们的思维,它让用户尽可能地专注于实现自己的想法
  • 大佬支持,与Google的Tensorflow类似,Facebook的支持足以确保PyTorch获得持续的开发更新
  • 不错的的文档,PyTorch作者亲自维护的论坛供用户交流和求教问题
  • 入门简单

2、Pytorch环境搭建

PyTorch的安装十分简单,根据PyTorch官网,对系统选择和安装方式等灵活选择即可。这里以anaconda为例,Windows10 下 Anaconda和 PyCharm 的详细的安装教程(图文并茂),简单的说一下步骤和要点。

国内安装anaconda建议使用中科大镜像,快的不是一点半点。目前中科大、清华镜像都已经关闭。直接通过prompt下载很慢,并且经常会出现HTTPERROR导致下载失败。所以可以提前下载好压缩包,然后离线下载,这样就不容易出现下载到一半下载失败令人苦恼的情况。

2.1 安装Pytorch

Anaconda安装完成后,开始创建环境,这里以win10 系统为例。打开Anaconda Prompt:

# pytorch为环境名,这里创建python3.6版。
conda create - n pytorch python = 3.6
# 切换到pytorch环境
activate pytorch
# ***以下为1.0版本安装***
# 安装GPU版本,根据cuda版本选择cuda80,cuda92,如果cuda是9.0版,则不需要
# 直接conda install pytorch -c pytorch即可
# win下查看cuda版本命令nvcc -V
conda install pytorch cuda92 - c pytorch
# cpu版本使用
conda install pytorch-cpu -c pytorch

# torchvision 是torch提供的计算机视觉工具包,后面介绍
pip install torchvision

# *** 官方更新了1.01 所以安装方式也有小的变更
# torchversion提供了conda的安装包,可以用conda直接安装了
# cuda支持也升级到了10.0
# 安装方式如下:
# cpu版本
conda install pytorch - cpu torchvision - cpu - c pytorch
# GPU版
conda install pytorch torchvision cudatoolkit = 10.0 - c pytorch
# cudatoolkit后跟着相应的cuda版本
# 目前测试 8.0、9.0、9.1、9.2、10.0都可安装成功

验证输入python 进入

import torch
torch.__version__
# 得到结果'1.1.0'

2.2 配置 Jupyter Notebook

新建的环境是没有安装ipykernel的,所以无法注册到Jupyter Notebook中,所以先要准备下环境:

# 安装ipykernel
conda install ipykernel
# 写入环境
python -m ipykernel install  --name pytorch --display-name "Pytorch for Deeplearning"

下一步就是定制 Jupyter Notebook:

# 切换回基础环境
activate base
# 创建jupyter notebook配置文件
jupyter notebook --generate-config
## 这里会显示创建jupyter_notebook_config.py的具体位置

打开文件,修改

c.NotebookApp.notebook_dir = '' 默认目录位置
c.NotebookApp.iopub_data_rate_limit = 100000000 这个改大一些否则有可能报错

2.3 测试

至此 Pytorch 的开发环境安装完成,可以在开始菜单中打开Jupyter Notebook,在New 菜单中创建文件时选择Pytorch for Deeplearning,创建PyTorch的相关开发环境了

3-7章为官方网站的 Deep Learning with PyTorch: A 60 Minute Blitz 的中文翻译,目前在网上看到所有中文翻译版本都已经过时了,所以才又从新翻译了一遍,确保与官方同步。
此外,3-7章所有图片均来自于PyTorch官网,版权归PyTorch所有。

3、张量

%matplotlib inline

PyTorch是什么?

基于Python的科学计算包,服务于以下两种场景:

  • 作为NumPy的替代品,可以使用GPU的强大计算能力
  • 提供最大的灵活性和高速的深度学习研究平台

开始

Tensors(张量)

^^^^^^^

  • Tensors与Numpy中的 ndarrays类似,但是在PyTorch中
  • Tensors 可以使用GPU进行计算.
from __future__ import print_function
import torch

创建一个 5x3 矩阵, 但是未初始化:

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

创建一个随机初始化的矩阵:

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

创建一个0填充的矩阵:

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

创建一个0填充的矩阵,数据类型为long:

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

创建tensor并使用现有数据初始化:

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

根据现有的张量创建张量。 这些方法将重用输入张量的属性,例如, dtype,除非设置新的值进行覆盖

x = x.new_ones(5, 3, dtype=torch.double)      # new_* 方法来创建对象
print(x)

x = torch.randn_like(x, dtype=torch.float)    # 覆盖 dtype!
print(x)                                      # 对象的size 是相同的,只是值和类型发生了变化

获取 size

译者注:使用size方法与Numpy的shape属性返回的相同,张量也支持shape属性,后面会详细介绍

print(x.size())
torch.Size([5, 3])


操作

^^^^^^^^^^

操作有多种语法。

我们将看一下加法运算。

加法1:

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

加法2:

print(torch.add(x, y))

提供输出tensor作为参数

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

替换

# adds x to y
y.add_(x)
print(y)


你可以使用与NumPy索引方式相同的操作来进行对张量的操作

print(x[:, 1])

torch.view: 可以改变张量的维度和大小

译者注:torch.view与Numpy的reshape类似

x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8)  #  size -1 从其他维度推断
print(x.size(), y.size(), z.size())

如果你有只有一个元素的张量,使用.item()来得到Python数据类型的数值

x = torch.randn(1)
print(x)
print(x.item())

Read later:

100+ Tensor operations, including transposing, indexing, slicing, mathematical operations, linear algebra, random numbers, etc., are described here <https://pytorch.org/docs/torch>_.

100+张量操作,包括转置、索引、切片,数学运算、线性代数、随机数等,描述为“here https://pytorch.org/docs/torch”。

NumPy 转换

Converting a Torch Tensor to a NumPy array and vice versa is a breeze.

The Torch Tensor and NumPy array will share their underlying memory locations, and changing one will change the other.

Converting a Torch Tensor to a NumPy Array ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

将Torch Tensor转换成NumPy array,反之亦然,这是轻而易举的。
Torch Tensor和NumPy array将共享它们的底层内存位置,更改其中一个将更改另一个。
将Torch Tensor转换为NumPy array。

a = torch.ones(5)
print(a)

b = a.numpy()
print(b)

See how the numpy array changed in value.

a.add_(1)
print(a)
print(b)

NumPy Array 转化成 Torch Tensor

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

使用from_numpy自动转化

import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)

所有的 Tensor 类型默认都是基于CPU, CharTensor 类型不支持到 NumPy 的转换.

CUDA 张量

使用.to 方法 可以将Tensor移动到任何设备中

# is_available 函数判断是否有cuda可以使用
# ``torch.device``将张量移动到指定的设备中
if torch.cuda.is_available():
    device = torch.device("cuda")          # a CUDA 设备对象
    y = torch.ones_like(x, device=device)  # 直接从GPU创建张量
    x = x.to(device)                       # 或者直接使用``.to("cuda")``将张量移动到cuda中
    z = x + y
    print(z)
    print(z.to("cpu", torch.double))       # ``.to`` 也会对变量的类型做更改
tensor([0.7632], device='cuda:0')
tensor([0.7632], dtype=torch.float64)

4、自动求导

%matplotlib inline

Autograd: 自动求导机制

PyTorch 中所有神经网络的核心是 autograd 包。我们先简单介绍一下这个包,然后训练第一个简单的神经网络。

autograd包为张量上的所有操作提供了自动求导。它是一个在运行时定义的框架,这意味着反向传播是根据你的代码来确定如何运行,并且每次迭代可以是不同的。

示例

张量(Tensor)

torch.Tensor是这个包的核心类。如果设置 .requires_gradTrue,那么将会追踪所有对于该张量的操作。 当完成计算后通过调用 .backward(),自动计算所有的梯度,这个张量的所有梯度将会自动积累到 .grad 属性。

要阻止张量跟踪历史记录,可以调用.detach()方法将其与计算历史记录分离,并禁止跟踪它将来的计算记录。

为了防止跟踪历史记录(和使用内存),可以将代码块包装在with torch.no_grad():中。在评估模型时特别有用,因为模型可能具有requires_grad = True的可训练参数,但是我们不需要梯度计算。

在自动梯度计算中还有另外一个重要的类Function.

Tensor and Function are interconnected and build up an acyclic graph, that encodes a complete history of computation. Each tensor has a .grad_fn attribute that references a Function that has created the Tensor (except for Tensors created by the user - their grad_fn is None).

TensorFunction互相连接并生成一个非循环图,它表示和存储了完整的计算历史。每个张量都有一个.grad_fn属性,这个属性引用了一个创建了TensorFunction(除非这个张量是用户手动创建的,即,这个张量的 grad_fnNone)。

如果需要计算导数,你可以在Tensor上调用.backward()。 如果Tensor是一个标量(即它包含一个元素数据)则不需要为backward()指定任何参数,但是如果它有更多的元素,你需要指定一个gradient 参数来匹配张量的形状。

译者注:在其他的文章中你可能会看到说将Tensor包裹到Variable中提供自动梯度计算,Variable 这个在0.4.1版中已经被标注为过期了,现在可以直接使用Tensor,官方文档在这里:

https://pytorch.org/docs/stable/autograd.html#variable-deprecated

具体的后面会有详细说明

import torch

创建一个张量并设置 requires_grad=True 用来追踪他的计算历史

x = torch.ones(2, 2, requires_grad=True)
print(x)

对张量进行操作:

y = x + 2
print(y)

结果y已经被计算出来了,所以,grad_fn已经被自动生成了。

print(y.grad_fn)

对y进行一个操作

z = y * y * 3
out = z.mean()

print(z, out)

.requires_grad_( ... ) 可以改变现有张量的 requires_grad 属性。 如果没有指定的话,默认输入的 flag 是 False。

a = torch.randn(2, 2)
a = ((a * 3) / (a - 1))
print(a.requires_grad)
print(a.grad_fn)

a.requires_grad_(True)

print(a.requires_grad)
b = (a * a).sum()
print(b.grad_fn)
False
None
True
<SumBackward0 object at 0x000002325360B438>

梯度

反向传播

因为 out是一个纯量(scalar),out.backward() 等于out.backward(torch.tensor(1))

out.backward()

print gradients d ( o u t ) / d x d(out)/dx d(out)/dx

print(x.grad)

得到矩阵 4.5.调用 out Tensor o o o”.

得到 o = 1 4 ∑ i z i o = \\frac14\\sum_i z_i o=41izi, z i = 3 ( x i + 2 ) 2 z_i = 3(x_i+2)^2 zi=3(xi+2)2 and z i ∣ x i = 1 = 27 z_i\\bigr\\rvert_x_i=1 = 27 zixi=1=27.

因此, ∂ o ∂ x i = 3 2 ( x i + 2 ) \\frac\\partial o\\partial x_i = \\frac32(x_i+2) xio=23(xi+2), 因此, ∂ o ∂ x i ∣ x i = 1 = 9 2 = 4.5 \\frac\\partial o\\partial x_i\\bigr\\rvert_x_i=1 = \\frac92 = 4.5 xioxi=1=29=4.5.

可以使用 autograd 做更多的操作

x = torch.randn(3, requires_grad=PyTorch深度学习60分钟快速入门 Part1:PyTorch是什么?

PyTorch深度学习60分钟快速入门 Part0:系列介绍

小白学习之pytorch框架-动手学深度学习(begin)

PyTorch深度学习60分钟快速入门 Part3:神经网络

参考《深度学习之PyTorch实战计算机视觉》PDF

PyTorch深度学习60分钟快速入门 Part2:Autograd自动化微分