PyTorch学习之:深入理解神经网络

使用torch.nn模块构建网络架构

在PyTorch中,torch.nn模块是构建神经网络的核心。使用这个模块,你可以轻松地定义网络层、激活函数、损失函数等。以下是使用torch.nn构建一个简单神经网络架构的步骤:

步骤1: 定义网络结构

首先,你需要通过继承nn.Module类来定义你自己的网络结构。在你的类中,你将初始化网络层并定义前向传播路径。这里是一个简单的多层感知器(MLP)网络的例子,它包含两个全连接层:

import torch
from torch import nn
import torch.nn.functional as Fclass SimpleMLP(nn.Module):def __init__(self, input_size, hidden_size, num_classes):super(SimpleMLP, self).__init__()self.fc1 = nn.Linear(input_size, hidden_size)  # 第一个全连接层self.relu = nn.ReLU()                          # 激活函数self.fc2 = nn.Linear(hidden_size, num_classes) # 第二个全连接层def forward(self, x):out = self.fc1(x)out = self.relu(out)out = self.fc2(out)return out

在这个例子中,__init__方法用于初始化网络中的各个层。forward方法定义了数据如何通过这些层流动。注意,我们并没有在forward方法中显式调用softmax函数来进行分类,因为如果你使用的是nn.CrossEntropyLoss作为损失函数,它已经包括了softmax操作。

步骤2: 实例化模型、定义损失函数和优化器

一旦定义了模型结构,接下来需要实例化模型,并定义损失函数和优化器:

model = SimpleMLP(input_size=784, hidden_size=500, num_classes=10)
criterion = nn.CrossEntropyLoss()  # 损失函数
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)  # 优化器

在这里,我们选择了交叉熵损失和Adam优化器。model.parameters()告诉优化器哪些是需要更新的参数。

步骤3: 训练模型

模型训练通常包括前向传播、计算损失、反向传播以及更新模型参数这几个步骤:

for epoch in range(num_epochs):    # 迭代整个数据集多次for i, (inputs, labels) in enumerate(train_loader):  # 从数据加载器获取数据批次# 前向传播outputs = model(inputs)loss = criterion(outputs, labels)# 反向传播和优化optimizer.zero_grad()  # 清除旧的梯度loss.backward()        # 反向传播optimizer.step()       # 更新参数if (i+1) % 100 == 0:   # 每100个批次打印一次状态print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {loss.item():.4f}')

在这个训练循环中,我们首先进行前向传播来计算输出和损失,然后执行反向传播来计算梯度,最后使用优化器来更新权重。

步骤4: 评估模型

模型训练完成后,你可以在测试集上评估模型的性能:

model.eval()  # 设置模型为评估模式
with torch.no_grad():  # 在评估模式下,不计算梯度correct = 0total = 0for inputs, labels in test_loader:outputs = model(inputs)_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print(f'Accuracy of the model on the test images: {100 * correct / total}%')

这里,model.eval()是为了通知网络我们现在处于评估阶段,而torch.no_grad()则是告诉PyTorch在接下来的代码中不需要计算梯度,这样可以节省计算资源和时间。

通过这些步骤,你可以使用torch.nn模块构建、训练并评估一个简单的神经网络。

数据加载器torch.utils.data的使用

在PyTorch中,torch.utils.data是处理数据加载到模型的一个非常重要的模块。它提供了DatasetDataLoader两个核心类,帮助你方便地加载数据、进行批处理和数据打乱,使得数据迭代更加高效、代码更加整洁。

Dataset

Dataset类是一个表示数据集的抽象类。在使用时,你通常需要继承Dataset并实现两个方法:

  • __len__:返回数据集中的数据个数。
  • __getitem__:支持从0到len(self)-1的索引,用于获取第n个样本。

PyTorch已经预先实现了一些常用的数据集类,如torchvision.datasets.ImageFolder用于处理文件夹中的图像数据,你也可以轻松地实现自定义的数据集。

自定义Dataset示例

假设我们有一个关于数字图像和标签的简单数据集,以下是如何实现一个自定义的Dataset类:

