Pytorch自动求导机制详解

news2024/11/22 22:08:15

目录

1. 自动求导

1.1 梯度计算

1.1.1 一阶导数

 1.1.2 二阶导数

 1.1.3 向量

 1.2 线性回归实战


1. 自动求导

在深度学习中,我们通常需要训练一个模型来最小化损失函数。这个过程可以通过梯度下降等优化算法来实现。梯度是函数在某一点上的变化率,可以告诉我们如何调整模型的参数以使损失函数最小化。自动求导是一种计算梯度的技术,它允许我们在定义模型时不需要手动推导梯度计算公式。PyTorch 提供了自动求导的功能,使得梯度的计算变得非常简单和高效。

PyTorch是动态图,即计算图的搭建和运算是同时的,随时可以输出结果。在pytorch的计算图里只有两种元素:数据(tensor)和 运算(operation)。

运算包括了:加减乘除、开方、幂指对、三角函数等可求导运算。

数据可分为:叶子节点(leaf node)和非叶子节点;叶子节点是用户创建的节点,不依赖其它节点;它们表现出来的区别在于反向传播结束之后,非叶子节点的梯度会被释放掉,只保留叶子节点的梯度,这样就节省了内存。如果想要保留非叶子节点的梯度,可以使用retain_grad()方法。

torch.tensor 具有如下属性:

  • 查看 是否可以求导 requires_grad
  • 查看 运算名称 grad_fn
  • 查看 是否为叶子节点 is_leaf
  • 查看 导数值 grad

针对requires_grad属性,自己定义的叶子节点默认为False,而非叶子节点默认为True,神经网络中的权重默认为True。判断哪些节点是True/False的一个原则就是从你需要求导的叶子节点到loss节点之间是一条可求导的通路。当我们想要对某个Tensor变量求梯度时,需要先指定requires_grad属性为True,指定方式主要有两种:

x = torch.tensor(1.).requires_grad_() # 第一种

x = torch.tensor(1., requires_grad=True) # 第二种

总结: 

(1)torch.tensor()设置requires_grad关键字参数

(2)查看tensor是否可导,x.requires_grad 属性

(3)设置叶子变量 leaf variable的可导性,x.requires_grad_()方法

(4)自动求导方法 y.backward() ,直接调用backward()方法,只会计算对计算图叶节点的导数。

(5)查看求得的到数值, x.grad 属性

1.1 梯度计算

自动求导的核心是反向传播算法(Backpropagation)。反向传播算法是一种高效地计算梯度的方法,它使用链式法则计算每个可导操作的梯度,然后利用这些梯度更新参数。一旦我们创建了可导张量,PyTorch 将会自动追踪所有涉及这些张量的操作,并构建一个计算图。计算图是一个有向无环图,表示了计算过程中张量之间的依赖关系。

1.1.1 一阶导数

然后我们举个例子:z=w*x+b

import torch

x=torch.tensor(1.,requires_grad=True)
b=torch.tensor(2.,requires_grad=True)
w=torch.tensor(3.,requires_grad=True)
z=w*x+b
z.backward()#反向传播
print(x.grad)#x导数值
print(w.grad)#w导数值
print(b.grad)#b导数值

运行结果如下图:

要想使上面的x,b,w支持求导,必须让它们为浮点类型,也就是我们给初始值的时候要加个点:“.”。不然的话,就会报错。 

 1.1.2 二阶导数

import torch

x = torch.tensor(2.).requires_grad_()
y = torch.tensor(3.).requires_grad_()
z = x * x * y
z.backward(create_graph=True) # x.grad = 12
print(x.grad)
x.grad.data.zero_() #PyTorch使用backward()时默认会累加梯度,需要手动把前一次的梯度清零
x.grad.backward() #对x一次求导后为2xy,然后再次反向传播
print(x.grad)

运行结果如下图:

 1.1.3 向量

在pytorch里面,默认:只能是【标量】对【标量】,或者【标量】对向【量/矩阵】求导

在深度学习中在求导的时候是对损失函数求导,损失函数一般都是一个标量,参数又往往是向量或者是矩阵。

比如有一个输入层为3节点的输入层,输出层为一个节点的输出层,这样一个简单的神经网络,针对一组样本而言,有

X=(x1,x2,x3)=(1.5,2.5,3.5),X是(1,3)维的,输出层的权值矩阵为W=(w1,w2,w3)W=(0.2,0.4,0.6)T,这里表示初始化的权值矩阵,T表示转置,则W表示的是(3,1)维度,偏置项为b=0.1,是一个标量,则可以构建一个模型如下:

Y=XW+b,其中W,b就是要求倒数的变量,这里Y是一个标量,W是向量,b是标量,W,b是叶节点。

将上面展开得到:

Y=x1*w1+x2*w2*x3*w3+b   

import torch

# 创建一个多元函数,即Y=XW+b=Y=x1*w1+x2*w2*x3*w3+b,x不可求导,W,b设置可求导
X = torch.tensor([1.5, 2.5, 3.5], requires_grad=False)
W = torch.tensor([0.2, 0.4, 0.6], requires_grad=True)
b = torch.tensor(0.1, requires_grad=True)
Y = torch.add(torch.dot(X, W), b)


