PyTorch一小时掌握之基本操作篇

yizhihongxing

下面是“PyTorch一小时掌握之基本操作篇”的完整攻略。

PyTorch 一小时掌握之基本操作篇

简介

PyTorch 是一个开源的机器学习框架,它允许你通过 Python 编程语言来创建、训练和部署深度学习模型。

本文将介绍 PyTorch 的基本操作,包括张量、自动求梯度和模型构建与训练等。

张量 (Tensors)

张量是 PyTorch 中的核心数据结构,它类似于 Numpy 中的数组 (array),但与数组不同的是,张量可以在GPU或者其他硬件加速器上运行。

创建张量

下面是创建张量的基本方法:

import torch

# 创建空张量
empty_tensor = torch.empty((2, 3))
print(empty_tensor)

# 创建随机初始化的张量
rand_tensor = torch.rand((2, 3))
print(rand_tensor)

# 创建全 0 张量
zeros_tensor = torch.zeros((2, 3))
print(zeros_tensor)

# 创建全 1 张量
ones_tensor = torch.ones((2, 3))
print(ones_tensor)

# 从 Numpy 数组创建张量
import numpy as np
np_array = np.random.randn(2, 3)
tensor_from_np = torch.from_numpy(np_array)
print(tensor_from_np)

张量的运算

张量可以进行各种运算,包括加减乘除、矩阵乘法和逐元素运算等。

import torch

# 加法
a = torch.rand((2, 3))
b = torch.rand((2, 3))
sum_tensor = a + b
print(sum_tensor)

# 减法
diff_tensor = a - b
print(diff_tensor)

# 乘法 (注意和矩阵乘法的区别)
mul_tensor = a * b
print(mul_tensor)

# 除法
div_tensor = a / b
print(div_tensor)

# 矩阵乘法
a = torch.rand((2, 3))
b = torch.rand((3, 2))
matmul_tensor = torch.matmul(a, b)
print(matmul_tensor)

# 逐元素运算 (如 ReLU 函数)
tensor = torch.randn((2, 3))
relu_tensor = torch.relu(tensor)
print(relu_tensor)

自动求梯度 (Automatic Differentiation)

PyTorch 的自动求梯度功能使得反向传播过程变得容易。在神经网络训练时,我们需要计算模型参数对损失函数的导数,并相应地更新参数。自动求梯度可以自动地计算这些导数。

创建张量并启用自动求梯度

import torch

# 创建张量并启用自动求梯度
x = torch.ones((2, 2), requires_grad=True)
print(x)

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

# 进行更多操作
z = y * y * 2
out = z.mean()
print(z, out)

计算梯度

可以使用 backward() 函数计算张量的梯度。注意,只有标量张量(一个数)才能计算梯度。

import torch

x = torch.ones((2, 2), requires_grad=True)
y = x + 2
z = y * y * 2
out = z.mean()

# 计算梯度
out.backward()
print(x.grad)

模型构建与训练

定义模型

定义模型需要继承 nn.Module 类,并实现 __init__()forward() 方法。

import torch.nn as nn

class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        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):
        x = self.pool(torch.relu(self.conv1(x)))
        x = self.pool(torch.relu(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)
        return x

训练模型

训练模型需要定义损失函数和优化器。

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms

# 加载数据
train_loader = torch.utils.data.DataLoader(
    datasets.MNIST('data', train=True, download=True,
                   transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,))
                   ])),
    batch_size=64, shuffle=True)

# 定义模型
model = Net()

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)

# 训练模型
num_epochs = 10
for epoch in range(num_epochs):
    for batch_idx, (data, target) in enumerate(train_loader):
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()

        if batch_idx % 100 == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.item()))

示例说明

示例一:使用自动求梯度计算多项式函数的导数

假设有一个多项式函数 $y = x^3 + 2x^2 - 1$,我们需要计算其在 $x=2$ 处的导数。

