【第十四周】PyTorch深度学习实践1

news2024/9/29 14:04:00

目录

  • 摘要
  • Abstract
  • 1.反向传播
  • 2.线性回归
    • 2.1.准备数据集
    • 2.2.设计模型
    • 2.3.定义损失函数和优化器
    • 2.4.模型训练
  • 3.逻辑回归
  • 4.处理多维特征的输入
  • 5.加载数据集
    • 5.1.导入必要的库
    • 5.2.准备数据集
    • 5.3.定义模型
    • 5.4.构建损失函数和优化器
    • 5.5.训练模型
  • 总结

摘要

本周主要通过B站刘二大人的视频对 PyTorch 进行实践学习,了解了PyTorch 中各个常用的类以及方法,学习了搭建神经网络的四个步骤,为后面手动复现模型提供了实践基础。其中,最重要的是学习到了看文档的能力,对于新学习到的类和方法能够通过查询文档去理解用法和作用。

Abstract

This week, I mainly focused on practical learning with PyTorch, understanding the various commonly used classes and methods within it. I learned the four steps to building a neural network, which provided a practical foundation for manually reproducing models in the future. Most importantly, I developed the ability to read documentation, allowing me to understand the usage and function of newly learned classes and methods by consulting the documentation.

本周学习内容来自于《PyTorch深度学习实践》完结合集 1~8课

参考资料来自于PyTorch 英文文档

1.反向传播

在这里插入图片描述
对于简单的线性模型可以通过解析式来求对参数的导数。

在这里插入图片描述
一个复杂的神经网络中含有成千上百个参数,分别对这些参数求解析是一个很繁重的任务,因此我们需要一个新的办法——反向传播算法

在这里插入图片描述
线性函数叠加之后总是可以化简成 W ⋅ X + b W·X+b WX+b的形式,这样子多层叠加就没有意义了,所以要在每一层的结果处加上一个非线性函数。

在这里插入图片描述
前馈过程求解中间值和局部导数,反向传播过程求解对各个参数的偏导。

在这里插入图片描述
PyTorch中 Tensor(张量)包含两个成员,一个是保存参数的 Data,一个是保存导数的 Grad。同样这两个成员也是 Tensor。

torch.Tensor 和 torch.tensor的区别

代码如下:

import torch

x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]

# 创建一个 Tensor 类型,方便求梯度
w = torch.tensor([1.0])    
w.requires_grad = True      

# 前向传播
def forward(x):
    return x * w

# 计算损失,创建计算图
def loss(x, y):
    y_pred = forward(x)
    return (y_pred - y) ** 2


print("predict before training", 4, forward(4).item())

for epoch in range(100):
    for x, y in zip(x_data, y_data):   # 选择一个样本更新梯度值
        l = loss(x, y)
        l.backward()
        print('\tgrad:', x, y, w.grad.item())
        w.data = w.data - 0.01 * w.grad.data

        # 每次更新完梯度要清除梯度
        w.grad.data.zero_()

    print("progress:", epoch, l.item())

print("predict after training", 4, forward(4).item())

结果如下:

在这里插入图片描述

2.线性回归

在这里插入图片描述
神经网络模型的搭建遵循上图的四个流程。

2.1.准备数据集

x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]

2.2.设计模型

在这里插入图片描述

定义 LinearModel 类

class LinearModel(torch.nn.Module):

这里定义了一个名为 LinearModel 的类,它继承自 torch.nn.Module。torch.nn.Module 是所有神经网络模块的基类,包含了一些有用的属性和方法,用于管理模型参数、前向传播等。

def __init__(self):
    super(LinearModel, self).__init__()
    self.linear = torch.nn.Linear(1, 1)
  • _init_ 方法是 Python 中类的构造函数,当创建类的实例时会自动调用。
  • super(LinearModel, self).init() 调用了父类 torch.nn.Module 的构造函数,这是必要的步骤,以确保父类能够正确地初始化。
  • self.linear = torch.nn.Linear(1, 1) 创建了一个线性层(全连接层),输入维度为1,输出维度也为1。这意味着该模型将接受一个标量作为输入,并产生一个标量作为输出。

