本系列是PyTorch官网Tutorial Deep Learning with PyTorch: A 60 Minute Blitz 的翻译和总结。
1. PyTorch概览
2. Autograd – 自动微分
3. 神经网络
4. 训练一个分类器
下载本文的Jupyter NoteBook文件:60min_01_PyTorch Overview.ipynb

Tensor 张量

Tensor类似于Numpy的ndarray,但不同的是,Tensor可以在GPU上被加速。

from __future__ import print_function
import torch

生成一个未初始化的 5×3 矩阵:

x = torch.empty(5,3)
print(x)
tensor([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]])

生成一个随机矩阵:

x = torch.rand(5,3)
print(x)
tensor([[0.4907, 0.1470, 0.9752],
        [0.9518, 0.6973, 0.4775],
        [0.5643, 0.6586, 0.3142],
        [0.2364, 0.8435, 0.6187],
        [0.3253, 0.5903, 0.9939]])

生成一个0矩阵,数据类型为long

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

直接从数据创造tensor

x = torch.tensor([6.7,6,7])
print(x)
tensor([6.7000, 6.0000, 7.0000])

在已有tensor的基础上创建tensor。这些方法将会继承原tensor的属性,比如数据类型,除非新的值由用户给出。

print('x:\n',x)
y = x.new_ones(5, 3, dtype=torch.double)
print('y:\n',y)

x = torch.randn_like(x, dtype=torch.float)    # dtype被改写,但是结果继承了size。
print(x)                                      
x:
 tensor([6.7000, 6.0000, 7.0000])
y:
 tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]], dtype=torch.float64)
tensor([-0.3186,  0.5506,  0.4940])

获得tensor的size

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

Operations 操作

相加

PyTorch中有许多种相加语法:

相加:语法1

x = torch.rand(5, 3)
y = torch.rand(5, 3)
print(x + y)
tensor([[0.9943, 0.3976, 0.6645],
        [0.6796, 1.1703, 1.2389],
        [1.5879, 1.1208, 1.5912],
        [1.2165, 0.8195, 1.0364],
        [1.2178, 1.3195, 1.1736]])

相加:语法2

print(torch.add(x,y))
tensor([[0.9943, 0.3976, 0.6645],
        [0.6796, 1.1703, 1.2389],
        [1.5879, 1.1208, 1.5912],
        [1.2165, 0.8195, 1.0364],
        [1.2178, 1.3195, 1.1736]])

相加:将一个tensor作为out参数,用以输出。

result = torch.empty(5,3)
torch.add(x,y,out=result)
print(result)
tensor([[0.9943, 0.3976, 0.6645],
        [0.6796, 1.1703, 1.2389],
        [1.5879, 1.1208, 1.5912],
        [1.2165, 0.8195, 1.0364],
        [1.2178, 1.3195, 1.1736]])

相加:替代

y.add_(x)
print(y)
tensor([[0.9943, 0.3976, 0.6645],
        [0.6796, 1.1703, 1.2389],
        [1.5879, 1.1208, 1.5912],
        [1.2165, 0.8195, 1.0364],
        [1.2178, 1.3195, 1.1736]])

Note:

任何让tensor被覆盖的方法的名称都以_结尾。例如x.copy_(y), x.t_()等。

索引

NumPy中的索引方法可以使用:

print(x[:, 1])
tensor([0.0200, 0.4981, 0.2466, 0.7497, 0.8315])

Resizing

想要改变tensor的规模,可以使用torch.view

x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8)  # the size -1 is inferred from other dimensions
print(x.size(), y.size(), z.size())
torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])

取值

如果你有一个单元素的tensor,.item()方法可以取值。

x = torch.randn(1)
print(x)
print(x.item())
tensor([-0.7093])
-0.709314227104187

与NumPy的沟通桥梁

将Torch张量转换为NumPy数组很容易,反之亦然。
Torch张量将会和NumPy数组共享同一个内存位置(Torch张量在CPU上的情况下),其中一个发生改变,另一个也会随之改变。

将Torch Tensor转换为NumPy数组

a = torch.ones(5)
print(a)
b = a.numpy()
print(b)
a.add_(1)
print(a)
print(b)
tensor([1., 1., 1., 1., 1.])
[1. 1. 1. 1. 1.]
tensor([2., 2., 2., 2., 2.])
[2. 2. 2. 2. 2.]

将NumPy数组转换为Torch Tensor

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

除了CharTensor,其他在CPU上的Torch张量均支持与NumPy数组的相互转换。

CUDA Tensors

使用.to()方法,可以将张量转移到其他设备。

if torch.cuda.is_available():
    device = torch.device("cuda")          # 创建CUDA设备对象
    y = torch.ones_like(x, device=device)  # 直接在GPU上
    x = x.to(device)
    # x = x.to("cuda") 也可以这么写
    z = x + y
    print(z)
    print(z.to("cpu", torch.double))       # ``.to`` 方法可以同时转换数据类型
tensor([0.2907], device='cuda:0')
tensor([0.2907], dtype=torch.float64)