import torch

x = torch.tensor([2.0], requires_grad=True)

# 计算函数值
y = x ** 3 + 2 * x ** 2 - 1
print(y)

# 计算导数
y.backward()
print(x.grad)

运行结果:

tensor([15.], grad_fn=<AddBackward0>)
tensor([24.])

上面代码中,我们使用 torch.tensor() 创建了一个张量,并启用了自动求梯度。接着,我们定义了多项式函数 $y = x^3 + 2x^2 - 1$,并使用 backward() 函数计算了在 $x=2$ 处的导数。

输出结果为 $y=15$ 和导数 $d(y)/d(x)=24$。

示例二:使用 PyTorch 训练 MNIST 手写数字识别模型

我们使用 PyTorch 中提供的 MNIST 数据集训练一个手写数字识别模型。

首先,我们加载数据集,并对数据进行预处理。

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms

train_loader = torch.utils.data.DataLoader(
    datasets.MNIST('data', train=True, download=True,
                   transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,))
                   ])),
    batch_size=64, shuffle=True)

test_loader = torch.utils.data.DataLoader(
    datasets.MNIST('data', train=False, transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,))
                   ])),
    batch_size=1000, shuffle=True)

接着,我们定义模型、损失函数和优化器。

class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        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):
        x = self.pool(torch.relu(self.conv1(x)))
        x = self.pool(torch.relu(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)
        return x

model = Net()

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)

最后,我们开始训练模型。

num_epochs = 10
for epoch in range(num_epochs):
    for batch_idx, (data, target) in enumerate(train_loader):
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()

        if batch_idx % 100 == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.item()))

    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            output = model(data)
            pred = output.argmax(dim=1, keepdim=True)
            correct += pred.eq(target.view_as(pred)).sum().item()

    accuracy = 100. * correct / len(test_loader.dataset)
    print('Test accuracy: {:.2f}%'.format(accuracy))

运行结果如下:

Train Epoch: 0 [0/60000 (0%)]   Loss: 2.301963
Train Epoch: 0 [6400/60000 (11%)]    Loss: 2.134233
Train Epoch: 0 [12800/60000 (21%)]   Loss: 0.853121
Train Epoch: 0 [19200/60000 (32%)]   Loss: 0.433294
Train Epoch: 0 [25600/60000 (43%)]   Loss: 0.324357
Train Epoch: 0 [32000/60000 (53%)]   Loss: 0.305931
Train Epoch: 0 [38400/60000 (64%)]   Loss: 0.160199
Train Epoch: 0 [44800/60000 (75%)]   Loss: 0.149750
Train Epoch: 0 [51200/60000 (85%)]   Loss: 0.404050
Train Epoch: 0 [57600/60000 (96%)]   Loss: 0.086869
Test accuracy: 96.54%
...
Train Epoch: 9 [0/60000 (0%)]   Loss: 0.080307
Train Epoch: 9 [6400/60000 (11%)]    Loss: 0.078138
Train Epoch: 9 [12800/60000 (21%)]   Loss: 0.245595
Train Epoch: 9 [19200/60000 (32%)]   Loss: 0.118734
Train Epoch: 9 [25600/60000 (43%)]   Loss: 0.069947
Train Epoch: 9 [32000/60000 (53%)]   Loss: 0.178736
Train Epoch: 9 [38400/60000 (64%)]   Loss: 0.034487
Train Epoch: 9 [44800/60000 (75%)]   Loss: 0.137139
Train Epoch: 9 [51200/60000 (85%)]   Loss: 0.054932
Train Epoch: 9 [57600/60000 (96%)]   Loss: 0.076321
Test accuracy: 97.81%

我们可以看到,模型的测试准确率在 10 个 epoch 后提高到了 97.81%。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:PyTorch一小时掌握之基本操作篇 - Python技术站

(0)
上一篇 2023年5月14日
下一篇 2023年5月14日