from torch.utils.data import Dataset, DataLoader
import torchclass CustomDataset(Dataset):def __init__(self, data, labels, transform=None):self.data = dataself.labels = labelsself.transform = transformdef __len__(self):return len(self.data)def __getitem__(self, idx):item = self.data[idx]label = self.labels[idx]if self.transform:item = self.transform(item)return item, label

在这个例子中,datalabels应当是等长的列表或类似数组的对象,transform是一个可选的参数,用于对数据进行预处理。

DataLoader

DataLoader是一个迭代器,它封装了Dataset,提供了批量处理、打乱数据和多线程加载等功能。使用DataLoader可以让数据加载更加简单、更加灵活。

你可以这样实例化一个DataLoader

dataset = CustomDataset(data, labels, transform=my_transform)
data_loader = DataLoader(dataset, batch_size=4, shuffle=True, num_workers=2)

其中:

  • dataset是一个Dataset对象。
  • batch_size指定了每个批次的大小。
  • shuffle设置为True时,在每个epoch开始时,数据将被打乱(这对于训练模型是非常有用的)。
  • num_workers指定了加载数据时使用的子进程数。增加num_workers可以加速数据加载。

使用DataLoader

一旦你有了DataLoader的实例,你可以简单地迭代它来获取数据批次:

dataset = CustomDataset(data, labels, transform=my_transform)
data_loader = DataLoader(dataset, batch_size=4, shuffle=True, num_workers=2)

这种方式使得在训练循环中处理批量数据变得非常简单和清晰。使用torch.utils.dataDatasetDataLoader,你可以轻松地管理复杂的数据集,利用多线程等优化数据加载过程,从而提高模型训练的效率。

损失函数和优化器的选择和应用

在神经网络训练过程中,损失函数和优化器是两个核心组件。损失函数衡量模型输出与真实标签之间的差异,优化器则负责根据损失函数的梯度更新模型的权重,以最小化损失。

损失函数

损失函数(或代价函数)的选择依赖于具体的任务(如分类、回归等)和模型类型。以下是一些常用的损失函数:

  • 均方误差损失(Mean Squared Error, MSE):通常用于回归任务。计算模型预测值与实际值之间差的平方的平均值。

     
    criterion = torch.nn.MSELoss()
    

  • 交叉熵损失(Cross Entropy Loss):常用于分类任务。对于多分类问题,它计算真实标签的分布和预测标签分布之间的交叉熵。

     
    criterion = torch.nn.CrossEntropyLoss()
    

  • 二进制交叉熵损失(Binary Cross Entropy Loss):用于二分类任务。

     
    criterion = torch.nn.BCELoss()
    

  • 对数似然损失(Negative Log Likelihood Loss, NLLLoss):当模型的最后一层是LogSoftmax时使用。

     
    criterion = torch.nn.NLLLoss()
    

选择合适的损失函数对模型的性能有直接影响。

优化器

优化器用于更新模型的权重以减小损失函数的值。PyTorch提供了多种优化算法,包括但不限于:

  • 随机梯度下降(Stochastic Gradient Descent, SGD):是最基本的优化算法,也可以添加动量(Momentum)来加快收敛。

     
    optimizer = torch.optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
    

  • Adam:结合了AdaGrad和RMSProp算法的优点,对梯度的一阶矩估计(即平均值)和二阶矩估计(即未中心化的方差)进行自适应调整。

     
    optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
    

  • RMSprop:是一种自适应学习率方法,专为处理非平稳目标而设计,对于循环神经网络效果很好。

     
    optimizer = torch.optim.RMSprop(model.parameters(), lr=0.01)
    

应用示例

在每个训练周期(epoch)中,你会对数据集进行迭代,计算损失并使用优化器更新模型的权重。以下是一个简单的训练循环示例:

 
for epoch in range(num_epochs):for inputs, labels in data_loader:# 前向传播outputs = model(inputs)loss = criterion(outputs, labels)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()

  • optimizer.zero_grad()用于清空过往梯度;
  • loss.backward()计算损失的梯度;
  • optimizer.step()根据梯度更新权重。

