Pytorch 入门介绍

发布于:2024-12-18 ⋅ 阅读:(53) ⋅ 点赞:(0)

1. Pytorch 简介

1.1 Pytorch 的历史

PyTorch 是一个由 Facebook 的人工智能研究团队开发的开源深度学习框架。在2016年发布后,PyTorch 很快就因其易用性、灵活性和强大的功能而在科研社区中广受欢迎。

1.2 Pytorch 的优点

1. 动态计算图

PyTorch 最突出的优点之一就是它使用了动态计算图(Dynamic Computation Graphs,DCGs),与 TensorFlow 和其他框架使用的静态计算图不同。动态计算图允许你在运行时更改图的行为。这使得 PyTorch 非常灵活,在处理不确定性或复杂性时具有优势,因此非常适合研究和原型设计。

2. 易用性

PyTorch 被设计成易于理解和使用。其API设计的直观性使得学习和使用 PyTorch 成为一件非常愉快的事情。此外,由于 PyTorch 与 Python 的深度集成,它在 Python 程序员中非常流行。

3. 易于调试

由于 PyTorch 的动态性和 Python 性质,调试 PyTorch 程序变得相当直接。你可以使用 Python 的标准调试工具,如 PDB 或 PyCharm,直接查看每个操作的结果和中间变量的状态。

4. 强大的社区支持

PyTorch 的社区非常活跃和支持。官方论坛、GitHub、Stack Overflow 等平台上有大量的 PyTorch用户和开发者,你可以从中找到大量的资源和帮助。

5. 广泛的预训练模型

PyTorch 提供了大量的预训练模型,包括但不限于 ResNet,VGG,Inception,SqueezeNet,EfficientNet 等等。这些预训练模型可以帮助你快速开始新的项目。

6. 高效的GPU利用

PyTorch 可以非常高效地利用 NVIDIA 的 CUDA 库来进行 GPU 计算。同时,它还支持分布式计算,让你可以在多个 GPU 或服务器上训练模型。

综上所述,PyTorch 因其易用性、灵活性、丰富的功能以及强大的社区支持,在深度学习领域中备受欢迎。

2. Pytorch基础 

2.1 Tensor操作

Tensor 是 PyTorch 中最基本的数据结构,你可以将其视为多维数组或者矩阵。PyTorch tensor 和NumPy array 非常相似,但是 tensor 还可以在 GPU 上运算,而 NumPy array 则只能在 CPU 上运算。下面,我们将介绍一些基本的 tensor 操作。

首先,我们需要导入 PyTorch 库:

import torch

然后,我们可以创建一个新的 tensor。以下是一些创建 tensor 的方法:

# 创建一个未初始化的5x3矩阵
x = torch.empty(5, 3)
print(x)

# 创建一个随机初始化的5x3矩阵
x = torch.rand(5, 3)
print(x)

# 创建一个5x3的零矩阵,类型为long
x = torch.zeros(5, 3, dtype=torch.long)
print(x)

# 直接从数据创建tensor
x = torch.tensor([5.5, 3])
print(x)

我们还可以对已有的 tensor 进行操作。以下是一些基本操作:

# 创建一个tensor,并设置requires_grad=True以跟踪计算历史
x = torch.ones(2, 2, requires_grad=True)
print(x)

# 对tensor进行操作
y = x + 2
print(y)

# y是操作的结果,所以它有grad_fn属性
print(y.grad_fn)

# 对y进行更多操作
z = y * y * 3
out = z.mean()

print(z, out)

上述操作的结果如下:

tensor([[1., 1.],
        [1., 1.]], requires_grad=True)
tensor([[3., 3.],
        [3., 3.]], grad_fn=<AddBackward0>)
<AddBackward0 object at 0x7f36c0a7f1d0>
tensor([[27., 27.],
        [27., 27.]], grad_fn=<MulBackward0>) tensor(27., grad_fn=<MeanBackward0>)

在 PyTorch 中,我们可以使用.backward()方法来计算梯度。例如:

# 因为out包含一个标量,out.backward()等价于out.backward(torch.tensor(1.))
out.backward()

# 打印梯度 d(out)/dx
print(x.grad)

以上是 PyTorch tensor 的基本操作,我们可以看到 PyTorch tensor 操作非常简单和直观。在后续的学习中,我们将会使用到更多的tensor操作,例如索引、切片、数学运算、线性代数、随机数等等。

2.2 GPU加速

在深度学习训练中,GPU(图形处理器)加速是非常重要的一部分。GPU的并行计算能力使得其比CPU在大规模矩阵运算上更具优势。PyTorch提供了简单易用的API,让我们可以很容易地在CPU和GPU之间切换计算。

首先,我们需要检查系统中是否存在可用的GPU。在PyTorch中,我们可以使用torch.cuda.is_available()来检查:

import torch

# 检查是否有可用的GPU
if torch.cuda.is_available():
    print("There is a GPU available.")
else:
    print("There is no GPU available.")

如果存在可用的GPU,我们可以使用.to()方法将tensor移动到GPU上:

# 创建一个tensor
x = torch.tensor([1.0, 2.0])

# 移动tensor到GPU上
if torch.cuda.is_available():
    x = x.to('cuda')

我们也可以直接在创建tensor的时候就指定其设备:

# 直接在GPU上创建tensor
if torch.cuda.is_available():
    x = torch.tensor([1.0, 2.0], device='cuda')

在进行模型训练时,我们通常会将模型和数据都移动到GPU上:

