原作者: Soumith Chintala
本教程的目标:1.深度理解PyTorch
张量库和神经网络;2.训练一个小的神经网络对图像进行分类。本教程默认读者对numpy
有基本的了解。在学习本教程,请确保你已经安装了torch
和torchvision
工具包,这个可以参考:https://github.com/pytorch/pytorch ,https://github.com/pytorch/vision。
Pytorch是一个基于python的科学计算程序包,针对两类用户:1.代替NumPy使用gpu的功能,2.深度学习研究平台,提供最大的灵活性和速度。下面让我们开始吧。
1 入门
1.1 张量(Tensors)
张量类似于NumPy的ndarrays(多维向量),另外张量还可以用于GPU加速计算。
import torch # 导入Pytorch
构建一个未初始化的5x3矩阵:
x = torch.empty(5, 3)
print(x)
Out:
tensor([[1.0194e-38, 9.6429e-39, 9.2755e-39],
[9.1837e-39, 9.3674e-39, 1.0745e-38],
[1.0653e-38, 9.5510e-39, 1.0561e-38],
[1.0194e-38, 1.1112e-38, 1.0561e-38],
[9.9184e-39, 1.0653e-38, 4.1327e-39]])
构建一个随机初始化的矩阵:
x = torch.rand(5, 3)
print(x)
Out:
tensor([[0.3987, 0.4777, 0.8551],
[0.1742, 0.2225, 0.1197],
[0.9467, 0.4619, 0.0553],
[0.7775, 0.6511, 0.7104],
[0.9011, 0.9555, 0.8334]])
(注:由于随机种子不同,每次运行程序后产生的随机结果不同,可以通过设定相同的随机种子保证每次得到的随机值相同)
构建一个数据类型(dtype)为long(torch.long)的全零矩阵:
x = torch.zeros(5, 3, dtype=torch.long)
print(x)
Out:
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
直接从数据中构建一个tensor:
x = torch.tensor([5.5,3])
print(x)
Out:
tensor([5.5000, 3.0000])
或者基于一个已经存在的tensor创建一个tensor。这类方法将会重用输入的tensor(已经存在的张量)。例如:数据类型(dtype),除非用户提供新的数据类型。
x = x.new_ones(5,3,dtype=torch.double) # new_* 方法使用当前张量的大小
print(x)
x = torch.randn_like(x, dtype=torch.float) # 重写数据类型
print(x) # 结果维度大小相同
Out:
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
tensor([[-1.2883, -2.2655, -0.3594],
[-0.1736, 0.9013, -1.5596],
[ 0.6928, -0.5005, 0.4360],
[ 0.7676, 0.8466, -0.4920],
[ 0.1550, 0.2033, -0.1045]])
(注:使用dtype=torch.*
指定tensor的数据类型)
获取tensor的维度:
print(x.size())
Out:
torch.Size([5, 3])
(注:torch.Size
实际上是tuple类型, 因此支持所有tuple的操作)
1.2 运算(Operations)
对于运算在Pytorch中有很多语法,在下面的例子中,我们那相加为例。
相加:语法1
y = torch.rand(5,3)
print(x + y)
Out:
tensor([[ 0.8894, 1.4587, -0.0206],
[ 2.0755, 2.2714, 1.5907],
[ 0.2857, 0.8927, 2.2268],
[ 2.0490, -0.4140, 2.5176],
[ 0.3738, -0.6546, 0.9200]])
相加:语法2
print(torch.add(x, y))
Out:
tensor([[ 0.7903, -0.3930, 0.3958],
[ 0.3016, 0.3043, 0.1237],
[-0.4394, -0.8068, -0.0399],
[ 2.4730, 0.6044, -0.3062],
[-0.8490, 0.2315, 1.1253]])
相加:提供了一个输出的tensor作为参数,会把相加的结果输出道这个参数上
result = torch.empty(5,3)
torch.add(x,y,out=result)
print(result)
Out:
tensor([[-1.1764, 0.5166, 0.8928],
[ 0.5941, -0.0534, -0.4999],
[-1.1142, 0.7863, 1.2288],
[ 0.8042, 0.6324, 0.4039],
[ 0.0635, 1.2785, 1.1780]])
相加:in-place
y.add_(x) # 将x的值加到y上
print(y)
Out:
tensor([[-0.6319, 2.4173, 0.0136],
[ 0.9607, 0.5124, -1.4165],
[-0.3057, 0.5004, 1.0406],
[ 1.3614, 1.8937, -0.8388],
[ 0.8840, 1.0522, -0.2256]])
(注:任何一个使用in-place改变一个tensor的操作都会固定使用一个_
。例如:x.copy_(y)
,x.t_()
都会改变x
)
你可以使用标准的类Numpy索引功能。
print(x[:, 1])
Out:
tensor([-1.3168, 1.2866, 0.3565, -0.1922, -0.8024])
改变大小:如果你想重新设置一个tensor的大小或者形状,你可以使用torch.view
x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8) # 维度为 -1 将通过其他维度自动计算出来
print(x.size(), y.size(), z.size())
Out:
torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])
如果一个张量只有一个元素,可以通过.item()
去获取Python类型的值。
x = torch.randn(1)
print(x)
print(x.item())
Out:
tensor([0.3939])
0.39389508962631226
(继续阅读:超过100个的Tensor运算,如:transposing, indexing, slicing, mathematical operations, linear algebra, random numbers等的具体介绍可以查看:https://pytorch.org/docs/stable/torch.html)
2 Numpy与Pytorch
将一个张量转换为Numpy矩阵很容易,反之也是如此。Torch中的Tensor和Numpy中的数组将共享一个内存地址(如果Torch的张量在CPU上),并且一个值的变化也会引起另一个值得变化。
2.1 将Tensor转化为Numpy Array
a = torch.ones(5)
print(a)
b = a.numpy()
print(b)
Out:
tensor([1., 1., 1., 1., 1.])
[1. 1. 1. 1. 1.]
查看numpy中得数组中值是如何改变得:
a.add_(1)
print(a)
print(b)
Out:
tensor([2., 2., 2., 2., 2.])
[2. 2. 2. 2. 2.]
2.2 将Numpy Array转化为Tensor
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)
Out:
[2. 2. 2. 2. 2.]
tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
除了CharTensor,所有得Tensors都支持与Numpy互转。
3 CUDA 与张量
张量可以使用.to
移动道任何一个设备。
# 如何CUDA可以使用得话,我们可以运行下面得内容看看
# 我们将使用 ``torch.device`` 对象将tensors 移入和移出GPU
if torch.cuda.is_available():
device = torch.device("cuda") # 一个CUDA设备对象
y = torch.ones_like(x, device=device) # 直接在GPU上创建对象
x = x.to(device) # 或者使用 ``.to("cuda")``
z = x + y
print(z)
print(z.to("cpu", torch.double)) # ``.to`` 可一起改变数据得类型
Out:
tensor([1.9125], device='cuda:0')
tensor([1.9125], dtype=torch.float64)
个人订阅号
更多编程,人工智能知识等着你