选择合适的损失函数和优化器,根据任务的不同进行调整,对模型的训练效果和收敛速度至关重要。在实践中,通常需要尝试不同的组合以找到最佳配置。

使用GPU加速模型训练

使用GPU加速模型训练是深度学习中常见的做法,因为相比于CPU,GPU在进行大规模矩阵运算时可以提供显著更快的计算速度,这对于训练大型神经网络模型尤其重要。PyTorch提供了简单而直观的方式来利用GPU进行计算。

检查并使用GPU

首先,你需要检查GPU是否可用,并选择使用GPU还是CPU。这可以通过检查torch.cuda.is_available()来完成:

 
import torch# 检查CUDA是否可用
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

然后,你可以将你的模型和数据移动到选定的设备上:

 
model = model.to(device)

对于数据,每次从数据加载器中获取批数据时,你也需要确保数据被送到正确的设备上:

 
for inputs, labels in data_loader:inputs = inputs.to(device)labels = labels.to(device)

使用多个GPU

如果你有多个GPU,PyTorch可以让你轻松地并行化数据处理来进一步提高训练速度。这可以通过torch.nn.DataParallel来实现,它会自动将你的数据切分并在多个GPU上并行处理:

 
if torch.cuda.device_count() > 1:print(f"Let's use {torch.cuda.device_count()} GPUs!")model = nn.DataParallel(model)model = model.to(device)

优化GPU使用

为了最大化GPU使用效率,你应该注意以下几点:

  • 批大小(Batch Size):增加批大小可以更充分利用GPU,但也要注意不要超出GPU内存。
  • 减少CPU和GPU之间的数据传输:尽量避免在训练循环中频繁地在CPU和GPU之间移动数据。
  • 合理选择数据加载的num_workers参数:在DataLoader中适当增加num_workers的数量可以加快数据加载的速度,减少GPU等待CPU加载数据的时间。

示例:简单的训练循环

下面是一个使用GPU进行训练的简单例子:

 
# 模型和数据移至GPU
model = MyModel().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)# 训练模型
for epoch in range(num_epochs):for i, (inputs, labels) in enumerate(data_loader):inputs = inputs.to(device)labels = labels.to(device)# 前向传播outputs = model(inputs)loss = criterion(outputs, labels)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()if (i+1) % 100 == 0:print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(data_loader)}], Loss: {loss.item():.4f}')

在这个例子中,我们首先将模型和数据移至GPU(如果可用),然后进行正常的训练循环。注意,模型、输入数据、标签和损失函数的计算都应该在同一个设备上进行。

总之,使用GPU可以显著加速你的模型训练,而PyTorch提供的简单API让这个过程变得非常容易。不过,要充分利用GPU的计算能力,还需要对你的模型和数据处理流程进行一些优化。

实践项目

构建并训练一个分类网络模型,如对MNIST数据集进行手写数字识别

构建和训练一个分类网络模型来识别MNIST数据集中的手写数字是机器学习入门的经典项目。这个项目涉及到数据加载、模型构建、训练和评估等多个步骤。以下是一个使用PyTorch实现的完整示例:

步骤1: 导入必要的库

 
import torch
import torchvision
import torchvision.transforms as transforms
from torch import nn, optim
from torch.utils.data import DataLoader
from torchvision.datasets import MNIST

步骤2: 加载和预处理数据

MNIST数据集包含60000个训练样本和10000个测试样本,每个样本是一个28x28的灰度手写数字图像。

 
# 定义数据转换
transform = transforms.Compose([transforms.ToTensor(),  # 转换为Tensortransforms.Normalize((0.5,), (0.5,))  # 归一化
])# 下载并加载训练集和测试集
train_dataset = MNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = MNIST(root='./data', train=False, download=True, transform=transform)train_loader = DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=64, shuffle=False)

步骤3: 定义神经网络模型

