作者:Soumith Chintala

原文翻译自:https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html

中文翻译、注释制作:黄海广

github:https://github.com/fengdu78

代码全部测试通过。

配置环境:PyTorch 1.0,python 3.6,

主机:显卡:一块1080ti;内存:32g(注:绝大部分代码不需要GPU)

目录

一、PyTorch 是什么

他是一个基于Python的科学计算包,目标用户有两类

  • 为了使用GPU来替代numpy
  • 一个深度学习研究平台:提供最大的灵活性和速度

开始

张量(Tensors)

张量类似于numpy的ndarrays,不同之处在于张量可以使用GPU来加快计算。

  1. from __future__ import print_function
  2. import torch

构建一个未初始化的5*3的矩阵:

  1. x = torch.Tensor(5, 3)
  2. print(x)
  1. tensor([[ 0.0000e+00, 0.0000e+00, 1.3004e-42],
  2. [ 0.0000e+00, 7.0065e-45, 0.0000e+00],
  3. [-3.8593e+35, 7.8753e-43, 0.0000e+00],
  4. [ 0.0000e+00, 1.8368e-40, 0.0000e+00],
  5. [-3.8197e+35, 7.8753e-43, 0.0000e+00]])

构建一个零矩阵,使用long的类型

  1. x = torch.zeros(5, 3, dtype=torch.long)
  2. print(x)
  1. tensor([[0, 0, 0],
  2. [0, 0, 0],
  3. [0, 0, 0],
  4. [0, 0, 0],
  5. [0, 0, 0]])

从数据中直接构建一个张量(tensor):

  1. x = torch.tensor([5.5, 3])
  2. print(x)
  1. tensor([5.5000, 3.0000])

或者在已有的张量(tensor)中构建一个张量(tensor). 这些方法将重用输入张量(tensor)的属性,例如, dtype,除非用户提供新值

  1. x = x.new_ones(5, 3, dtype=torch.double) # new_* methods take in sizes
  2. print(x)
  3. x = torch.randn_like(x, dtype=torch.float) # 覆盖类型!
  4. print(x) # result 的size相同
  1. tensor([[1., 1., 1.],
  2. [1., 1., 1.],
  3. [1., 1., 1.],
  4. [1., 1., 1.],
  5. [1., 1., 1.]], dtype=torch.float64)
  6. tensor([[ 1.1701, -0.8342, -0.6769],
  7. [-1.3060, 0.3636, 0.6758],
  8. [ 1.9133, 0.3494, 1.1412],
  9. [ 0.9735, -0.9492, -0.3082],
  10. [ 0.9469, -0.6815, -1.3808]])

获取张量(tensor)的大小

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

注意

torch.Size实际上是一个元组,所以它支持元组的所有操作。

操作

张量上的操作有多重语法形式,下面我们以加法为例进行讲解。

语法1

  1. y = torch.rand(5, 3)
  2. print(x + y)
  1. tensor([[ 1.7199, -0.1819, -0.1543],
  2. [-0.5413, 1.1591, 1.4098],
  3. [ 2.0421, 0.5578, 2.0645],
  4. [ 1.7301, -0.3236, 0.4616],
  5. [ 1.2805, -0.4026, -0.6916]])

语法二

  1. print(torch.add(x, y))
  1. tensor([[ 1.7199, -0.1819, -0.1543],
  2. [-0.5413, 1.1591, 1.4098],
  3. [ 2.0421, 0.5578, 2.0645],
  4. [ 1.7301, -0.3236, 0.4616],
  5. [ 1.2805, -0.4026, -0.6916]])

语法三:

给出一个输出张量作为参数

  1. result = torch.empty(5, 3)
  2. torch.add(x, y, out=result)
  3. print(result)
  1. tensor([[ 1.7199, -0.1819, -0.1543],
  2. [-0.5413, 1.1591, 1.4098],
  3. [ 2.0421, 0.5578, 2.0645],
  4. [ 1.7301, -0.3236, 0.4616],
  5. [ 1.2805, -0.4026, -0.6916]])

语法四:

原地操作(in-place)

  1. # 把x加到y上
  2. y.add_(x)
  3. print(y)
  1. tensor([[ 1.7199, -0.1819, -0.1543],
  2. [-0.5413, 1.1591, 1.4098],
  3. [ 2.0421, 0.5578, 2.0645],
  4. [ 1.7301, -0.3236, 0.4616],
  5. [ 1.2805, -0.4026, -0.6916]])

注意

任何在原地(in-place)改变张量的操作都有一个_后缀。例如x.copy_(y), x.t_()操作将改变x.

你可以使用所有的numpy索引操作。

你可以使用各种类似标准NumPy的花哨的索引功能

  1. print(x[:, 1])
  1. tensor([-0.8342, 0.3636, 0.3494, -0.9492, -0.6815])

调整大小:如果要调整张量/重塑张量,可以使用torch.view

  1. x = torch.randn(4, 4)
  2. y = x.view(16)
  3. z = x.view(-1, 8) # -1的意思是没有指定维度
  4. print(x.size(), y.size(), z.size())
  1. torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])

如果你有一个单元素张量,使用.item()将值作为Python数字

  1. x = torch.randn(1)
  2. print(x)
  3. print(x.item())
  1. tensor([0.3441])
  2. 0.34412217140197754

稍后阅读

这里描述了一百多种张量操作,包括转置,索引,数学运算,线性代数,随机数等。

numpy桥

把一个torch张量转换为numpy数组或者反过来都是很简单的。

Torch张量和numpy数组将共享潜在的内存,改变其中一个也将改变另一个。

把Torch张量转换为numpy数组

  1. a = torch.ones(5)
  2. print(a)
  1. tensor([1., 1., 1., 1., 1.])
  1. b = a.numpy()
  2. print(b)
  3. print(type(b))
  1. [ 1. 1. 1. 1. 1.]
  2. <class 'numpy.ndarray'>

通过如下操作,我们看一下numpy数组的值如何在改变。

  1. a.add_(1)
  2. print(a)
  3. print(b)
  1. tensor([2., 2., 2., 2., 2.])
  2. [ 2. 2. 2. 2. 2.]

把numpy数组转换为torch张量

看看改变numpy数组如何自动改变torch张量。

  1. import numpy as np
  2. a = np.ones(5)
  3. b = torch.from_numpy(a)
  4. np.add(a, 1, out=a)
  5. print(a)
  6. print(b)
  1. [ 2. 2. 2. 2. 2.]
  2. tensor([2., 2., 2., 2., 2.], dtype=torch.float64)

所有在CPU上的张量,除了字符张量,都支持在numpy之间转换。

CUDA张量

可以使用.to方法将张量移动到任何设备上。

  1. # let us run this cell only if CUDA is available
  2. # We will use ``torch.device`` objects to move tensors in and out of GPU
  3. if torch.cuda.is_available():
  4. device = torch.device("cuda") # a CUDA device object
  5. y = torch.ones_like(x, device=device) # directly create a tensor on GPU
  6. x = x.to(device) # or just use strings ``.to("cuda")``
  7. z = x + y
  8. print(z)
  9. print(z.to("cpu", torch.double)) # ``.to`` can also change dtype together!
  1. tensor([1.3441], device='cuda:0')
  2. tensor([1.3441], dtype=torch.float64)

本章的官方代码: