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

    当你没有任何编程经验时,学习Python可能会感到有些困难。但是,只要你掌握了正确的学习方法和技巧,就可以快速掌握Python的基础知识和语法。以下是零基如何系统快速学习Python的完整攻略,包含两个示例。 1. 学习Python的基础知识 在学习之前,需要掌握一些基础知识,例如计算机编程的基本概念、数据类型、变量、运算符、条件语、循环句等。可以通过阅读相…

    python 2023年5月14日
    00
  • 对python numpy.array插入一行或一列的方法详解

    下面是关于“对Python NumPy数组插入一行或一列的方法详解”的完整攻略,包含了两个示例。 插入一行 下面是一个示例,演示如何在二维数组中插一行。 import numpy as np # 创建一个二维数组 a = np.array([[1, 2, 3], [4, 5,6], [7, 8, 9]]) # 创建一个新的一维数组 b = np.array(…

    python 2023年5月14日
    00
  • Pytorch 实现变量类型转换

    在PyTorch中,变量类型转换是一种常见的操作,可以将一个变量从一种类型转换为另一种类型。本文将详细讲解如何在PyTorch中实现变量类型转换,并提供两个示例说明。 变量类型转换的方法 在PyTorch中,变量类型转换的方法包括: 方法1:使用to()方法 可以使用to()方法将变量转换为指定的类型,例如: import torch # 将变量a转换为fl…

    python 2023年5月14日
    00
  • 详解Numpy扩充矩阵维度(np.expand_dims, np.newaxis)和删除维度(np.squeeze)的方法

    详解Numpy扩充矩阵维度(np.expand_dims,np.newaxis)和删除维度(np.squeeze)的方法 在Numpy中,我们可以使用np.expand_dims()和np.newaxis来扩充矩阵的维度,使用np.squeeze()来删除矩阵维度。这些函数可以帮助我们更方便地处理多维数组。 np.expand_dims()和np.newax…

    python 2023年5月13日
    00
  • Numpy数组转置的两种实现方法

    以下是关于“Numpy数组转置的两种实现方法”的完整攻略。 背景 在NumPy中,数组转置是一个常见的操作。在本攻略中我们将介绍两种现Numpy数组转置的方法。 实现 方法1:使用属性 NumPy数组有一个T属性,可以用于转置数组。T属性返回数组的转置视图,而不是复制数组。 以下是一个示例,展示如何使用T属性转置数组: import numpy as np …

    python 2023年5月14日
    00
  • 关于python导入模块import与常见的模块详解

    以下是关于Python导入模块import与常见的模块详解的完整攻略,包括两个示例: 关于Python导入模块import与常见的模块详解 导入模块 在Python中,可以使用import语句导入模块。可以使用以下语法导入模块: import module_name 在这个示例中,我们使用import语句导入名为module_name的模块。 示例1:导入m…

    python 2023年5月14日
    00
  • 利用Python实现sqlite3增删改查的封装

    下面我详细讲解一下“利用Python实现sqlite3增删改查的封装”的完整攻略。 1. sqlite3简介 sqlite3是一款轻量级、嵌入式的关系型数据库。它无需单独的服务器进程,数据存储在本地文件中,因此非常适合于需要本地数据存储需求的应用程序。 2. Python的sqlite3模块 Python标准库中自带sqlite3模块,使用sqlite3模块…

    python 2023年5月14日
    00
  • Python爬虫常用库的安装及其环境配置

    以下是“Python爬虫常用库的安装及其环境配置”的完整攻略。 步骤一:安装Python解释器 首先需要安装Python解释器,可以到官网下载对应系统的安装包,然后进行安装。 步骤二:安装pip包管理工具 pip是Python的包管理工具,一般在Python安装时会默认安装,可以通过以下命令检查是否已安装: pip –version 如果未安装,则可以通过…

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