Pytorch 复习总结 2

Pytorch 复习总结,仅供笔者使用,参考教材:

  • 《动手学深度学习》
  • Stanford University: Practical Machine Learning

本文主要内容为:Pytorch 线性神经网络。

本文以机器学习中的两大基本问题 —— 回归和分类为例,介绍线性神经网络的用法。


Pytorch 语法汇总:

  • Pytorch 张量的常见运算、线性代数、高等数学、概率论 部分 见 Pytorch 复习总结1;
  • Pytorch 线性神经网络 部分 见 Pytorch 复习总结2;
  • Pytorch 多层感知机 部分 见 Pytorch 复习总结3;
  • Pytorch 深度学习计算 部分 见 Pytorch 复习总结4;
  • Pytorch 卷积神经网络 部分 见 Pytorch 复习总结5;
  • Pytorch 现代卷积神经网络 部分 见 Pytorch 复习总结6;

目录

  • 一. 线性回归
    • 1. 读取 / 生成数据集
    • 2. 数据迭代器
    • 3. 神经网络模型
    • 4. 损失函数
    • 5. 优化器
    • 6. 训练
  • 二. Softmax 回归
    • 1. 读取数据集
    • 2. 神经网络模型
    • 3. 损失函数
    • 4. 优化器
    • 5. 训练

一. 线性回归

线性回归模型通过建立自变量与因变量之间的线性关系,来解决回归预测问题。涉及数据迭代器、神经网络层、损失函数、优化器等,以 y = X w + b y=Xw+b y=Xw+b 为例。

1. 读取 / 生成数据集

线性回归模型的样本数据包括特征值 X X X 和标签值 y y y。如果数据存储在 .csv 等文件中,可以直接读取:

import csv
import torchdef load_csv_data(filename):features = []labels = []with open(filename, 'r') as csvfile:csv_reader = csv.reader(csvfile)for row in csv_reader:features.append(list(map(float, row[:-1])))labels.append(float(row[-1]))X = torch.tensor(features, dtype=torch.float32)y = torch.tensor(labels, dtype=torch.float32).reshape(-1, 1)return X, yfilename = "path_to_dataset.csv"
features, labels = load_csv_data(filename)

如果想要随机生成数据,可以在特定线性模型上加噪:

def synthetic_data(w, b, num_examples):"""生成y=Xw+b+噪声"""X = torch.normal(0, 1, (num_examples, len(w)))y = torch.matmul(X, w) + by += torch.normal(0, 0.01, y.shape)     # 加噪return X, y.reshape((-1, 1))true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)

2. 数据迭代器

数据迭代器用于迭代访问数据集中的样本,可以将整个数据集按照指定的批量大小划分成小批量。并且在每个 epoch 开始之前重新打乱数据集的样本顺序,然后使用 next() 函数获取下一小批量样本:

from torch.utils import datadef load_array(data_arrays, batch_size, is_train=True):"""构造一个PyTorch数据迭代器"""dataset = data.TensorDataset(*data_arrays)return data.DataLoader(dataset, batch_size, shuffle=is_train)batch_size = 10
data_iter = load_array((features, labels), batch_size)
# print(next(iter(data_iter)))

上述示例中,数据迭代器将 1000 组训练数据分成 100 批,每批包含 10 组训练数据。

3. 神经网络模型

神经网络模型可以使用顺序模型容器 nn.Sequential() 将多个网络层按顺序连接:

from torch import nnnet = nn.Sequential(nn.Linear(2, 64),nn.ReLU(),nn.Linear(64, 32),nn.ReLU(),nn.Linear(32, 1)
)

神经网络的线性层(也叫全连接层)初始化时需要分别初始化权重和偏置:

net[0].weight.data.normal_(0, 0.01)
net[0].bias.data.fill_(0)
net[2].weight.data.normal_(0, 0.01)
net[2].bias.data.fill_(0)
net[4].weight.data.normal_(0, 0.01)
net[4].bias.data.fill_(0)

网络层还可以添加卷积层、循环层、批量归一化层:

# 卷积层
conv_layer = nn.Conv2d(2, 32, 3)
conv_layer.weight.data.normal_(0, 0.01)
conv_layer.bias.data.fill_(0)
# 循环层
lstm_layer = nn.LSTM(2, 16)
lstm_layer.weight_ih_l0.data.normal_(0, 0.01)   # 输入到隐藏层的权重
lstm_layer.weight_hh_l0.data.normal_(0, 0.01)   # 隐藏层到隐藏层的权重
lstm_layer.bias_ih_l0.data.fill_(0)             # 输入到隐藏层的偏置
lstm_layer.bias_hh_l0.data.fill_(0)             # 隐藏层到隐藏层的偏置
# 批量归一化层
batchnorm_layer = nn.BatchNorm2d(8)
batchnorm_layer.weight.data.fill_(1)
batchnorm_layer.bias.data.fill_(0)

4. 损失函数

训练神经网络模型时,通常会将模型的输出与真实标签计算损失值,并通过反向传播算法来更新模型的参数,以最小化损失函数。以均方误差为例:

loss = nn.MSELoss()

数学表达式如下,这里除以 2 是为了求导后的简洁美观:
L ( w , b ) = 1 n ∑ i = 1 n 1 2 ( w ⊤ x ( i ) + b − y ( i ) ) 2 L(\mathbf{w}, b)=\frac{1}{n} \sum_{i=1}^n \frac{1}{2}\left(\mathbf{w}^{\top} \mathbf{x}^{(i)}+b-y^{(i)}\right)^2 L(w,b)=n1i=1n21(wx(i)+by(i))2

除了均方误差,还可以使用交叉熵损失函数 nn.CrossEntropyLoss、二元交叉熵损失函数 nn.BCELoss、多标签二元交叉熵损失函数 nn.BCEWithLogitsLoss、KL 散度损失函数 nn.KLDivLoss、Hinge 损失函数 nn.HingeEmbeddingLoss、Triplet 损失函数 nn.TripletMarginLoss、余弦相似度损失函数 nn.CosineEmbeddingLoss 等。

5. 优化器

训练神经网络模型时,使用优化器根据损失函数的梯度信息来更新模型的参数,可以使用 net.parameters() 获取模型所以参数。一般都会使用随机梯度下降进行优化:

trainer = torch.optim.SGD(net.parameters(), lr=0.03)

使用优化器更新模型参数时,一般都会使用 小批量随机梯度下降 (minibatch stochastic gradient descent, mini-batch SGD)。更新梯度时,将梯度乘以学习率 η \eta η,再除以批量大小 ∣ B ∣ |\mathcal{B}| B,然后从当前参数的值中减掉:
( w , b ) ← ( w , b ) − η ∣ B ∣ ∑ i ∈ B ∂ ( w , b ) l ( i ) ( w , b ) (\mathbf{w}, b) \leftarrow(\mathbf{w}, b)-\frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \partial_{(\mathbf{w}, b)} l^{(i)}(\mathbf{w}, b) (w,b)(w,b)BηiB(w,b)l(i)(w,b)

以线性回归的损失函数 L ( w , b ) L(\mathbf{w}, b) L(w,b) 为例,将 w \mathbf{w} w b b b 的优化更新表达式展开如下:
w ← w − η ∣ B ∣ ∑ i ∈ B ∂ w l ( i ) ( w , b ) = w − η ∣ B ∣ ∑ i ∈ B x ( i ) ( w ⊤ x ( i ) + b − y ( i ) ) b ← b − η ∣ B ∣ ∑ i ∈ B ∂ b l ( i ) ( w , b ) = b − η ∣ B ∣ ∑ i ∈ B ( w ⊤ x ( i ) + b − y ( i ) ) \mathbf{w} \leftarrow \mathbf{w}-\frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \partial_{\mathbf{w}} l^{(i)}(\mathbf{w}, b)=\mathbf{w}-\frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \mathbf{x}^{(i)}\left(\mathbf{w}^{\top} \mathbf{x}^{(i)}+b-y^{(i)}\right)\\ b \leftarrow b-\frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \partial_b l^{(i)}(\mathbf{w}, b)=b-\frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}}\left(\mathbf{w}^{\top} \mathbf{x}^{(i)}+b-y^{(i)}\right) wwBηiBwl(i)(w,b)=wBηiBx(i)(wx(i)+by(i))bbBηiBbl(i)(w,b)=bBηiB(wx(i)+by(i))

6. 训练

在训练的每一轮 epoch 迭代中,遍历数据迭代器划分的小批量训练数据,每次获取一个小批量的输入和相应的标签。对于每一个小批量,使用网络模型预测标签并计算损失,然后反向传播来计算梯度,最后通过调用优化器来更新模型参数:

num_epochs = 3
for epoch in range(num_epochs):     # 迭代训练轮次for X, y in data_iter:          # 迭代小批量l = loss(net(X) ,y)trainer.zero_grad()         # 清除优化器中的梯度信息l.backward()                # 根据损失自动计算梯度trainer.step()              # 根据梯度信息和学习率更新模型参数l = loss(net(features), labels)print(f'epoch {epoch + 1}, loss {l:f}')

二. Softmax 回归

Softmax 回归是一种多类别分类模型。在 Softmax 回归模型中,计算输入特征对应的每个类别的分数,然后通过 Softmax 函数将这些分数转换为对应每个类别的概率值。

1. 读取数据集

以 Fashion-MNIST 数据集为例,读取 Fashion-MNIST 数据集并将其加载到内存中,返回训练集和验证集的数据迭代器:

import torch
import torchvision
from torch.utils import data
from torchvision import transformsdef load_data_fashion_mnist(batch_size, resize=None):"""下载Fashion-MNIST数据集并将其加载到内存中"""trans = [transforms.ToTensor()]if resize:trans.insert(0, transforms.Resize(resize))trans = transforms.Compose(trans)mnist_train = torchvision.datasets.FashionMNIST(root="./data", train=True, transform=trans, download=True)mnist_test = torchvision.datasets.FashionMNIST(root="./data", train=False, transform=trans, download=True)return (data.DataLoader(mnist_train, batch_size, shuffle=True),data.DataLoader(mnist_test, batch_size, shuffle=False))batch_size = 256
train_iter, test_iter = load_data_fashion_mnist(batch_size)
# for X, y in train_iter:
#     print(X.shape, X.dtype, y.shape, y.dtype)

2. 神经网络模型

Softmax 回归的输出层是一个全连接层,因此在 Sequential 中添加一个带有 10 个输出的全连接层:

from torch import nn
net = nn.Sequential(nn.Flatten(),nn.Linear(784, 10)
)

这里使用展平层 nn.Flatten() 将输入的图片展平为一维张量,以适应后面全连接层的输入要求。因为 Fashion-MNIST 中每张图片的大小为 28×28,所以展平层的输出维度为 784,所以全连接层的输入维度也是 784。

然后需要初始化模型,将 init_weights() 函数应用到模型的每个子模块上,按正态分布初始化所有全连接层的权重:

def init_weights(m):if type(m) == nn.Linear:nn.init.normal_(m.weight, std=0.01)net.apply(init_weights)

3. 损失函数

loss = nn.CrossEntropyLoss(reduction='none')

4. 优化器

trainer = torch.optim.SGD(net.parameters(), lr=0.1)

5. 训练

为了计算模型的分类精度,事先定义 accuracy(y_hat, y) 函数计算网络的预测标签 y_hat 的正确预测数量。y_hat.argmax(axis=1) 返回预测标签 y_hat 每一行最大值所在的索引,然后类型转换后与真实标签 y 比较得到布尔型数组,相加即可得到正确预测数量:

def accuracy(y_hat, y):"""计算预测正确的数量"""if len(y_hat.shape) > 1 and y_hat.shape[1] > 1:y_hat = y_hat.argmax(axis=1)cmp = y_hat.type(y.dtype) == yreturn float(cmp.type(y.dtype).sum())

然后就可以训练:

num_epochs = 10for epoch in range(num_epochs):     # 迭代训练轮次net.train()                     # 将模型设置为训练模式train_loss_sum = 0.0            # 训练损失总和train_acc_sum = 0.0             # 训练准确度总和sample_num = 0                  # 样本数for X, y in train_iter:y_hat = net(X)l = loss(y_hat, y)trainer.zero_grad()l.mean().backward()trainer.step()train_loss_sum += l.sum()train_acc_sum += accuracy(y_hat, y)sample_num += y.numel()train_loss = train_loss_sum / sample_numtrain_acc = train_acc_sum / sample_numnet.eval()                      # 将模型设置为评估模式test_acc_sum = 0.0test_sample_num = 0for X, y in test_iter:test_acc_sum += accuracy(net(X), y)test_sample_num += y.numel()test_acc = test_acc_sum / test_sample_numprint(f'epoch {epoch + 1}, 'f'train loss {train_loss:.4f}, train acc {train_acc:.4f}, 'f'test acc {test_acc:.4f}')

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

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

相关文章

【数据结构初阶 6】二叉树:堆的基本操作 + 堆排序的实现

文章目录 🌈 Ⅰ 二叉树的顺序结构🌈 Ⅱ 堆的概念与性质🌈 Ⅲ 堆的基本操作01. 堆的定义02. 初始化堆03. 堆的销毁04. 堆的插入05. 向上调整堆06. 堆的创建07. 获取堆顶数据08. 堆的删除09. 向下调整堆10. 判断堆空 🌈 Ⅳ 堆的基本…

【selenium】八大元素定位方式|xpath css id name...

目录 一、基础元素定位 二、cssSelector元素定位——通过元素属性定位 三、xpath元素定位——通过路径 1 、xpath绝对定位 (用的不多) 缺点:一旦页面结构发生变化(比如重新设计时,路径少两节)&#x…

从计网的角度讲明白什么是网关

网关(Gateway)又称网间连接器、协议转换器。网关在传输层上以实现网络互连,是最复杂的网络互连设备,仅用于两个高层协议不同的网络互连。网关的结构也和路由器类似,不同的是互连层。网关既可以用于广域网互连,也可以用于局域网互连…

JDBC实现连接池

