在开始深入学习深度学习之前,了解Python编程语言和高中数学是有帮助的。本文不需要具备深度学习的先验知识。将介绍PyTorch库的基础知识和工作原理,以便能够开始使用深度学习。请跟随本教程,获得实践经验。
PyTorch基于Python和torch库构建,支持在图形处理单元上计算张量。目前,它是深度学习和人工智能研究社区最受欢迎的库。
将使用Jupyter Notebooks来运行代码。建议在Google Colaboratory上跟随本教程。这是一个Jupyter笔记本环境,不需要设置即可使用,并且完全在云端运行。还可以免费使用GPU。可以查看以获得使用Colab的一些指导。
PyTorch是一个处理张量的库。张量是数据的基本单位。它可以是一个数字、向量、矩阵或任何n维数组。它类似于Numpy数组。
在开始之前,应该按照以下方式导入torch模块:
import torch
创建一个包含单个数字数据的张量t1:
# 单数字张量
t1 = torch.tensor(5.)
print(t1)
输出:
tensor(5.)
5.是5.0的简写。它用于指示PyTorch该张量是一个浮点数。可以使用tensor.dtype来验证上述内容。如果使用的是jupyter笔记本,那么可以直接在单元格中输入变量并运行它以查看结果。
print(t1.dtype)
输出:torch.float32
同样,可以创建向量类型的张量:
# 1D向量张量
t2 = torch.tensor([1, 2, 3., 4])
print(t2)
输出:tensor([1., 2., 3., 4.])
从上述输出中可以看到,即使向量中的一个元素是浮点数,张量也会将所有元素的数据类型转换为float。
现在创建一个2D张量:
# 矩阵
t3 = torch.tensor([[1., 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(t3)
输出:
tensor([[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.]])
一个3D张量:
t4 = torch.tensor([
[[10. , 11, 12],
[13, 14, 15]],
[[16, 17, 18],
[19, 20, 21]]
])
print(t4)
输出:
tensor([[[10., 11., 12.],
[13., 14., 15.]],
[[16., 17., 18.],
[19., 20., 21.]]])
如果观察这些张量,它们与NumPy数组相似。因此,可以使用tensor.shape来检查张量的形状。数组的维度将是返回形状的长度。因此,定义的张量的形状将是:
print(t1.shape)
输出:
torch.Size([])
由于t1只是一个数字,其维度是0。
print(t2.shape)
输出:torch.Size([4])
由于t2是一个向量,其维度是1。
print(t3.shape)
输出:torch.Size([3, 3])
由于t3是一个3x3大小的矩阵,其维度是2。
print(t4.shape)
输出:torch.Size([2, 2, 3])
由于t4堆叠了两个2x3的张量,其维度是3。
可以使用通常的算术运算对张量进行操作。此外,张量具有计算给定表达式相对于所有独立变量的梯度或导数的特殊能力。让看一个例子,定义一些张量,然后初始化一些值:
x = torch.tensor(3.)
w = torch.tensor(4., requires_grad=True)
z = torch.tensor(5., requires_grad=True)
x, w, z
输出:
(tensor(3.), tensor(4., requires_grad=True), tensor(5., requires_grad=True))
在上述代码片段中,创建了3个张量x、w和z,带有数字,对于w和z,额外的参数requires_grad设置为True。
现在让用这些张量执行算术运算:
y = x*w + z
print(y)
输出:
tensor(17., grad_fn=<AddBackward0>)
根据基本的乘法和加法,得到了预期的输出,即y = 3 * 4 + 5 = 17。
现在让讨论Pytorch的一个独特能力,它可以自动计算任何表达式(以y为例)相对于将参数requires_grad设置为True的独立变量的导数。这可以通过在y上调用.backward方法来完成:
# 计算导数
y.backward()
可以在相应输入张量的.grad属性中找到y相对于输入张量的导数。
print("dy/dx =", x.grad)
print("dy/dw =", w.grad)
print("dy/dz =", z.grad)
输出:
dy/dx = None
dy/dw = tensor(3.)
dy/dz = tensor(1.)
可以观察到以下情况:
y相对于x的导数值为None,因为参数requires_grad设置为False。
y相对于w的导数值为3,因为dy/dw = x = 3。
y相对于z的导数值为1,因为dy/dz = 1。
NumPy是一个流行的开源库,用于Python中的科学和数学计算。它还支持对大型多维数组的操作和基于线性代数、傅里叶变换和矩阵的计算。NumPy有一个庞大的支持库生态系统,包括Pandas、Matplotlib和OpenCv。
因此,PyTorch与NumPy互操作,利用NumPy的工具和库,然后进一步扩展能力。首先,创建一个NumPy数组。
import numpy as np
x = np.array([1, 2., 3])
print(x)
输出:array([1., 2., 3.])
可以将Numpy数组转换为Torch张量,使用torch.from_numpy():
# 从numpy数组创建张量
y = torch.from_numpy(x)
print(y)
输出:tensor([1., 2., 3.], dtype=torch.float64)
可以使用.dtype检查数据类型:
print(x.dtype)
print(y.dtype)
输出:float64 torch.float64
现在可以将PyTorch张量转换为NumPy数组,使用.numpy()方法:
z = y.numpy()
print(z)
输出:array([1., 2., 3.])
与NumPy的互操作性是必需的,因为将要处理的大多数数据集很可能会在NumPy中进行处理。
在这里,可能会想知道为什么使用Pytorch而不是NumPy,因为它也提供了所有所需的库和实用工具,用于处理多维数组和执行大型计算。这主要是因为两个原因:
自动梯度:计算张量操作的梯度的能力是一个强大的能力,对于训练神经网络和执行反向传播至关重要。