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

PyTorch(六)优化模型参数

#c 目的 优化的目的

已经拥有了一个「模型」和「数据」,是时候通过「优化模型参数」来训练、验证和测试模型。

#d 迭代训练

训练模型是一个迭代过程;在每次迭代中,模型对输出做出猜测,计算其猜测的误差(损失),收集误差相对于其参数的导数,并使用「梯度下降」来优化这些参数。

1 超参数(Hyperparameters)

#d 超参数

超参数(Hyperparameters)是可调节的参数,它们允许你「控制模型优化过程」。不同的超参数值可能会影响模型的训练和收敛速率。

#e 超参数定义例子 超参数

周期数(Epochs):迭代数据集的次数。
批量大小(Batch Size):在更新参数之前通过网络传播的数据样本数量。
学习率(Learning Rate):在每个批量/周期中更新模型参数的程度。较小的值会导致学习速度慢,而较大的值可能会导致训练过程中出现不可预测的行为。

learning_rate = 1e-3
batch_size = 64
epochs = 5

2 优化循环,损失函数,优化器

#d 优化循环

一旦设置了超参数,就可以通过优化循环来训练和优化模型。优化循环的每一次迭代称为一个「周期(Epoch)」。

每个「周期」由两个主要部分组成:

  1. 训练循环(Train Loop):遍历训练数据集,尝试收敛到最优参数。
  2. 验证/测试循环(Validation/Test Loop):遍历测试数据集,以检查模型性能是否在提高。

#d 损失函数作用

当提供一些训练数据时,未经训练的网络很可能无法给出正确的答案。
「损失函数」衡量了所得「结果」与「目标值」之间的不相似程度,而在训练过程中,希望最小化的就是这个损失函数。为了计算损失,使用给定数据样本的输入进行预测,并将其与真实的数据标签值进行比较。

#e 常见损失函数 损失函数的作用

nn.MSELoss(均方误差):用于回归任务。
nn.NLLLoss(负对数似然损失):用于分类任务。
nn.CrossEntropyLoss:结合了nn.LogSoftmax和nn.NLLLoss的功能。
将模型的输出(logits)传递给nn.CrossEntropyLoss,它将对logits进行归一化并计算预测误差。

loss_fn = nn.CrossEntropyLoss()#初始化损失函数

#d 优化器作用

优化器(Optimizer)是「调整模型参数」以减少每个训练步骤中的「模型误差」的过程。优化算法定义了这个过程是如何执行的。所有的优化逻辑都被封装在优化器optimizer对象中。在PyTorch中还有许多不同的优化器可用,例如ADAM和RMSProp,它们对不同类型的模型和数据有更好的效果。

#e SGD(随机梯度下降) 优化器作用

通过注册需要训练的模型参数,并传入学习率超参数来初始化优化器。

optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)#初始化优化器

#d 优化器作用位置

在训练循环中,优化发生在三个步骤中:

  1. 梯度清零:调用optimizer.zero_grad()来重置模型参数的梯度。梯度默认情况下是累加的;为了防止重复计算,在每次迭代中明确地将它们清零。

  2. 反向传播:通过调用loss.backward()对预测损失进行反向传播。PyTorch会计算损失相对于每个参数的梯度。

  3. 参数更新:一旦有了梯度,就调用optimizer.step()根据反向传播过程中收集的梯度来调整参数。

这个过程确保了模型在每次迭代中都能朝着减少损失的方向更新参数。

3 完整过程

