当前位置: 首页 > news >正文

Python 课程15-PyTorch

前言

PyTorch 是一个开源的深度学习框架,由 Facebook 开发,广泛应用于学术研究和工业领域。与 TensorFlow 类似,PyTorch 提供了强大的工具用于构建和训练深度学习模型。PyTorch 的动态计算图和灵活的 API 使得它特别适合研究和实验。它还支持 GPU 加速,适用于构建复杂的神经网络。

本教程将详细介绍 PyTorch 的每个常用指令和功能,帮助你从基础知识开始,逐步掌握如何使用 PyTorch 进行深度学习开发。


目录

  1. PyTorch 基础

    • 安装 PyTorch
    • 创建张量(Tensors)
    • 张量操作与计算
    • 自动微分与反向传播
  2. 神经网络构建

    • 使用 nn.Module 构建神经网络
    • 激活函数与损失函数
    • 优化器:SGD、Adam 等
    • 自定义训练循环
  3. 高级功能

    • 数据集与数据加载器
    • 使用 GPU 加速模型训练
    • 保存与加载模型
  4. 卷积神经网络 (CNN)

    • 构建 CNN 模型
    • 训练与评估 CNN
  5. 递归神经网络 (RNN)

    • 构建 RNN 与 LSTM
    • 训练与评估 RNN 模型

1. PyTorch 基础

安装 PyTorch

PyTorch 可以通过 pip 安装。你可以根据你的操作系统和硬件(例如 GPU)选择合适的安装命令:

pip install torch torchvision torchaudio

 导入 PyTorch:

import torch
创建张量(Tensors)

张量是 PyTorch 中的核心数据结构,它类似于 NumPy 数组,但支持 GPU 加速。

  • 创建张量
    # 创建一个 3x3 的随机张量
    x = torch.rand(3, 3)
    print(x)# 创建一个全 0 张量
    x = torch.zeros(3, 3)
    print(x)# 创建一个全 1 张量
    x = torch.ones(3, 3)
    print(x)
    
  • 从列表或 NumPy 创建张量
    import numpy as np# 从列表创建张量
    x = torch.tensor([1, 2, 3, 4])
    print(x)# 从 NumPy 数组创建张量
    np_array = np.array([5, 6, 7, 8])
    x = torch.from_numpy(np_array)
    print(x)
    
    张量操作与计算

    PyTorch 提供了多种张量运算函数,如加法、乘法、矩阵乘法等。它们与 NumPy 的操作类似,但支持自动微分。

  • 基本运算
    x = torch.rand(3, 3)
    y = torch.rand(3, 3)# 加法
    z = x + y
    print(z)# 乘法
    z = x * y
    print(z)# 矩阵乘法
    z = torch.matmul(x, y)
    print(z)
    
  • 重塑张量
    x = torch.rand(16)# 重塑为 4x4 的张量
    x_reshaped = x.view(4, 4)
    print(x_reshaped)
    
    自动微分与反向传播

    PyTorch 的自动微分机制通过 autograd 实现,它能够自动计算张量的梯度,从而实现反向传播。

  • 计算梯度
    # 创建一个张量,并设置 requires_grad=True 以跟踪其梯度
    x = torch.tensor([2.0, 3.0], requires_grad=True)# 定义一个简单的函数
    y = x[0]**2 + x[1]**3# 进行反向传播,计算梯度
    y.backward()# 输出梯度
    print(x.grad)  # x[0] 的梯度是 4.0,x[1] 的梯度是 27.0
    


2. 神经网络构建

PyTorch 提供了 torch.nn 模块,用于构建神经网络。通过继承 nn.Module 类,你可以创建自定义的神经网络。

使用 nn.Module 构建神经网络

以下是一个使用 PyTorch 构建的简单前馈神经网络:

import torch.nn as nnclass SimpleNN(nn.Module):def __init__(self):super(SimpleNN, self).__init__()self.fc1 = nn.Linear(28 * 28, 128)  # 输入层到隐藏层self.fc2 = nn.Linear(128, 64)       # 隐藏层self.fc3 = nn.Linear(64, 10)        # 输出层def forward(self, x):x = x.view(-1, 28 * 28)  # 展平输入x = torch.relu(self.fc1(x))  # 激活函数 ReLUx = torch.relu(self.fc2(x))x = self.fc3(x)return x# 创建模型实例
model = SimpleNN()
print(model)
激活函数与损失函数
  • 激活函数:PyTorch 提供了多种激活函数,可以在网络的前向传播中使用。
    # 使用 ReLU 激活函数
    x = torch.rand(5, 5)
    x = torch.relu(x)
    
  • 损失函数:用于计算模型预测与真实标签之间的误差。
criterion = nn.CrossEntropyLoss()  # 适用于分类问题的交叉熵损失
优化器:SGD、Adam 等

优化器用于更新模型参数。PyTorch 提供了多种优化器,如 SGDAdam

  • 使用 SGD 优化器
    import torch.optim as optim# 使用 SGD 优化器
    optimizer = optim.SGD(model.parameters(), lr=0.01)
    
  • 使用 Adam 优化器
    optimizer = optim.Adam(model.parameters(), lr=0.001)
    