前向传播

def forward(self, x):
    y_pred = self.linear(x)
    return y_pred
  • forward 方法定义了模型的前向传播逻辑,即如何从输入数据 x 计算出输出 y_pred。
  • self.linear(x) 使用之前定义的线性层对输入 x 进行变换。
  • return y_pred 返回前向传播的结果,即预测值 y_pred。

2.3.定义损失函数和优化器

在这里插入图片描述
定义损失和优化器

criterion = torch.nn.MSELoss(size_average=False)
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

model.parameters() 返回模型中所有需要优化的参数。

2.4.模型训练

在这里插入图片描述

for epoch in range(100):
    y_pred = model(x_data)
    loss = criterion(y_pred, y_data)
    print(epoch, loss.item())
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

print('w = ', model.linear.weight.item())
print('b = ', model.linear.bias.item())

x_test = torch.tensor([[4.0]])
y_test = model(x_test)
print('y_pred = ', y_test.data)

结果如下:
在这里插入图片描述

3.逻辑回归

在这里插入图片描述
在这里插入图片描述
为什么交叉熵可以衡量两个分布的差异呢?
交叉熵 H ( P , Q ) H(P,Q) H(P,Q) 可以理解为使用概率分布 Q Q Q编码来自概率分布P的数据所需的平均比特数。具体来说:如果 P ( x ) P(x) P(x) Q ( x ) Q(x) Q(x) 完全相同,即 P ( x ) = Q ( x ) P(x)=Q(x) P(x)=Q(x),那么 H ( P , Q ) H(P,Q) H(P,Q) 等于 H ( P ) H(P) H(P),也就是真实分布的熵。如果 P ( x ) P(x) P(x) Q ( x ) Q(x) Q(x) 不同,那么 H ( P , Q ) H(P,Q) H(P,Q) 会大于 H ( P ) H(P) H(P),因为使用不准确的概率分布Q来编码数据会导致更多的冗余信息,从而需要更多的比特数。

在这里插入图片描述

代码如下:

import torch
import torch.nn.functional as F

# prepare dataset
x_data = torch.Tensor([[1.0], [2.0], [3.0]])
y_data = torch.Tensor([[0], [0], [1]])


# design model using class
class LogisticRegressionModel(torch.nn.Module):
    def __init__(self):
        super(LogisticRegressionModel, self).__init__()
        self.linear = torch.nn.Linear(1, 1)

    def forward(self, x):
        y_pred = F.sigmoid(self.linear(x))
        return y_pred


model = LogisticRegressionModel()

# construct loss and optimizer
# 默认情况下,loss会基于element平均,如果size_average=False的话,loss会被累加。
criterion = torch.nn.BCELoss(size_average=False)
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

# training cycle forward, backward, update
for epoch in range(1000):
    y_pred = model(x_data)
    loss = criterion(y_pred, y_data)
    print(epoch, loss.item())

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

print('w = ', model.linear.weight.item())
print('b = ', model.linear.bias.item())

x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print('y_pred = ', y_test.data)

结果如下:

在这里插入图片描述

4.处理多维特征的输入

在这里插入图片描述

上图为预测一个人在一年之后糖尿病病情加重概率的例子,这时每个样本会有八个不同的特征,通过八个不同的特征来预测是否病情会加重。
在这里插入图片描述
对于多维的特征输入我们需要把每一个特征x乘以相应的权重。在进行逻辑回归时,把每一个维度的x乘相应的权值的和加上一个偏置量。然后再把每个样本的式子写成矩阵乘法的形式。

import numpy as np
import torch
import matplotlib.pyplot as plt
 
# prepare dataset
xy = np.loadtxt('diabetes.csv', delimiter=',', dtype=np.float32)
x_data = torch.from_numpy(xy[:, :-1]) # 第一个‘:’是指读取所有行,第二个‘:’是指从第一列开始,最后一列不要
y_data = torch.from_numpy(xy[:, [-1]]) # [-1] 最后得到的是个矩阵
 