简单上手 使用 JDBC 来执行 SQL 查询和更新操作 import java.sql.*;public class Main {public static void main(String[] args) {String url "jdbc:mysql://localhost:3306/your_database_name";String username "your_username";String password &…

vs2015零基础编译zlib从失败到成功

本博文源于笔者不断尝试从0编译zlib到能够将文件打包成zip的一个简单过程,其中包含了如何下载zlib,如何编译zlib,如何使用zlib等。内容堪比教科书级别,可以收藏,可以自用,希望博文能帮助到读者。 1、下载z…

Protocol Buffers v21.12 安装 ( linux 系统 )

下载 Protocol Buffers v21.12 Protocol Buffers v21.12 解压 tar zxvf protobuf-cpp-3.21.12.tar.gz执行 进入解压目录,执行下面configure可执行程序,目的是监测安装环境,生成makefile ./configure执行完后可以检查是否生成makefile文件 构…

Unity单元测试

Unity单元测试是一个专门用于嵌入式单元测试的库, 现在简单讲下移植以及代码结构. 源码地址: GitHub - ThrowTheSwitch/Unity: Simple Unit Testing for C 1.我们只需要移植三个文件即可: unity.c, unity.h, unity_internals.h 2.然后添加需要测试的函数. 3.在main.c中添加…

Swift基础知识:23.Swift析构过程

在 Swift 中,析构过程是指在一个类的实例被释放之前进行的清理操作。通常,这些清理操作包括释放实例所持有的资源、取消订阅通知、关闭文件等。Swift 使用析构器(deinitializer)来实现析构过程,它类似于构造器&#xf…

公司文件防泄密管理系统

公司文件防泄密管理系统是一种综合性的解决方案,旨在确保企业文件的安全性和保密性,防止内部员工或外部攻击者非法获取、泄露或篡改敏感信息。 PC端:https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 以下是关于…

【JavaEE】_form表单构造HTTP请求

目录 1. form表单的格式 1.1 form表单的常用属性 1.2 form表单的常用搭配标签:input 2. form表单构造GET请求实例 3. form表单构造POST请求实例 4. form表单构造法的缺陷 对于客户端浏览器,以下操作即构造了HTTP请求: 1. 直接在浏览器…

IDM下载器2024中文版主要功能、使用场景、优点、缺点介绍

软件分析师眼中的IDM(Internet Download Manager) IDM绿色下载如下: https://wm.makeding.com/iclk/?zoneid34275 一、主要功能 高速下载:利用多线程技术和文件分块下载策略,显著提高下载速度。断点续传:即使在下载…

【Linux】MySQL数据库的使用

【Linux】MySQL数据库的使用 一、访问MySQL数据库二、创建及删除库和表1、创建新的库2、创建新的表3、删除一个数据表4、删除一个数据库 三、管理表中的数据记录1、插入数据记录2、查询数据记录3、修改数据记录4、删除数据记录 四、数据库用户授权1、授予权限2、查看权限3、撤销…

db-gpt docker部署进坑

1.docker 不支持gpu,参考之前文章 2.docker 容器启动就关闭,docker ps -a 查看容器状态为exited 停止 定位问题: (1) 查看日志 docker logs dbgpt -f (2) 日志错误最后一行: V…

《图解HTTP》笔记1:http的诞生

1,http的诞生: 1.1 为共享知识而生 我们现在使用web(World Wide Web的简称,即万维网)浏览器,目前可以输入一个网址(http://www.baidu.com),就会有一个网页显示出来。 最开始设想出…

jenkins远程触发构建报:Error 403 No valid crumb was included in the request

最近在跨jenkins触发构建的时候发现不能触发相应的项目,报如下图错误 解决方案: 1、安装Build Authorization Token Root Plugin插件 安装完成后去配置API Token,用户列表,配置用户的API Token,生成后记得保存 2、项…

YOLOv9来啦!YOLO目标检测全新工作!性能表现SOTA!在各个方面都大大超过了RT-DETR、YOLOv8等

摘要 今天的深度学习方法侧重于如何设计最合适的目标函数,使模型的预测结果最接近实际情况。同时,必须设计一种适当的架构,该架构可以促进获取足够的信息用于预测。现有的方法忽略了一个事实,即当输入数据经过逐层特征提取和空间…

NXP实战笔记(五):S32K3xx基于RTD-SDK在S32DS上配置ADC的硬件触发同步采样与软件采样过程

目录 1、概述 1.1、软件触发 1.2、硬件触发 - BCTU 1.3、硬件触发 - TRGMUX 1.4、ADC的校准 1.5、ADC时钟配置 2、BTCU硬件触发ADC的SDK配置 3、软件触发ADC 3.1、选择相应Port作为ADC的输入 3.2、ADC配置 3.3、代码示例 1、概述 恩智浦 S32K3xx 系列汽车微控制器…

【Linux】再谈进程地址空间

目录 一、引入 二、物理内存和外设空间的交互 三、解决页表过大问题 一、引入 我们在往期的博客中有讲解过进程地址空间:【Linux】进程地址空间 但是在上述博客中我们只是对进程地址空间的左边部分详细进行了讲解,下面我们就来谈谈右边的部分&#…

第3.6章:StarRocks数据导入——DataX StarRocksWriter

一、Datax 1.1 DataX 3.0概述 DataX3.0是一个异构数据源离线同步工具,可以方便的对各种异构数据源进行高效的数据同步。 其github地址为: https://github.com/alibaba/DataX/blob/master/introduction.mdhttps://github.com/alibaba/DataX/blob/mast…

盘点那些世界名校计算机专业采用的教材

清华、北大、MIT、CMU、斯坦福的学霸们在新学期里要学什么?今天我们来盘点一下那些世界名校计算机专业采用的教材。 书单目录 1.《深入理解计算机系统》(原书第3版)2. 《算法导论》(原书第3版)3. 《计算机程序的构造和…