# 求导,通过backward函数来实现
Y.backward()

# 查看导数,也即所谓的梯度
print(W.grad)
print(b.grad)

运行截图如下:

 1.2 线性回归实战

定义一个y=2*x+1线性方程,下面是一个使用 PyTorch 实现线性回归模型,并利用自动求导训练模型的示例:


import torch
import numpy as np
import torch.nn as nn
import torch.optim as optim

x_values=[i for i in range(11)]
x_train=np.array(x_values,dtype=np.float32)
x_train=x_train.reshape(-1,1)


y_values=[2*i +1 for i in x_values]
y_values=np.array(y_values,dtype=np.float32)
y_train=y_values.reshape(-1,1)


#这里线性回归就相当于不加激活函数的全连接层
class LinearRegression(nn.Module):
    def __init__(self):
        super(LinearRegression, self).__init__()
        self.linear = nn.Linear(1, 1)

    def forward(self, x):
        return self.linear(x)



#使用GPU训练
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

# 创建模型实例和优化器
model = LinearRegression()
model.to(device)
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 定义损失函数
criterion = nn.MSELoss()
for epoch in range(100):
    # 创建数据集
    inputs = torch.from_numpy(x_train).to(device)
    targets = torch.from_numpy(y_train).to(device)
    # 前向传播
    outputs = model(inputs)
    loss = criterion(outputs, targets)

    # 反向传播和优化器更新
    #梯度清零每一次迭代
    optimizer.zero_grad()
    #反向传播
    loss.backward()
    #更新权重参数
    optimizer.step()
    #每10轮,打印一下损失函数
    if epoch%10==0:
        print("epoch {}, loss {}".format(epoch,loss.item()))


#使用训练完的模型进行数据的预测
predicted=model(torch.from_numpy(x_train).to(device))
print(predicted)
print(targets)

在上面的例子中,我们首先创建了一个简单的线性回归模型 LinearRegression,并创建了一个包含11个样本的数据集。然后,我们定义了损失函数 criterion 和优化器 optimizer,并在训练循环中进行模型训练。

模型训练中损失值变化如下:

 在模型中预测结果和标签值对比如下图:上面的为模型预测结果,下面的为标签值

 至此这篇文章到此结束。

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

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

相关文章

vue代码格式化,Prettier - Code formatter格式化规则文件

vue2,vue3格式化代码使用方法: 1、新建文件名: .prettierrc.cjs,里面放上下面的代码片段,直接粘贴即可 2、把 .prettierrc.cjs文件放在项目的根目录中 // prettier的默认配置文件 module.exports {// 一行最多 100 …

Final Cut Pro中文新手教程 (52绿幕抠图)FCPX透明通道基础使用方法

今天小编为大家分享的是FCPX透明通道基础教程,究竟什么是透明通道呢?透明通道就是一个阿尔法(alpha)通道,也叫做通明阿尔法通道。只要带有alpha的图片或者视频,他们的背景就是透明的只会显示他们的形状和内容。这种技术经常应用在…

VLAN :虚拟局域网

目录 VLAN:虚拟局域网 VLAN种类: 接口分配链路类型 接口划分VLAN 跨网段的通讯 VLAN:虚拟局域网 LAN :局域网 MAN:城域网 WAN:广域网 1.一个VLAN相当于一个广播域 VLAN:通过路由器和交换机…

OpenCv之图像形态学

目录 一、形态学 二、图像全局二值化 三、自适应阈值二值化 四、腐蚀操作 五、获取形态学卷积核 六、膨胀操作 七、开运算 八、闭运算 一、形态学 定义: 指一系列处理图像形状特征的图像处理技术形态学的基本思想是利用一种特殊的结构元(本质上就是卷积核)来测量或提取输…

数据结构--图的基本操作

数据结构–图的基本操作 使用的存储模式&#xff1a; 图的基本操作&#xff1a; • Adjacent(G,x,y)&#xff1a;判断图G是否存在边<x, y>或(x, y)。 • Neighbors(G,x)&#xff1a;列出图G中与结点x邻接的边。 • InsertVertex(G,x)&#xff1a;在图G中插入顶点x。 • …

VSCode 注释后光标快速定位下一行

VSCode默认用 Ctrl / 注释一行时&#xff0c;光标停留在该行中。下面介绍如何注释后&#xff0c;光标会自动移动到下一行。 1.【View】 ->【Extensions】->【查找并安装Multi-command 扩展】 2.【File 】 -> 【Preferences 】->【Keyboard Shortcuts】&#xff08…

怎样优雅地增删查改(八):按用户关系查询

文章目录 原理实现正向用户关系反向用户关系 使用测试 用户关系&#xff08;Relation&#xff09;是描述业务系统中人员与人员之间的关系&#xff0c;如&#xff1a;签约、关注&#xff0c;或者朋友关系。 之前我们在扩展身份管理模块的时候&#xff0c;已经实现了用户关系管理…