我们将构建一个简单的神经网络,包含两个全连接层。

 
class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.fc1 = nn.Linear(28*28, 512)  # 将28*28的图像展平为784,然后连接到512个节点上self.fc2 = nn.Linear(512, 10)  # 输出层有10个节点,对应10个类别def forward(self, x):x = x.view(-1, 28*28)  # 展平图像x = torch.relu(self.fc1(x))x = self.fc2(x)return xmodel = Net()

步骤4: 定义损失函数和优化器

 
criterion = nn.CrossEntropyLoss()  # 使用交叉熵损失函数
optimizer = optim.SGD(model.parameters(), lr=0.01)  # 使用SGD优化器

步骤5: 训练模型

 
num_epochs = 5for epoch in range(num_epochs):for images, labels in train_loader:# 前向传播outputs = model(images)loss = criterion(outputs, labels)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

步骤6: 测试模型

 
model.eval()  # 设置模型为评估模式
with torch.no_grad():  # 在评估模式下,不计算梯度correct = 0total = 0for images, labels in test_loader:outputs = model(images)_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print(f'Accuracy of the model on the 10000 test images: {100 * correct / total}%')

这个简单的神经网络模型就是对MNIST数据集进行手写数字识别的完整流程。通过调整网络结构、增加层数、改变激活函数、优化器、学习率等参数,你可以进一步提高模型的准确率。

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

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

相关文章

STC8H8K64U 学习笔记 - 与上位机通信

与上位机通信 在天问中编程,通过分支判断来接收 PyQt 的传递的信号,进而控制单片机的点灯操作。 环境说明 该内容仅针对我自己学习的开发板做的笔记,在实际开发中需要针对目标电路板的原理图进行针对性研究。 芯片:STC8H8K64U烧录…

C++ 让类只在堆或栈上分配

1. 让类只在栈上或堆上分配内存 在C中,类的对象建立分为两种: 一种是静态建立,如A a; 另一种是动态建立,如A* ptrnew A;这两种方式是有区别的。 1、静态建立类对象:是由编译器为对象在栈空间…

掌握Go语言:Go语言类型转换,无缝处理数据类型、接口和自定义类型的转换细节解析(29)

在Go语言中,类型转换指的是将一个数据类型的值转换为另一个数据类型的过程。Go语言中的类型转换通常用于将一种数据类型转换为另一种数据类型,以满足特定操作或需求。 类型转换的基本语法 在Go语言中,类型转换的基本语法为: ne…

Redis Stack 安装部署

参考:Run Redis Stack on Docker | Redis Redis-stack 初体验_redis stack-CSDN博客 【docker】运行redis_docker run redis-stack-server requirepass-CSDN博客 Redis Stack 是一组软件套件,它主要由三部分组成。 一个是 Redis Stack Server&#x…

艺术点亮新乡村--博罗县“村ART“乡村艺术创作大赛圆满落幕

三月的博罗大地春意盎然,处处洋溢着勃勃生机。在这万物复苏、欣欣向荣的美好时节,一场由农民自编自演、自导自绘的乡村文化盛宴在古朴幽静的徐田村徐徐拉开帷幕。由博罗县委宣传部倾情指导,县文联、文广旅体局、文明办通力合作,泰康保险集团鼎力承办的"村ART"乡村艺术…

AI技术创业:探索无限商机与创新之路

AI技术创业在当前数字化时代呈现出蓬勃发展的态势,为创业者提供了广阔的机会和无限的可能性。随着AI技术的不断进步和应用领域的拓展,从智能家居到自动驾驶,从医疗健康到金融服务,几乎每一个行业都在积极拥抱AI,寻求创…

多功能知识付费源码下载-实现流量互导多渠道变现(带详细安装教程)

资源变现类产品的许多优势,并剔除了那些无关紧要的元素,使得本产品在运营和变现能力方面实现了质的飞跃。多领域素材资源知识变现营销裂变独立版本。 支持:视频、音频、图文、文档、会员、社群、用户发布、创作分成、任务裂变、流量主、在线…

MySQL DBA 需要了解一下 InnoDB Online DDL 算法更新

