What is Pytorch?
What is Pytorch?
起步(Getting Started)
内容参考自 Deep Learning with PyTorch: A 60 Munute Blitz 之 What is PyTorch (https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html)
张量(Tensor)
张量与 Numpy 的 ndarray 非常相似。
无初始化地创建一个矩阵,如下所示:
>>> import torch
>>> torch.empty(2, 3)
tensor([[1.4905e+03, 6.6702e-43, 3.1060e-15],
[4.2039e-45, 0.0000e+00, 0.0000e+00]])
创建一个随机初始化地矩阵,如下所示:
>>> torch.rand(2, 3)
tensor([[0.4724, 0.9018, 0.1788],
[0.9966, 0.6328, 0.8021]])
创建一个零矩阵,指定其数据类型为长整型(torth.long),torch.long 是 torch.int64 的别名(https://pytorch.org/docs/stable/tensor_attributes.html#torch.torch.dtype),如下所示:
>>> torch.zeros(2, 3, dtype=torch.long)
tensor([[0, 0, 0],
[0, 0, 0]])
直接从 list 中创建张量,如下所示:
>>> torch.tensor([0, 1.1, 1.2])
tensor([0.0000, 1.1000, 1.2000])
torch.double 是 torch.float64 的别名,torch.float 是 torch.float32 的别名(https://pytorch.org/docs/stable/tensor_attributes.html#torch.torch.dtype)。
还可以在现存的张量上创建,此时也可以指定数据的类型。new_ 表示在现存的张量上创建新的张量,此时需要重新指定新的shape。 _like 表示在现存的张量上创建新的张量,并且保持同样的 shape。如下所示:
>>> x = torch.zeros(2, 3)
>>> x = x.new_ones(1, 2, dtype=torch.double) # new_* methods take in sizes
>>> print(x)
tensor([[1., 1.]], dtype=torch.float64)
>>> x = torch.randn_like(x, dtype=torch.float) # override dtype!
>>> print(x) # result has the same size
tensor([[-1.8443, -3.2089]])
通过 size() 函数得到张量的尺寸,如下所示:
>> x = torch.zeros(2,3)
>> x.size()
torch.Size([2, 3])
操作符(operator)
每种操作符都有多种语法和语义,在接下来的例子中,以加法为例。
加法:语法1,如下所示:
>>> x = torch.ones(2, 3)
>>> y = torch.zeros(2, 3)
>>> print(x + y)
tensor([[1., 1., 1.],
[1., 1., 1.]])
加法:语法2,如下所示:
>>> x = torch.ones(2, 3)
>>> y = torch.zeros(2, 3)
>>> print(torch.add(x, y))
tensor([[1., 1., 1.],
[1., 1., 1.]])
加法:提供一个作为输出参数的张量,如下所示:
>>> x = torch.ones(2, 3)
>>> y = torch.zeros(2, 3)
>>> result = torch.empty(2, 3)
>>> torch.add(x, y, out=result)
>>> print(result)
tensor([[1., 1., 1.],
[1., 1., 1.]])
加法:在原地,如下所示:
>>> x = torch.ones(2, 3)
>>> y = torch.zeros(2, 3)
>>> y.add_(x) # adds x to y
>>> print(y)
tensor([[1., 1., 1.],
[1., 1., 1.]])
注意,任何使得张量在原地发生变化的操作都是以 “_” 为结尾。例如下面的两个函数将会改变张量 x:
x.copy_(y)
x.t_()
我们可以使用全部标准的类 Numpy 的索引方式。如下所示:
>>> x = torch.rand(2, 3)
>>> print(x)
tensor([[0.7521, 0.3104, 0.5551],
[0.7190, 0.4271, 0.1387]])
>>> print(x[:, 1])
tensor([0.3104, 0.4271])
指定张量的新尺寸(resize):如果想要指定张量的新尺寸(resize/reshap),可以使用 torch.view() 函数,如下所示:
>>> x = torch.rand(2, 3)
>>> y = x.view(6)
>>> z = x.view(-1, 2) # the size -1 is inferred from other dimensions
>>> print(x.size(), y.size(), z.size())
torch.Size([2, 3]) torch.Size([6]) torch.Size([3, 2])
如果张量中只有一个元素,可以用 .item 函数将数值提取出来,如下所示:
>>> x = torch.rand(1)
>>> print(x)
tensor([0.8990])
>>> print(x.item())
0.8989906907081604
Numpy 桥(Numpy Bridge)
Torch 张量与 Numpy 数组的互相转换非常简单。
Torch 张量与 Numpy 数组在底层共享内存空间(假设 Torch 张量是在 CPU 上),所以改变任意一个对象,另一个也会被改变(译注:类似于 C++ 引用的机制)。
将 Torch 张量转化为 Numpy 数组
Converting a Torch Tensor to a NumPy Array
如下所示:
>>> a = torch.rand(3)
>>> print(a)
tensor([0.2020, 0.4996, 0.2897])
>>> b = a.numpy()
>>> print(b)
[0.20200866 0.4995529 0.2897181 ]
改变 Torch 张量值的时候,Numpy 数组的值也会被改变。如下所示:
>>> a = torch.rand(3)
>>> print(a)
tensor([0.6871, 0.9258, 0.8865])
>>> a.add_(1)
>>> b = a.numpy()
>>> print(b)
[1.6871321 1.9258089 1.8865116]
将 Numpy 数组转换成 Torch 张量
Converting NumPy Array to Torch Tensor
改变 numpy 数组时,Torch 张量的值也会自动地随之改变,如下所示:
>>> a = np.ones(5)
>>> b = torch.from_numpy(a)
>>> np.add(a, 1, out=a)
>>> print(a)
[2. 2. 2. 2. 2.]
>>> print(b)
tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
除 CharTensor 以外,所有的 CPU 张量都支持与 Numpy 数组的互相转换。
CUDA 张量(CUDA Tensor)
可以通过 .to 函数将张量转移到任何设备上,如下所示:
>>> x = torch.ones(5)
>>> if torch.cuda.is_available():
>>> device = torch.device("cuda") # a CUDA device object
>>> y = torch.ones_like(x, device=device) # directly create a tensor on GPU
>>> x = x.to(device) # or just use strings ``.to("cuda")``
>>> z = x + y
>>> print(z)
tensor([2., 2., 2., 2., 2.], device='cuda:0')
>>> print(z.to("cpu", torch.double)) # ``.to`` can also change dtype together!
tensor([2., 2., 2., 2., 2.], dtype=torch.float64)