Python 课程15-PyTorch

news2024/11/24 7:03:56

前言

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 nn

class 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))  # 激活函数 ReLU
        x = 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 Dataset
    
    class MyDataset(Dataset):
        def __init__(self, data, labels):
            self.data = data
            self.labels = labels
    
        def __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 F

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        # 卷积层 1:输入 1 个通道,输出 32 个通道,卷积核 3x3
        self.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)
        # 全连接层 1
        self.fc1 = nn.Linear(64 * 12 * 12, 128)  # MNIST 图像 28x28,经过两次卷积和池化后为 12x12
        # 全连接层 2
        self.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))               # 全连接层 -> ReLU
        x = 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.0
        for 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 nn

class LSTM(nn.Module):
    def __init__(self, input_size, hidden_size, num_layers, output_size):
        super(LSTM, self).__init__()
        self.hidden_size = hidden_size
        self.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)
        
        # 前向传播 LSTM
        out, _ = 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.0
    for 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 加速显著提升训练效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2142919.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GetMaterialApp组件的用法

文章目录 1. 知识回顾2. 使用方法2.1 源码分析2.2 常用属性 3. 示例代码4. 内容总结 我们在上一章回中介绍了"Get包简介"相关的内容,本章回中将介绍GetMaterialApp组件.闲话休提,让我们一起Talk Flutter吧。 1. 知识回顾 我们在上一章回中已经…

King3399 SDK编译简明教程

该文章仅供参考,编写人不对任何实验设备、人员及测量结果负责!!! 0 引言 文章主要介绍King3399(瑞芯微rk3399开发板,荣品)官方SDK编译过程,涉及环境配置、补丁以及编译过程中注意事…

Using OpenAI API from Firebase Cloud Functions in flutter app

题意:“在 Flutter 应用中通过 Firebase Cloud Functions 使用 OpenAI API。” 问题背景: I cant figure out how to make this work. “我不知道该如何让这正常运行。” This is my cloud function in Javascript. Im trying a simple code to see if…

鸿蒙媒体开发系列04——音频播放

如果你也对鸿蒙开发感兴趣,加入“Harmony自习室”吧!扫描下方名片,关注公众号,公众号更新更快,同时也有更多学习资料和技术讨论群。 1、如何选择音频播放开发方式 在HarmonyOS系统中,多种API都提供了音频播…

C++_map_set详解

关联容器的基本介绍 关联容器支持高效的关键字查找和访问。map和set是最主要关联容器。关联容器也是用来存储数据的&#xff0c;与序列式容器不同的是&#xff0c;其里面存储的是<key, value>结构的键值对&#xff0c;在数据检索时比序列式容器效率更高。C标准库中提供了…

如何关闭前端Chrome的debugger反调试

1、禁用浏览器断点 2. 把控制台独立一个窗口

如何优雅地处理返回值

我们已经知道了如何优雅的校验传入的参数了&#xff0c;那么后端服务器如何实现把数据返回给前端呢&#xff1f; 返回格式 后端返回给前端我们一般用 JSON 体方式&#xff0c;定义如下&#xff1a; {#返回状态码code:string, #返回信息描述message:string,#返回值data…

《Google软件测试之道》笔记

介绍 GTAC&#xff1a;Google Test Automation Conference&#xff0c;Google测试自动化大会。 本书出版之前还有一本《微软测试之道》&#xff0c;值得阅读。 质量不是被测试出来的&#xff0c;但未经测试也不可能开发出有质量的软件。质量是开发过程的问题&#xff0c;而不…

09年408考研真题解析-计算机网络

[题34]在无噪声情况下&#xff0c;若某通信链路的带宽为3kHz&#xff0c;采用4个相位&#xff0c;每个相位具有4种振幅的QAM调制技术,则该通信链路的最大数据传输速率是&#xff08;B&#xff09; A.12 kbps B.24 kbps C.48 kbps D.96 kbps 解析&#xff…

优惠充值话费api对接如何选择对接平台?