自定义训练循环

以下是一个简单的训练循环示例,用于训练神经网络模型。

# 假设我们有训练数据 loader
for epoch in range(10):for batch_idx, (data, target) in enumerate(train_loader):# 将梯度置零optimizer.zero_grad()# 前向传播output = model(data)loss = criterion(output, target)# 反向传播loss.backward()# 更新权重optimizer.step()print(f'Epoch {epoch + 1}, Loss: {loss.item()}')

3. 高级功能

数据集与数据加载器

PyTorch 提供了 torch.utils.data 模块,用于加载数据集。你可以使用内置的数据集,或者自定义自己的数据集。

  • 使用内置数据集(MNIST)
    from torchvision import datasets, transforms# 定义数据变换
    transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,), (0.5,))
    ])# 加载 MNIST 数据集
    train_dataset = datasets.MNIST(root='data', train=True, transform=transform, download=True)
    test_dataset = datasets.MNIST(root='data', train=False, transform=transform, download=True)# 创建数据加载器
    train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=32, shuffle=True)
    test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=32, shuffle=False)
    
  • 自定义数据集
    from torch.utils.data import Datasetclass MyDataset(Dataset):def __init__(self, data, labels):self.data = dataself.labels = labelsdef __len__(self):return len(self.data)def __getitem__(self, idx):return self.data[idx], self.labels[idx]
    

使用 GPU 加速模型训练

PyTorch 支持使用 GPU 加速模型训练。你可以通过将模型和张量移动到 GPU 上来加速计算。

  • 检查 GPU 可用性
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    print(device)
    
  • 将模型和数据移动到 GPU
model.to(device)# 将数据移动到 GPU
data, target = data.to(device), target.to(device)
保存与加载模型

你可以通过保存和加载模型的权重来持久化训练的模型。

  • 保存模型
    torch.save(model.state_dict(), 'model.pth')
    
  • 加载模型
    model = SimpleNN()
    model.load_state_dict(torch.load('model.pth'))
    

4. 卷积神经网络 (CNN)

卷积神经网络(CNN)在处理图像数据时非常有效。它能够通过卷积层提取图像的局部特征,并通过池化层减少特征图的维度。以下部分将详细介绍如何在 PyTorch 中构建和训练 CNN 模型。

构建 CNN 模型

我们将使用 PyTorch 的 torch.nn 模块构建一个 CNN 模型来处理 MNIST 手写数字分类任务。该模型包含卷积层、池化层和全连接层。

import torch.nn as nn
import torch.nn.functional as Fclass CNN(nn.Module):def __init__(self):super(CNN, self).__init__()# 卷积层 1:输入 1 个通道,输出 32 个通道,卷积核 3x3self.conv1 = nn.Conv2D(1, 32, kernel_size=3)# 卷积层 2:输入 32 个通道,输出 64 个通道self.conv2 = nn.Conv2D(32, 64, kernel_size=3)# 最大池化层:2x2 核self.pool = nn.MaxPool2D(2, 2)# 全连接层 1self.fc1 = nn.Linear(64 * 12 * 12, 128)  # MNIST 图像 28x28,经过两次卷积和池化后为 12x12# 全连接层 2self.fc2 = nn.Linear(128, 10)  # 输出为 10 类别(0-9)def forward(self, x):# 前向传播x = self.pool(F.relu(self.conv1(x)))  # 卷积 -> ReLU -> 池化x = self.pool(F.relu(self.conv2(x)))  # 卷积 -> ReLU -> 池化x = x.view(-1, 64 * 12 * 12)          # 展平张量以适配全连接层x = F.relu(self.fc1(x))               # 全连接层 -> ReLUx = self.fc2(x)                       # 输出层return x# 实例化模型
model = CNN()
print(model)
训练与评估 CNN 模型

接下来,我们将训练这个 CNN 模型,并在 MNIST 数据集上进行评估。

  • 数据加载与准备
    import torch.optim as optim
    from torchvision import datasets, transforms# 定义图像变换:将图像转换为张量并标准化
    transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])# 加载 MNIST 数据集
    train_dataset = datasets.MNIST(root='data', train=True, transform=transform, download=True)
    test_dataset = datasets.MNIST(root='data', train=False, transform=transform, download=True)train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=32, shuffle=True)
    test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=32, shuffle=False)
    
  • 编译模型:我们将使用 交叉熵损失Adam 优化器 来训练模型。
    criterion = nn.CrossEntropyLoss()  # 交叉熵损失函数
    optimizer = optim.Adam(model.parameters(), lr=0.001)  # Adam 优化器
    
  • 训练模型:以下是训练循环代码,它包括前向传播、计算损失、反向传播以及权重更新。
    for epoch in range(10):  # 训练 10 个周期running_loss = 0.0for i, (inputs, labels) in enumerate(train_loader):# 梯度清零optimizer.zero_grad()# 前向传播outputs = model(inputs)loss = criterion(outputs, labels)# 反向传播loss.backward()optimizer.step()# 打印损失值running_loss += loss.item()if i % 100 == 99:  # 每 100 个 batch 打印一次print(f'Epoch {epoch + 1}, Batch {i + 1}, Loss: {running_loss / 100:.3f}')running_loss = 0.0
    
  • 模型评估:在测试集上评估模型的准确性。
    correct = 0
    total = 0
    model.eval()  # 设置模型为评估模式
    with torch.no_grad():  # 禁用梯度计算,以提高推理速度for inputs, labels in test_loader:outputs = model(inputs)_, predicted = torch.max(outputs, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print(f'Accuracy on test set: {100 * correct / total:.2f}%')
    

