跳转至

什么是PyTorch?

什么是PyTorch?

它是一个基于Python的科学计算软件包,针对两组受众:

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

开始

张量(Tensor)

Tensor(张量)类似于NumPy的ndarrays(多维数组),不过Tensor可以使用GPU加速计算。

1
2
from __future__ import print_function
import torch

构造一个未初始化的5x3矩阵:

1
2
x = torch.empty(5, 3)
print(x)
1
2
3
4
5
tensor([[-2.6621e+09,  4.5587e-41, -2.6621e+09],
        [ 4.5587e-41,  3.3129e-18,  2.6302e+20],
        [ 6.1949e-04,  2.5640e-09,  1.6408e-07],
        [ 3.1472e+12,  2.7095e-09,  1.0374e-08],
        [ 6.4830e-10,  1.2398e+16,  1.8503e+20]])

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

1
2
x = torch.rand(5, 3)
print(x)
1
2
3
4
5
tensor([[0.8017, 0.1650, 0.3771],
        [0.8411, 0.4406, 0.3873],
        [0.3508, 0.8021, 0.5265],
        [0.0255, 0.8830, 0.0428],
        [0.1457, 0.5150, 0.1314]])

构造一个零填充,数据类型(dtype)为长整形(long)的矩阵:

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

直接从数据构造 tensor:

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

或者在已有 tensor 的基础上创建 tensor。 这种方法将重用输入 tensor 的属性,如 dtype, 除非提供新的值

1
2
3
4
5
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
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]], dtype=torch.float64)
tensor([[ 0.4672, -2.5856, -0.5848],
        [-0.0800, -0.0157, -0.1485],
        [-1.4250,  1.9369, -1.9591],
        [ 0.2027, -0.4884, -0.9408],
        [ 1.0423,  0.9927, -0.4951]])

获取其大小:

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

注意:

torch.Size 是 tuple(元组),它支持所有 tuple 操作。

运算

运算有多种语法。在下面的示例中,我们将看一看加法运算

加法: 语法 1

1
2
y = torch.rand(5, 3)
print(x + y)
1
2
3
4
5
tensor([[ 1.4545, -1.7998, -0.3246],
        [-0.0237,  0.9005,  0.3812],
        [-1.0698,  2.0101, -1.0791],
        [ 0.5078,  0.4077, -0.0533],
        [ 1.8212,  1.6021, -0.3893]])

加法: 语法 2

1
print(torch.add(x, y))
1
2
3
4
5
tensor([[ 1.4545, -1.7998, -0.3246],
        [-0.0237,  0.9005,  0.3812],
        [-1.0698,  2.0101, -1.0791],
        [ 0.5078,  0.4077, -0.0533],
        [ 1.8212,  1.6021, -0.3893]])

加法: 将输出 tensor 作为参数

1
2
3
result = torch.empty(5, 3)
torch.add(x, y, out=result)
print(result)
1
2
3
4
5
tensor([[ 1.4545, -1.7998, -0.3246],
        [-0.0237,  0.9005,  0.3812],
        [-1.0698,  2.0101, -1.0791],
        [ 0.5078,  0.4077, -0.0533],
        [ 1.8212,  1.6021, -0.3893]])

加法: 原位修改

1
2
3
# adds x to y
y.add_(x)
print(y)
1
2
3
4
5
tensor([[ 1.4545, -1.7998, -0.3246],
        [-0.0237,  0.9005,  0.3812],
        [-1.0698,  2.0101, -1.0791],
        [ 0.5078,  0.4077, -0.0533],
        [ 1.8212,  1.6021, -0.3893]])

注意:

任何原位修改 tensor 的运算方法都是以 _ 结尾的。 例如:x.copy_(y)x.t_() ,会改变 x

可以使用类似 NumPy 的索引运算!

1
print(x[:, 1])
1
tensor([-2.5856, -0.0157,  1.9369, -0.4884,  0.9927])

调整大小:如果要对 tensor 调整大小/改变形状,可以使用 torch.view:

1
2
3
4
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())
1
torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])

对于只有一个元素的 tensor,可以用 .item() 得到这个值对应的 Python 数值

1
2
3
x = torch.randn(1)
print(x)
print(x.item())
1
2
tensor([1.0215])
1.0214648246765137

延后阅读

100+ Tensor 运算,包括:移调、索引、切片、数学运算、线性代数、随机数等,可参考 https://pytorch.org/docs/torch

NumPy 互转

将 Torch Tensor 转换为 NumPy 数组(反之亦然)是一件轻而易举的事。

Torch Tensor 和 NumPy 数组共享其底层内存位置,更改一个会导致另一个的改变。

将 Torch Tensor 转换为 NumPy 数组

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

了解numpy数组的值如何变化。

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

将 NumPy 数组转换为 Torch Tensor

了解更改 NumPy 数组如何自动更改 Torch Tensor

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

除了 CharTensor ,所有 CPU 上的 Tensor 都可以和 Numpy 互相转换。

CUDA Tensor

可以使用 .to 方法移动Tensor对象到任何设备。

1
2
3
4
5
6
7
8
9
# 只有 CUDA 可用时,才运行这个 cell
# 使用 ``torch.device`` 对象将 tensor 移入以及移出 GPU
if torch.cuda.is_available():
    device = torch.device("cuda")          # CUDA 设备对象
    y = torch.ones_like(x, device=device)  # 直接在 GPU 上创建 tensor
    x = x.to(device)                       # 或者用 ``.to("cuda")``
    z = x + y
    print(z)
    print(z.to("cpu", torch.double))       # ``.to`` 也可以同时更改 ``dtype``!
1
2
tensor([2.0215], device='cuda:0')
tensor([2.0215], dtype=torch.float64)