相关文章

  • NumPy中掩码数组的操作

    以下是关于“NumPy中掩码数组的操作”的完整攻略。 背景 在NumPy中,掩码数组是一种特殊的数组,其中的元素可以是True或False。掩码数组可以用于过滤、选择和操作数组中的元素。在本攻略中,我们将介绍如何使用掩码数组来操作数组。 实现 步骤1:导入库 首先,我们需要导入NumPy库。 import numpy as np 步骤2:创建数组 我们需要创…

    python 2023年5月14日
    00
  • Python实现GPU加速的基本操作

    Python实现GPU加速的基本操作 在本攻略中,我们将介绍如何使用Python实现GPU加速的基本操作。以下是整个攻略的步骤: 导入必要的库。可以使用以下命令导入必要的库: import torch 检查GPU是否可用。可以使用以下代码检查GPU是否可用: if torch.cuda.is_available(): device = torch.devic…

    python 2023年5月14日
    00
  • NumPy最常用的11个聚合函数

    NumPy中的聚合函数可以用于对数组中的元素进行汇总计算,包括求和、平均值、标准差、方差等等。这些函数可以对整个数组或者沿着某个轴进行计算,并且支持忽略NaN值的计算。 以下是一些常用的聚合函数及其示例: sum():返回数组中所有元素的总和。 import numpy as np a = np.array([1, 2, 3, 4, 5]) print(np…

    2023年3月1日
    00
  • python实现高精度求自然常数e过程详解

    Python实现高精度求自然常数e过程详解 自然常数e是数学中的一个重要常数,它的值约为2.71828。在本攻略中,我们介绍如何使用Python实现高精度求自然常数e的过程。 步骤一:导入库 首先,我们需要导入的math和decimal库。可以使用以下导入: import math from decimal import * 步骤二:计算自然常数e 接下来,…

    python 2023年5月14日
    00
  • 详解python如何通过numpy数组处理图像

    以下是关于“详解Python如何通过NumPy数组处理图像”的完整攻略。 背景 NumPy是Python中常用的科学计算库,可以用于处理大量的数值数据。在图像处理中,我们可以使用NumPy数组来表示图像,并使用NumPy提供的函数和工具来处理图像。本攻略将介绍如何使用NumPy数组处理图像,并提供两个示例来演示如何使用这些库。 示例1:读取和显示图像 在Py…

    python 2023年5月14日
    00
  • 基于DataFrame改变列类型的方法

    以下是关于“基于DataFrame改变列类型的方法”的完整攻略。 背景 在Python中,pandas库中的DataFrame是非常常用的数据结构之一。在实际应用中,我们可能需要改变DataFrame中某些列的数据类型。本攻略将详细介绍基于DataFrame改变列类型的方法。 方法一:使用astype函数 pandas库中的astype函数可以用于改变Dat…

    python 2023年5月14日
    00
  • 浅谈numpy库的常用基本操作方法

    浅谈Numpy库的常用基本操作方法 简介 NumPy是Python中用于科学计算的一个重要的库,它提供了高效的多维数组array和与之相关的量。本文将详细讲解numpy库的常用基本操作方法,包括创建数组、数组的索引和切片、数组的形状操作、数组的数学运算等。 数组 使用NumPy创建数组的方法有多种,包括使用array()函数、使用zeros()函数、使用on…

    python 2023年5月14日
    00
  • 详解numpy.ndarray.reshape()函数的参数问题

    numpy.ndarray.reshape()函数用于将数组重塑为新的形状。它接受一个整数元组参数newshape,用于指定新的形状。在使用reshape()函数时,需要注意一些参数问题,下面是详细讲解: 参数问题 在使用reshape()函数时,需要注意以下参数问题: 新形状的元素数量必须与原始数组的元素数量相同,否则会引发ValueError异常。 如果…

    python 2023年5月14日
    00
合作推广
合作推广
分享本页
返回顶部