# 创建一个简单的模型
model = torch.nn.Linear(10, 1)

# 创建一些数据
data = torch.randn(100, 10)

# 移动模型和数据到GPU
if torch.cuda.is_available():
    model = model.to('cuda')
    data = data.to('cuda')

以上就是在PyTorch中进行GPU加速的基本操作。使用GPU加速可以显著提高深度学习模型的训练速度。但需要注意的是,数据在CPU和GPU之间的传输会消耗一定的时间,因此我们应该尽量减少数据的传输次数。

2.3 自动求导

在深度学习中,我们经常需要进行梯度下降优化。这就需要我们计算梯度,也就是函数的导数。在PyTorch中,我们可以使用自动求导机制(autograd)来自动计算梯度。

在PyTorch中,我们可以设置tensor.requires_grad=True来追踪其上的所有操作。完成计算后,我们可以调用.backward()方法,PyTorch会自动计算和存储梯度。这个梯度可以通过.grad属性进行访问。

下面是一个简单的示例:

import torch

# 创建一个tensor并设置requires_grad=True来追踪其计算历史
x = torch.ones(2, 2, requires_grad=True)

# 对这个tensor做一次运算:
y = x + 2

# y是计算的结果,所以它有grad_fn属性
print(y.grad_fn)

# 对y进行更多的操作
z = y * y * 3
out = z.mean()

print(z, out)

# 使用.backward()来进行反向传播,计算梯度
out.backward()

# 输出梯度d(out)/dx
print(x.grad)

以上示例中,out.backward()等同于out.backward(torch.tensor(1.))。如果out不是一个标量,因为tensor是矩阵,那么在调用.backward()时需要传入一个与out同形的权重向量进行相乘。

例如:

x = torch.randn(3, requires_grad=True)

y = x * 2
while y.data.norm() < 1000:
    y = y * 2

print(y)

v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)

print(x.grad)

以上就是PyTorch中自动求导的基本使用方法。自动求导是PyTorch的重要特性之一,它为深度学习模型的训练提供了极大的便利。

3. PyTorch 神经网络

3.1 构建神经网络

PyTorch提供了torch.nn库,它是用于构建神经网络的工具库。torch.nn库依赖于autograd库来定义和计算梯度。nn.Module包含了神经网络的层以及返回输出的forward(input)方法。

以下是一个简单的神经网络的构建示例:

import torch
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()

        # 输入图像channel:1,输出channel:6,5x5卷积核
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.conv2 = nn.Conv2d(6, 16, 5)

        # 全连接层
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        # 使用2x2窗口进行最大池化
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        # 如果窗口是方的,只需要指定一个维度
        x = F.max_pool2d(F.relu(self.conv2(x)), 2)

        x = x.view(-1, self.num_flat_features(x))

        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)

        return x

    def num_flat_features(self, x):
        size = x.size()[1:]  # 获取除了batch维度之外的其他维度
        num_features = 1
        for s in size:
            num_features *= s
        return num_features

net = Net()
print(net)

以上就是一个简单的神经网络的构建方法。我们首先定义了一个Net类,这个类继承自nn.Module。然后在__init__方法中定义了网络的结构,在forward方法中定义了数据的流向。在网络的构建过程中,我们可以使用任何tensor操作。

需要注意的是,backward函数(用于计算梯度)会被autograd自动创建和实现。你只需要在nn.Module的子类中定义forward函数。

在创建好神经网络后,我们可以使用net.parameters()方法来返回网络的可学习参数。

3.2 模型的保存和加载

在深度学习模型的训练过程中,我们经常需要保存模型的参数以便于将来重新加载。这对于中断的训练过程的恢复,或者用于模型的分享和部署都是非常有用的。

PyTorch提供了简单的API来保存和加载模型。最常见的方法是使用torch.save来保存模型的参数,然后通过torch.load来加载模型的参数。

3.2.1 保存和加载模型参数

以下是一个简单的示例:

# 保存
torch.save(model.state_dict(), PATH)

# 加载
model = TheModelClass(*args, **kwargs)
model.load_state_dict(torch.load(PATH))
model.eval()

在保存模型参数时,我们通常使用.state_dict()方法来获取模型的参数。.state_dict()是一个从参数名字映射到参数值的字典对象。

在加载模型参数时,我们首先需要实例化一个和原模型结构相同的模型,然后使用.load_state_dict()方法加载参数。

请注意,load_state_dict()函数接受一个字典对象,而不是保存对象的路径。这意味着在你传入load_state_dict()函数之前,你必须反序列化你的保存的state_dict

在加载模型后,我们通常调用.eval()方法将dropout和batch normalization层设置为评估模式。否则,它们会在评估模式下保持训练模式。

3.2.2 保存和加载整个模型

除了保存模型的参数,我们也可以保存整个模型。

# 保存
torch.save(model, PATH)

# 加载
model = torch.load(PATH)
model.eval()

保存整个模型会将模型的结构和参数一起保存。这意味着在加载模型时,我们不再需要手动创建模型实例。但是,这种方式需要更多的磁盘空间,并且可能在某些情况下导致代码的混乱,所以并不总是推荐的。

以上就是PyTorch中模型的保存和加载的基本方法。适当的保存和加载模型可以帮助我们更好地进行模型的训练和评估。

参考文章:

https://zhuanlan.zhihu.com/p/647001891


网站公告

今日签到

点亮在社区的每一天
去签到