pytorch 入门(1): pytorch是什么?

tech2022-08-16  137

这一系列文章是对pytorch 入门教程的翻译和学习总结。英文原版可以从以下网址获得:

https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html

 

目标:

理解Pytorch Tensor 库和神经网络训练一个小的神经网络来分类图片。

本手册假定你对numpy库有一个基本的了解。

 

注意:

确保你的测试环境已经安装了torch 和 torchvision 包

 

Pytorch是什么?

Pytoch是一个基于Python的科学计算的包,目标使用者有两类:

替换NumPy以达到使用GPU算力的目的一个深度学习的研究平台,能够提供最大的灵活性和速度

1 Tensors(张量)

Tensors 类似于 NumPy库中的ndarrays, 而且,Tensor还能够使用GPU做计算加速。

使用torch,首先import torch包,如下

 

$ python3

from __future__ import print_function

import torch

 

1.1 创建一个未初始化的 5x3 矩阵:

x = torch.empty(5, 3)

print(x)

输出:

tensor([[1.9160e-11, 0.0000e+00, 8.5305e+02], [1.0894e+27, 8.9683e-44, 0.0000e+00], [4.4842e-44, 0.0000e+00, 1.9160e-11], [0.0000e+00, 1.7857e+05, 3.9586e+12], [1.3452e-43, 0.0000e+00, 4.4842e-44]])

注意:

创建一个未初始化的矩阵后,矩阵中的值是不确定的, 使用分配内存时,内存中的值作为初始值。

 

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

x = torch.rand(5, 3)

print(x)

输出:

tensor([[1.9160e-11, 0.0000e+00, 8.5305e+02], [1.0894e+27, 8.9683e-44, 0.0000e+00], [4.4842e-44, 0.0000e+00, 1.9160e-11], [0.0000e+00, 1.7857e+05, 3.9586e+12], [1.3452e-43, 0.0000e+00, 4.4842e-44]])

创建的矩阵是经过初始化的,初始化为随机值。

 

1.3 创建一个矩阵,初始化为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]])

 

创建一个张量并赋值

x = torch.tensor([[2.2, 1.2], [2.1, 1.5], [4.5, 3.1]])

print(x)

输出:

tensor([[2.2000, 1.2000], [2.1000, 1.5000], [4.5000, 3.1000]])

 

1.4 基于已有的张量创建新张量

使用new_ones时,新的tensor会继承原来tensor的属性(例如tdype,device等),除非用户指定了新属性。

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!

rint(x)

输出:

tensor([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.], [1., 1., 1.], [1., 1., 1.]], dtype=torch.float64) tensor([[-0.4050, -0.8701, -0.3150], [ 0.0908, -0.3928, 0.0118], [ 1.0196, 0.0511, 1.0521], [ 0.3389, -0.1678, -0.3757], [-0.2501, 0.4394, 0.2627]])

 

获取张量的大小:

print(x.size())

输出:

torch.Size([5, 3])

torch.Size()是一个元组,支持所有的元组操作。

 

1.5 Operations 运算

torch中有很多运算语法,这里看一下加法运算

x = torch.tensor([1.2, 2.0])

y = torch.tensor([2.1, 3.0])

print(x + y)

print(torch.add(x,y))

 

输出:

>>> print(x + y) tensor([3.3000, 5.0000])

>>> print(torch.add(x,y)) tensor([3.3000, 5.0000])

 

result = torch.empty(1, 2)

torch.add(x, y, out=result)

print(result)

输出:

tensor([3.3000, 5.0000])

 

在变量上加:

y.add(x)

print(y)

y.add_(x)

print(y)

输出:

>>> y.add(x) tensor([3.3000, 5.0000])

>>> print(y) tensor([2.1000, 3.0000])

>>> y.add_(x) tensor([3.3000, 5.0000])

>>> print(y) tensor([3.3000, 5.0000])

注意: 加上“_”的操作会改变变量自己的值,不加"_"的操作,不改变变量的值。

例如x.copy_(y), x.t_(), 将会改变 x的值

 