5. 递归神经网络 (RNN)

递归神经网络(RNN)特别适合处理序列数据,例如时间序列、自然语言处理等任务。PyTorch 提供了多种 RNN 层,如 RNNGRULSTM

构建 RNN 与 LSTM 模型

LSTM(长短期记忆网络)是一种改进的 RNN,能够更好地处理长期依赖关系。下面是一个简单的 LSTM 模型。

import torch.nn as nnclass LSTM(nn.Module):def __init__(self, input_size, hidden_size, num_layers, output_size):super(LSTM, self).__init__()self.hidden_size = hidden_sizeself.num_layers = num_layers# 定义 LSTM 层self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)# 全连接层self.fc = nn.Linear(hidden_size, output_size)def forward(self, x):# 初始化隐藏状态和记忆状态h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)# 前向传播 LSTMout, _ = self.lstm(x, (h0, c0))# 取最后一个时间步的输出out = self.fc(out[:, -1, :])return out# 实例化 LSTM 模型
model = LSTM(input_size=28, hidden_size=128, num_layers=2, output_size=10)
print(model)
训练与评估 RNN 模型
  • 数据加载

假设我们使用 MNIST 数据集,但将每行像素视为序列输入。

train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=32, shuffle=False)
  • 训练模型
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)for epoch in range(10):running_loss = 0.0for i, (inputs, labels) in enumerate(train_loader):inputs = inputs.view(-1, 28, 28)  # 将图像展平为序列形式optimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()running_loss += loss.item()if i % 100 == 99:print(f'Epoch {epoch + 1}, Batch {i + 1}, Loss: {running_loss / 100:.3f}')running_loss = 0.0
  • 评估模型
correct = 0
total = 0
model.eval()
with torch.no_grad():for inputs, labels in test_loader:inputs = inputs.view(-1, 28, 28)outputs = model(inputs)_, predicted = torch.max(outputs, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print(f'Accuracy on test set: {100 * correct / total:.2f}%')

结论

通过本教程,你已经学习了如何使用 PyTorch 进行深度学习项目的构建与训练。PyTorch 强大的灵活性和动态计算图,使它成为了学术研究和工业应用中的首选工具。它提供了简洁的 API,可以让你轻松实现复杂的神经网络模型,并通过 GPU 加速显著提升训练效率。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 产品探秘|开物——面向AI原生和云原生网络研究的首选科研平台
  • 电脑的主板,内存条插多少合适?
  • SpringBoot入门(黑马)
  • 抖音生活服务常见玩法及收益情况详解!普通人如何把握机会?
  • Linux Kernel Makefiles 编译标志详解
  • Spring高手之路23——AOP触发机制与代理逻辑的执行
  • 项目测试用例:
  • 混合整数规划及其MATLAB实现
  • 阿里云OSS与IOT使用详解
  • C++的类与对象下
  • sshpass 实现的SSH免交互密码登录和ARM移植
  • JSON数组
  • opencv实战项目二十四:棋盘格相机内参标定
  • SpinalHDL之结构(一)
  • 水下目标检测数据集 urpc2021
  • CSS 三角实现
  • CSS魔法堂:Absolute Positioning就这个样
  • Docker: 容器互访的三种方式
  • es的写入过程
  • JS+CSS实现数字滚动
  • js继承的实现方法
  • PHP变量
  • vue.js框架原理浅析
  • WebSocket使用
  • 创建一个Struts2项目maven 方式
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 技术:超级实用的电脑小技巧
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 想写好前端,先练好内功
  • 一个完整Java Web项目背后的密码
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​Python 3 新特性:类型注解
  • #AngularJS#$sce.trustAsResourceUrl
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (bean配置类的注解开发)学习Spring的第十三天
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (每日一问)计算机网络:浏览器输入一个地址到跳出网页这个过程中发生了哪些事情?(废话少说版)
  • (算法)Travel Information Center
  • ***利用Ms05002溢出找“肉鸡
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .form文件_SSM框架文件上传篇
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • .net中我喜欢的两种验证码
  • @Autowired注解的实现原理
  • @NotNull、@NotEmpty 和 @NotBlank 区别
  • @RequestMapping-占位符映射
  • @vue/cli 3.x+引入jQuery