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

下面是“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日

相关文章

  • Python编程给numpy矩阵添加一列方法示例

    以下是关于“Python编程给numpy矩阵添加一列方法示例”的完整攻略。 给numpy矩阵添加一列 在Python中,可以使用numpy库中的concatenate()函数和reshape()函数来给numpy矩阵添加一列。具体步骤如下: 创建一个新的一维数组,作为要添加的列; 使用concatenate()将原矩阵和新数组按列连接; 使用reshape(…

    python 2023年5月14日
    00
  • Python编程不要再使用print调试代码了

    Python编程不要再使用print调试代码了 在Python编程中,调试代码是一个非常重要的过程。在过去,我们通常使用print语句来调试代码。但是,这种方法有时会很麻烦,尤其是在调试大型代码库时。在本攻略中,我们将介绍一些替代print语句的方法,以帮助您更有效地调试Python代码。 为什么不要使用print语句? 使用print语句调试代码的主要问题…

    python 2023年5月14日
    00
  • Python NumPy随机抽模块介绍及方法

    NumPy是Python中用于科学计算的一个重要的库,它提供了高效的多维数组array和与之相关的量。本文将详细讲解NumPy中的随机抽样模块,包括随机数生成、随机抽样、随机排列等方法。 随机数生成 使用NumPy中的random模块可以生成各种类型的随机数,包括整数、浮点数、布尔值等。面是一些示例: import numpy as np # 生成随机整数 …

    python 2023年5月14日
    00
  • numpy中数组的堆叠方法

    在NumPy中,可以使用堆叠方法将多个数组沿着不同的轴进行组合。本文将详细讲解NumPy中数组的堆叠方法,包括np.concatenate()函数、np.vstack()函数、np.hstack()函数、np.dstack()函数和np.stack()函数。 np.concatenate()函数 np.concatenate()函数可以将多个数组沿着指定的轴…

    python 2023年5月13日
    00
  • Python numpy生成矩阵基础用法实例代码

    Numpy是Python中一个非常强大的数学库,它提供了许多高效的数学函数和工具,特别是对于数组和矩阵的处理。本攻略详细讲解Python numpy生成矩阵的基础用法,包括生成矩阵的方法、矩阵的基本操作等,并提供两个示例代码。 生成矩阵的方法 使用Numpy,可以使用多种方法生成矩阵。下面是一些示例: 使用np.array()函数生成矩阵 import nu…

    python 2023年5月13日
    00
  • Numpy中np.max的用法及np.maximum区别

    Numpy中np.max的用法及np.maximum区别 在Numpy中,np.max()函数用于计算数组中的最大值,np.maximum()函数用于计算两个数组中对应元素的最大值。本文将深入讲这两个函数的用法及区别,并提供两个示例。 np.max()函数的用法 np.max()函数用于计算数组中的最大值。下面是一个示例: import numpy as n…

    python 2023年5月13日
    00
  • Python numpy.interp的实例详解

    以下是关于Python中numpy.interp()函数的攻略: Python中numpy.interp()函数 在Python中,使用numpy.interp()函数来进行线性插值。以下是一些实现方法: numpy.interp()函数的本用法 numpy.interp()函数可以在两个数组之间进行线性插值。以下是一个示例: import numpy as…

    python 2023年5月14日
    00
  • 使用numpy实现矩阵的翻转(flip)与旋转

    使用NumPy实现矩阵的翻转(flip)与旋转 NumPy是Python中一个重要的科学计算库,提供了高效的多维数组和各种派生对象及计算各种函数。在NumPy,可以使用flip()函数和rot90()函数来实现矩阵的翻转和旋转。本文将详细讲解使用NumPy实现矩阵的翻转和旋转的方法,并提供两个示例。 矩阵的翻转(f) 矩阵的翻转是指将矩阵中的行或列进行翻转。…

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