优惠充值话费接口通常由电信运营商、第三方支付平台或专业的充值服务提供商提供。这些平台通过API接口允许开发者将话费充值功能集成到应用程序或网站中。 选择哪个平台比较好&#xff0c;取决于以下几个因素&#xff1a; 覆盖范围&#xff1a;选择能够覆盖你需要服务的地区和…

49.面向对象综合训练-朋友

1.创建JavaBean类 public class Friend {//题目要求&#xff1a;定义数组存储4个朋友对象//属性&#xff1a;姓名&#xff0c;年龄&#xff0c;性别&#xff0c;爱好//计算出四位朋友的平均年龄//统计出比平均年龄低的朋友有几个&#xff0c;并把信息都打印出来private String…

openstack之keystone介绍

功能 keystone在OpenStack中负责&#xff1a; 管理&#xff1a;用户、租户和权限&#xff1b; 认证&#xff1a;组件相互访问的身份认证&#xff1b; 鉴权&#xff1a;提供 RBAC&#xff08;Role Based Access Control&#xff09; 权限体系&#xff1b; 服务注册与发现&#…

windows系统docker装milvus向量数据库

首先创建一个文件夹比如milvus,在创建如下文件 docker-compose.yml文件如下: version: 3.5services:etcd:container_name: milvus-etcdimage: quay.io/coreos/etcd:v3.5.5environment:- ETCD_AUTO_COMPACTION_MODErevision- ETCD_AUTO_COMPACTION_RETENTION1000- ETCD_QUOTA_B…

Redis重要知识点:哨兵是什么?哨兵如何选择Redis主服务器

引言 哨兵贼简单&#xff0c;就是一个节点去看守领一个节点有没有挂掉&#xff0c;挂掉的数量比较多那得新选主节点了。 1. Redis哨兵 1.1 哨兵作用 哨兵的含义是什么&#xff1f;我们来看看百度百科的解释。 哨兵&#xff0c;汉语词语&#xff0c;是指站岗、放哨、巡逻、稽…

关于less的基本使用

1、介绍及概述 1.1、解释 less 是方便开发人员书写CSS的一门预处理语言。浏览器只认识html /css /js格式的文件&#xff0c;所以直接引入.less文件&#xff0c;没有任何的效果&#xff0c;需要把less文件转换成css文件 1.2、概述 CSS弊端&#xff1a; 没有逻辑性、变量、函…

【Paper Reading】结合 NanoFlow 研究,优化大语言模型服务效率的探索

作者 王伟 PAI引擎团队 近年来&#xff0c;人工智能领域的快速发展推动了大型语言模型的广泛应用&#xff0c;随之而来的是对其服务效率的迫切需求。论文《NanoFlow&#xff1a;Towards Optimal Large Language Model Serving Throughput》提出了一种突破性的新型服务框架&…

刚接触无处下手?水下航行器AUV/UUV六自由度模型/控制器设计matlab/simulink参考代码,基础的/进阶的,入门到顺利毕业/完成课题/发表论文。

导师不管&#xff1f;无人指导&#xff1f;无代码可参考&#xff1f;毫无头绪&#xff1f;换条思路借鉴一下吧&#xff0c;金钱买不到时间&#xff0c;但可以让你更多的支配你自己的时间&#xff0c;没错的&#xff0c;条条大路通罗马&#xff0c;毕竟前程是自己的&#xff0c;…

时序必读论文11|ICLR23 TimesNet时间序列分析的二维变化建模

论文标题&#xff1a;TEMPORAL 2D-VARIATION MODELING FOR GENERAL TIME SERIES ANALYSIS 开源代码&#xff1a;https://github.com/Thinklab-SJTU/Crossformer 前言 时间序列分析中&#xff0c;如何有效地建模时序数据中的时间变化是关键&#xff0c;然而直接从一维时序数据…

css <样式一>

1. 盒子模型 1.1>boarder 在这里插入图片描述 boarder 相邻框合并问题 boarder-classpse 相同的边框会合并在一起 text-alicn center 文字居中对齐 ########### boarder 会撑大盒子的实际大小 一个盒子加了boarder之后会变大的我可以把我的盒子内容进行修改, 减少像素内…

细胞分裂检测系统源码分享

细胞分裂检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…