Spark(30):Spark性能调优之常规性能调优

目录 0. 相关文章链接 1. 最优资源配置 2. RDD优化 2.1. RDD复用 2.2. RDD持久化 2.3. RDD尽可能早的 filter 操作 3. 并行度调节 4. 广播大变量 5. Kryo序列化 6. 调节本地化等待时长 0. 相关文章链接 Spark文章汇总 1. 最优资源配置 Spark 性能调优的第一步&…

9.Ceph部署

文章目录 Ceph部署前期环境准备实验部署软件安装部署Ceph集群部署mon节点部署OSD存储节点部署mgr节点开启监控模块管理pool Ceph部署 前期环境准备 主机名public网络cluster网络角色admin192.168.242.69admin(管理节点)node01192.168.242.66192.168.242.100.11mon、mgr、osdn…

【Elemnt-UI——el-popover点击出现多个弹框】

效果图 解决 :append-to-body"false"添加这个属性就可以了 <el-popoverv-model"item.contextmenuVisible"placement"bottom-end":append-to-body"false"trigger"click":visible-arrow"false"hide"item.…

[PCIE体系结构导读]PCIE总结(一)

什么是PCIE PCIe Peripheral Component Interconnect express 快速外部组件互联 高速串行计算机扩展总线标准 处理器系统的局部总线 连接外部设备 高速、低时延支持热插拔可靠扩展性好复杂度高点对点串行连接 附一个博主写的总结文章&#xff0c;非常好 《PCI EXPRESS体系结…

如何在服务器下载coco数据集

如果是需要在服务器上进行跑实验&#xff0c;可以直接通过wget下载链接 那么如何确定下载地址呢&#xff1f; 例如&#xff1a;先找到coco的数据集地址http://cocodataset.org 然后可以看到 可以下载一个 2017 Train/Val annotations[241MB]&#xff0c;在下载内容中可以看到…

跨域是怎么个事?

跨域是怎么个事&#xff1f; 【一】到底什么是跨域&#xff1f;【二】什么是浏览器的同源策略&#xff1f;【三】跨域问题有哪些解决方案&#xff1f;【四】详细说说Nginx解决跨域问题的实现过程&#xff1f;&#xff08;1&#xff09;项目准备 【一】到底什么是跨域&#xff1…

宋浩线性代数笔记(一)行列式的计算

本帖更新b站宋浩老师的线代网课笔记&#xff0c;内容较为细致详细&#xff0c;参考书用的是科学出版社的第三版&#xff0c;之后会附加同济出版社第六版的教材内容。 &#xff08;字不好看大家将就看吧QAQ&#xff09;

【论文阅读】一些多轮对话文章的体会 ACL 2023

前言 本文是对昨天看到的ACL 2023三篇多轮对话文章的分享这三个工作都是根据一些额外属性控制输出的工作&#xff0c;且评估的方面比较相似&#xff0c;可以借鉴 方法 这几篇文章都不是做general任务的&#xff0c;倾向于通过一些额外信息&#xff0c;来做specific任务 【1】…

当低代码和无代码平台可以加速应用程序现代化时

你的组织很可能正在寻求将遗留应用程序现代化、将单片应用架构拆分为服务&#xff0c;并迁移到公共或私有云基础架构。在此过程中&#xff0c;您可能还希望改善用户体验&#xff0c;创建CI/CD流水线&#xff0c;添加测试自动化&#xff0c;并实施一系列其他DevOps最佳实践。 这…

水声功率放大器的作用是什么

水声功率放大器是一种专门用于水声设备的高功率电子设备&#xff0c;主要用于提升水下信号的传输距离和保证语音清晰度。它的作用在水下通信、水下测量、海洋科学等领域都非常重要。 其主要作用有以下几个方面&#xff1a; 增强信号传输距离 水声信号在水中传播会受到各种因素的…

维安股份冲刺A股上市:计划募资约15亿元,上海科学院为实控人

7月17日&#xff0c;上海证券交易所对上海维安电子股份有限公司&#xff08;下称“维安股份”&#xff09;发出问询函。据贝多财经了解&#xff0c;维安股份于2023年6月20日递交招股书&#xff0c;准备在上海证券交易所主板上市。 本次冲刺上市&#xff0c;维安股份计划募资15.…

解决一云多芯全球命题,浪潮云海给出了解题思路

云计算&#xff0c;生而为用户简化资源的使用&#xff0c;让用户不必关注复杂的底层硬件架构&#xff0c;而是通过“服务”的方式调用资源&#xff0c;专注于自己的业务创新。 因此&#xff0c;用户要上云&#xff0c;就天然地要求云平台必须能够屏蔽底层的硬件架构&#xff0…

轻量级应用服务器开放端口

关于使用浏览器连接自己所写的TCP进程时&#xff0c;由于没有开放端口&#xff0c;而且搜索到对应的操作来进行开放端口&#xff0c;所以在完成开放端口后特意做个笔记&#xff0c;防止忘记。 登录自己所使用的服务器的网站找到控制台 找到轻量级应用服务器 找到所需要开放端口…