在 MySQL 8.0.12 中,我们引入了一种新的 DDL 算法,该算法在更改表的定义时不会阻塞表。第一个即时操作是在表格末尾添加一列,这是来自腾讯游戏的贡献。 然后在 MySQL 8.0.29 中,我们添加了在表中任意位置添加(或删除&…

14种建模语言(UML)图形

前言 UML 中有四种关系:依赖、关联、泛化和实现。这四种关系是 UML 模型中可以包含的基本关系事物。这里介绍14种UML图形:类图,对象图,包图,构件图,组合结构图,部署图,制品图,用例图…

sql之每日五题day02--多表联查/聚合函数/多值判断/函数

sql之每日五题day01--多表联查/聚合函数 where和group by同时出现分别查看&结果不去重--union allunion all细节别名case when多值判断数据处理函数 where和group by同时出现 SQL24 统计每个用户的平均刷题数 仅查看山东大学的用户在不同难度下的每个用户的平均答题题目数…

DNDC模型对所有处理的土壤温度和湿度模拟效果良好,但有时土壤湿度模拟存在偏差

使用 DNDC 模型评估加拿大多样化作物轮作系统对产量和 N2O 排放的影响 原名:Assessing the impacts of diversified crop rotation systems on yields and nitrous oxide emissions in Canada using the DNDC model 译名:使用 DNDC 模型评估加拿大多样…

爬虫逆向实战(39)-某某兔装修网登陆(RSA)

一、数据接口分析 主页地址:某某兔装修网 1、抓包 通过抓包可以发现登陆是表单提交 2、判断是否有加密参数 请求参数是否加密? 通过查看“载荷”模块,可以发现有一个val和password的加密参数 请求头是否加密? 无响应是否加密…

vue 实现自定义分页打印 window.print

首先这里是我自定义了打印界面才实现的效果,如果不用自定义界面实现,应该是一样的吧。具体可能需要自己去试试看 我的需求是界面有两个表格,点击全部打印,我需要把第一表格在打印是第1页,第二个表格是第二页 如图&…

大宋咨询(深圳舆情监控)政府舆情调查介绍

公众舆论调查旨在收集和分析普通大众对各种主题和问题的观点、态度和意见,它可以帮助政府部门了解公众的意见和情绪,为政策制定和决策提供参考。这些调查旨在了解人群的集体情绪和偏好,并提供公众舆论的见解。 公众舆论调查可以涵盖广泛的主…

SmartChart的部署以及可能遇见的报错解决方案

简介 数据可视化是一种将数据转化为图形的技术,可以帮助人们更好地理解和分析数据。但是,传统的数据可视化开发往往需要编写大量的代码,或者使用复杂的拖拽工具,不仅耗时耗力,而且难以实现个性化的需求。有没有一种更…

pytorch中的while for 循环 导出onnx的问题

问题: for执行次数不跟据输入而改变。 解决方案: torch.jit.script 例如: class LoopAdd(torch.nn.Module):def __init__(self):super().__init__()def forward(self, x):h xfor i in range(x.size(0)):h h 1return h input_1 torch…

Sora是什么 Sora怎么使用OpenAI最新文字转视频AI模型Sora,一句子生成60秒超逼画面

1. 背景介绍 随着人工智能技术的不断发展,自然语言处理(NLP)和计算机视觉(CV)技术已经取得了显著的进步。近年来,将文本转换为视频的技术逐渐成为研究的热点。OpenAI最新推出的文字转视频AI模型Sora&#…

983. 最低票价 C++

class Solution { public:int mincostTickets(vector<int>& days, vector<int>& costs) {// 状态定义&#xff1a; f[i] 表示 i 天及之后 旅行所需的最小花费int f[366]{};// 标注哪些天 出门for (int v: days) f[v] 1;// 由于状态转移是逆向的 所以倒序 …

号称史上最全的PostgreSQL备份恢复,送给有缘人...

&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&#x1f61c;&#x1f61c; 中国DBA联盟(ACD…