1.6 改变tensor的大小, 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())

输出:

>>> x = torch.randn(4,4)

>>> print(x) tensor([[-1.8123, 0.4619, -1.0568, -0.3072], [-0.4922, -0.7467, -0.6142, 0.7062], [-0.3275, 0.3135, 0.1623, 0.2957], [ 0.3594, 0.6116, 0.7314, -0.2364]])

>>> y = x.view(16)

>>> print(y)

tensor([-1.8123, 0.4619, -1.0568, -0.3072, -0.4922, -0.7467, -0.6142, 0.7062, -0.3275, 0.3135, 0.1623, 0.2957, 0.3594, 0.6116, 0.7314, -0.2364])

>>> z = x.view(-1, 8)

>>> print(z)

tensor([[-1.8123, 0.4619, -1.0568, -0.3072, -0.4922, -0.7467, -0.6142, 0.7062], [-0.3275, 0.3135, 0.1623, 0.2957, 0.3594, 0.6116, 0.7314, -0.2364]])

>>> print(x.size(), y.size(), z.size())

torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])

 

1.7 获取tensor元素的值 .item()

x = torch.randn(1)

print(x)

print(x.item())

x = torch.randn(2,2)

print(x[1,1].item())

输出:

>>> x = torch.randn(1)

>>> print(x)

tensor([0.0017])

>>> print(x.item())

0.0016834917478263378

>>> x = torch.randn(2,2)

>>> print(x[1,1].item())

0.9299264550209045

2 NumPy Bridge

可以将一个Torch Tensor转为NumPy array, 也可以将一个NumPy array转为Torch Tensor, 非常方便。

转换之后,Torch Tensor 和 NumPy array底层存储仍然共用相同的内存地址(Tensor在CPU上的情况下), 所以,改变一个值,另一个也会相应改变。

 

2.1 Torch Tensor 转为NumPy Array

a = torch.ones(5)

print(a)

b = a.numpy()

print(b)

输出:

>>> a = torch.ones(5)

>>> print(a)

tensor([1., 1., 1., 1., 1.])

>>> b = a.numpy()

>>> print(b)

[1. 1. 1. 1. 1.]

 

a的值改变后,b的值也会变:

a.add_(1)

print(a)

print(b)

输出:

>>> a.add_(1)

tensor([2., 2., 2., 2., 2.])

>>> print(b)

[2. 2. 2. 2. 2.]

 

2.2 NumPy Array 转为 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)

 

输出:

>>> import numpy as np

>>> a = np.ones(5)

>>> b = torch.from_numpy(a)

>>> np.add(a,1,out=a)

array([2., 2., 2., 2., 2.])

>>> print(b)

tensor([2., 2., 2., 2., 2.], dtype=torch.float64)

 

除了CharTensor之外,CPU上的所有tensors都支持与numpy间的相互转换。

 

3 CUDA Tensors

Tensors 可以使用.to() 方法移动到任何device上。

# let us run this cell only if CUDA is available # We will use ``torch.device`` objects to move tensors in and out of GPU 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) print(z.to("cpu", torch.double)) # ``.to`` can also change dtype together!

 

输出:

>>> torch.cuda.is_available()

True

>>> device = torch.device("cuda")

>>> y = torch.ones_like(x, device=device)

>>> print(x)

tensor([[ 0.2147, -1.1994], [-0.6267, 0.9299]])

>>> print(y)

tensor([[1., 1.], [1., 1.]], device='cuda:0')

>>> x = x.to(device)

>>> print(x)

tensor([[ 0.2147, -1.1994], [-0.6267, 0.9299]], device='cuda:0')

>>> z = x+y

>>> print(z) tensor([[ 1.2147, -0.1994], [ 0.3733, 1.9299]], device='cuda:0')

>>> print(z.to("cpu", torch.double))

tensor([[ 1.2147, -0.1994], [ 0.3733, 1.9299]], dtype=torch.float64)

完整的用法,见:

https://pytorch.org/docs/stable/torch.html

 

最新回复(0)