定义循环优化代码的train_loop,以及根据测试数据评估模型性能的test_loop。

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambda# 加载数据集
training_data = datasets.FashionMNIST(root="data",train=True,download=True,transform=ToTensor()
)test_data = datasets.FashionMNIST(root="data",train=False,download=True,transform=ToTensor()
)# 创建数据加载器
train_dataloader = DataLoader(training_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)
# 创建模型
class NeuralNetwork(nn.Module):def __init__(self):super(NeuralNetwork, self).__init__()self.flatten = nn.Flatten()self.linear_relu_stack = nn.Sequential(nn.Linear(28*28, 512),nn.ReLU(),nn.Linear(512, 512),nn.ReLU(),nn.Linear(512, 10),nn.ReLU())def forward(self, x):x = self.flatten(x)logits = self.linear_relu_stack(x)return logitsmodel = NeuralNetwork()def train_loop(dataloader, model, loss_fn, optimizer):size = len(dataloader.dataset)#数据集的大小model.train()#设置模型为训练模式for batch, (X, y) in enumerate(dataloader):pred = model(X)#前向传播loss = loss_fn(pred, y)# 反向传播loss.backward()optimizer.step()#参数更新optimizer.zero_grad()#梯度清零if batch % 100 == 0:#每100个批次打印一次loss, current = loss.item(), batch * len(X)print(f"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]")def test_loop(dataloader, model, loss_fn):model.eval()#设置模型为评估模式size = len(dataloader.dataset)#数据集的大小test_loss, correct = 0, 0#测试损失和正确数num_batches = len(dataloader)#批次数with torch.no_grad():#关闭梯度跟踪for X, y in dataloader:pred = model(X)#前向传播test_loss += loss_fn(pred, y).item()#计算损失correct += (pred.argmax(1) == y).type(torch.float).sum().item()#计算正确数test_loss /= num_batches#计算平均损失correct /= size#计算正确率print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")'''
初始化损失函数和优化器,并将其传递给train_loop和test_loop。随意增加轮数以跟踪模型的改进性能。
'''
loss_fn = nn.CrossEntropyLoss()#初始化损失函数
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)#初始化优化器
epochs = 10#周期数for t in range(epochs):print(f"Epoch {t+1}\n-------------------------------")train_loop(train_dataloader, model, loss_fn, optimizer)test_loop(test_dataloader, model, loss_fn)
print("Done!")

相关文章:

  • 2.2.5 C#中显示控件BDPictureBox 的实现----ROI交互续2
  • Golang中defer和return顺序
  • LabVIEW幅频特性测试系统
  • 前端工程化08-新的包管理工具pnpm
  • python系列30:各种爬虫技术总结
  • MySQL增删改查
  • Java Nio核心概念理解
  • 关于 Mybatis 的开启二级缓存返回对象不一致问题
  • 嵌入式PCB制图面试题及参考答案(2万字长文)
  • 【融合ChatGPT等AI模型】Python-GEE遥感云大数据分析、管理与可视化及多领域案例应用
  • 【2024德国签证】去德国读博士需要申请什么签证?
  • Spire.PDF for .NET【文档操作】演示:以特定的缩放比例/百分比打开 PDF 文件
  • 力扣习题--哈沙德数
  • Redis Stream Redisson Stream
  • Cube-Studio:开源大模型全链路一站式中台
  • [nginx文档翻译系列] 控制nginx
  • Linux Process Manage
  • MySQL用户中的%到底包不包括localhost?
  • Object.assign方法不能实现深复制
  • Promise面试题2实现异步串行执行
  • Python 反序列化安全问题(二)
  • Python学习之路16-使用API
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • 使用权重正则化较少模型过拟合
  • 手机端车牌号码键盘的vue组件
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 一个完整Java Web项目背后的密码
  • 一些关于Rust在2019年的思考
  • 3月27日云栖精选夜读 | 从 “城市大脑”实践,瞭望未来城市源起 ...
  • #define MODIFY_REG(REG, CLEARMASK, SETMASK)
  • (13)Hive调优——动态分区导致的小文件问题
  • (C++)八皇后问题
  • (Python) SOAP Web Service (HTTP POST)
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (四) 虚拟摄像头vivi体验
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (转)平衡树
  • .NET 4.0中的泛型协变和反变
  • .NET CORE 第一节 创建基本的 asp.net core
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .NET中 MVC 工厂模式浅析
  • @Transactional类内部访问失效原因详解
  • [2016.7.test1] T2 偷天换日 [codevs 1163 访问艺术馆(类似)]
  • [30期] 我的学习方法
  • [52PJ] Java面向对象笔记(转自52 1510988116)
  • [Android]使用Retrofit进行网络请求
  • [BROADCASTING]tensor的扩散机制
  • [BUG] Hadoop-3.3.4集群yarn管理页面子队列不显示任务
  • [bzoj2957]楼房重建
  • [cb]UIGrid+UIStretch的自适应
  • [HTML]Web前端开发技术18(HTML5、CSS3、JavaScript )HTML5 基础与CSS3 应用——喵喵画网页
  • [IE技巧] 如何关闭Windows Server版IE的安全限制
  • [kubernetes]控制平面ETCD