# design model using class
 
 
class Model(torch.nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.linear1 = torch.nn.Linear(8, 6) # 输入数据x的特征是8维,x有8个特征
        self.linear2 = torch.nn.Linear(6, 4)
        self.linear3 = torch.nn.Linear(4, 1)
        self.sigmoid = torch.nn.Sigmoid() # 将其看作是网络的一层,而不是简单的函数使用
 
    def forward(self, x):
        x = self.sigmoid(self.linear1(x))
        x = self.sigmoid(self.linear2(x))
        x = self.sigmoid(self.linear3(x)) # y hat
        return x
 
 
model = Model()
 
# construct loss and optimizer
# criterion = torch.nn.BCELoss(size_average = True)
criterion = torch.nn.BCELoss(reduction='mean')  
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
 
epoch_list = []
loss_list = []
# training cycle forward, backward, update
for epoch in range(100):
    y_pred = model(x_data)
    loss = criterion(y_pred, y_data)
    print(epoch, loss.item())
    epoch_list.append(epoch)
    loss_list.append(loss.item())
 
    optimizer.zero_grad()
    loss.backward()
 
    optimizer.step()
 
 
plt.plot(epoch_list, loss_list)
plt.ylabel('loss')
plt.xlabel('epoch')
plt.show()

torch.sigmoid、torch.nn.Sigmoid和torch.nn.functional.sigmoid的区别

结果如下:
在这里插入图片描述

在这里插入图片描述

5.加载数据集

5.1.导入必要的库

import torch
import numpy as np
from torch.utils.data import Dataset
from torch.utils.data import DataLoader

5.2.准备数据集

class DiabetesDataset(Dataset):
    def __init__(self, filepath):
        xy = np.loadtxt(filepath, delimiter=',', dtype=np.float32)
        self.len = xy.shape[0]
        self.x_data = torch.from_numpy(xy[:, :-1])
        self.y_data = torch.from_numpy(xy[:, [-1]])

    def __getitem__(self, index):
        return self.x_data[index], self.y_data[index]

    def __len__(self):
        return self.len
  • DiabetesDataset 继承自 Dataset 类,其中 Dataset 是抽象类,不可被实例化。
  • _init_ 方法:
    读取CSV文件并将其转换为NumPy数组。
    self.len 存储数据集的样本数量。
    self.x_data存储特征数据,self.y_data 存储标签数据。
  • _getitem_ 方法:
    返回指定索引处的特征和标签。
  • _len_ 方法:
    返回数据集的长度(样本数量)。

创建数据加载器

dataset = DiabetesDataset('diabetes.csv')
train_loader = DataLoader(dataset=dataset, batch_size=32, shuffle=True, num_workers=0)

5.3.定义模型

class Model(torch.nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.linear1 = torch.nn.Linear(8, 6)
        self.linear2 = torch.nn.Linear(6, 4)
        self.linear3 = torch.nn.Linear(4, 1)
        self.sigmoid = torch.nn.Sigmoid()

    def forward(self, x):
        x = self.sigmoid(self.linear1(x))
        x = self.sigmoid(self.linear2(x))
        x = self.sigmoid(self.linear3(x))
        return x
  • Model 继承自 torch.nn.Module 类。

  • _init_ 方法:
    定义了三个全连接层(Linear)和一个Sigmoid激活函数。

  • forward 方法:
    定义了前向传播过程,输入数据依次通过三个全连接层和Sigmoid激活函数。

5.4.构建损失函数和优化器

criterion = torch.nn.BCELoss(reduction='mean')
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

5.5.训练模型

if __name__ == '__main__':
    for epoch in range(100):
        for i, data in enumerate(train_loader, 0):
            inputs, labels = data
            y_pred = model(inputs)
            loss = criterion(y_pred, labels)
            print(epoch, i, loss.item())

            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

运行结果和上一小节类似,这一小节主要学习的是 dataloader 的具体作用和理解 epoch、batch 和 iteration 之间的关系。

总结

构建一个通用的神经网络模型是一个系统而精细的过程,大致可以分为四个关键步骤。首先,准备数据集是整个流程的基石,这一步骤不仅包括收集所需的数据,还需要对数据进行清洗、预处理以及划分训练集与测试集,确保数据的质量和适用性。接着,模型搭建阶段需要根据任务需求选择合适的网络架构,如卷积神经网络(CNN)用于图像识别,循环神经网络(RNN)适合序列数据处理等,并确定每一层的具体参数。第三步,定义损失函数和选择优化器是调整模型以达到最佳性能的关键,损失函数衡量预测值与真实值之间的差异,而优化器则通过反向传播算法最小化这种差异。最后,训练模型涉及迭代地将数据输入网络中,不断调整权重直至模型在训练集上表现良好,并通过验证集或测试集评估其泛化能力。掌握这一系列流程,就可以自己动手搭建绝大多数神经网络。

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

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

相关文章

酒店新科技,飞睿智能毫米波雷达人体存在感应器,智能照明创新节能新风尚

在这个日新月异的时代,科技正以未有的速度改变着我们的生活。从智能手机到智能家居,每一个细微之处都渗透着科技的魅力。而今,这股科技浪潮已经席卷到了酒店行业,为传统的住宿体验带来了翻天覆地的变化。其中,引人注目…

基于SpringBoot+Vue的茶园茶农文化交流平台

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏:Java精选实战项目…

对已经运行的flask服务测试代码覆盖率

上一篇文章《用pytest-cov获取flask项目的测试代码覆盖率》展示了用pytest的测试用例验证flask的函数,获取代码覆盖率信息。但是上述方法要求web服务没有提前启动,而是由pytest来启动,然后运行测试用例。 那么对于已经启动的web服务&#xff…

【STM32-HAL库】MQ2烟雾传感器使用(STM32F407ZET6)

MQ2可燃气体传感器介绍 MQ2是一种广谱气体传感器,能够检测多种可燃气体和烟雾。它是一种低成本、高灵敏度的传感器,广泛应用于家庭和工业环境中的气体监测。 原理 MQ2传感器的工作原理基于金属氧化物半导体(MOX)技术。当传感器暴露…

俄罗斯市场合格评定准入认证要求

前言 国内厂家想要把自己的产品顺利出口到俄罗斯市场,就需要基本了解俄罗斯的市场合格评定准入要求。俄罗斯主要实行的认证有EAC(TR-CU/CU-TR)认证、GOST R认证、计量认证和医疗产品国家注册。下面就分别简单介绍一下这几个产品认证。 一、EAC(TR-CU/CU-TR)认证介绍…

LVGL 笔记

在显示GUI的过程中需要对某些对象进行临时隐藏或临时显示,因此需要对该对象的FLAG进行配置就可以实现对象的显示和隐藏了. lv_obj_add_flag(user_obj, LV_OBJ_FLAG_HIDDEN);//隐藏对象 lv_obj_clear_flag(user_obj, LV_OBJ_FLAG_HIDDEN);//取消隐藏 GUI-Guider 中的选项卡 注意…

Linux驱动开发(速记版)--驱动基础

第一章 初识内核源码 Linux系统源码提供了操作系统的核心功能,如进程管理、内存管理、文件系统等。 BusyBox这类的文件系统构建工具,则提供了在这些核心功能之上运行的一系列实用工具和命令,使得用户能够执行常见的文件操作、文本处理、网络配…

MaxKB知识库问答系统入选Gitee最有价值开源项目

2024年9月19日,飞致云旗下开源项目MaxKB成功加入Gitee平台主导的GVP计划,入选2024年GVP——Gitee最有价值开源项目。MaxKB也是继MeterSphere、DataEase和1Panel之后,飞致云旗下第四个入选GVP的开源项目。 ▲图1 MaxKB入选2024年Gitee最有价值…

软机器人咋模仿生物?响应式水凝胶Aquabots有啥用?快来了解一下!

大家好,今天我们要来了解一项关于响应式水凝胶Aquabots的研究——《Responsive‐Hydrogel Aquabots》发表于《Advanced Science》。在当今科技发展中,制造能像生物体一样具有响应适应性的软机器人是个挑战。而Aquabots为解决这个问题带来了新的突破。它通…

vue3项目执行pnpm update后还原package.json文件后运行报错

项目场景: vue官方版本已更新到vue3.5,项目中还在使用vue3.4,因此想要更新项目vue版本。 问题描述 执行了 pnpm update 命令,一键更新了所有包,更新完成后项目不能正常运行。为了还原项目代码,先删除 nod…

“AI+Security”系列第3期(七):智能体车企落地实践

近日,由安全极客、Wisemodel 社区、InForSec 网络安全研究国际学术论坛和海升集团联合主办的 “AI Security” 系列第 3 期技术沙龙 ——“AI 安全智能体,重塑安全团队工作范式” 活动顺利举行。此次活动备受关注,吸引了线上线下超过千名观众…

DriveVLM 论文学习

论文链接:https://arxiv.org/abs/2402.12289 解决了什么问题? 自动驾驶对交通行业有着革命性的作用,实现 FSD 的一个主要障碍就是场景理解。场景理解涉及在复杂且不可预测的环境中进行导航,这些环境可能包括恶劣的天气条件、复杂…

【Git】克隆主项目,并同时克隆所有子模块

子模块 带有箭头的文件夹(relaxed_ik_core)通常表示这是一个 Git 子模块(submodule)。Git 子模块是一种嵌入式的 Git 仓库,它允许你在一个仓库中引用其他的 Git 仓库。换句话说,relaxed_ik_core 不是这个项…

uniapp实战教程:如何封装一个可复用的表单组件

在uniapp开发过程中,表单组件的使用场景非常广泛。为了提高开发效率,我们可以将常用的表单组件进行封装。本文将带你了解如何在uniapp中封装一个表单组件,让你只需要通过属性配置轻松实现各种表单,效果图如下: 一、准备…

《北方牧业》是什么级别的期刊?是正规期刊吗?能评职称吗?

问题解答 问:《中国动物检疫》是不是核心期刊? 答:不是,是知网收录的正规学术期刊。 问:《中国动物检疫》级别? 答:省级。主管单位:河北省畜牧局 主办单…

【win11】关闭windows11系统的讲述人

如何关闭windows11系统的讲述人,经常误触启动 讲述人(Narrator) 设置里找到讲述人(Narrator) 开关讲述人及快捷键

物联网行业中天线定制的激光直接成型 (LDS)技术

01 什么是lds技术? 普通的手机天线都被安装在手机的主板上: 在当今的智能手机中,我们常见的手机天线通常都被巧妙地安装在手机的主板上。这些天线承担着接收和发送信号的重要任务,是实现通信功能的关键组件之一。 而 LDS 天线…

运放信号失真原因分析——增益带宽积,压摆率

运放失真原因分析——增益带宽积,压摆率 运放失真原因分析 运放失真原因分析——增益带宽积,压摆率一、压摆率二、仿真模拟电路1.OPAx333的增益带宽积以及压摆率参数2.将输入信号的频率设置为10kHz3.将输入信号的频率设置为25kHz4.失真原因分析 总结 一、…

【MySQL实战45讲4-5】索引

文章目录 索引的定义索引的常见模型哈希表有序数组二叉搜索树 InnoDB的索引模型索引维护页分裂页合并页分裂和页合并的影响避免页分裂 覆盖索引最左前缀原则索引下推 索引的定义 索引的出现其实就是为了提高数据查询的效率,就像书的目录一样。一本500页的书&#x…

全开源/彩虹晴天多功能系统源码/知识付费系统/虚拟商城系统/完美可用+修复改良版

源码简介: 2024年最新全开源的彩虹晴天多功能系统源码,它可以作为知识付费系统、虚拟商城系统,完美可用,并且是修复改良版。 最让人兴奋的是,搭建这个系统完全不需要授权,不管是在国内还是国外的服务器&am…