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

PyTorch使用------自动微分模块

5b48cb01f659435cbe69ea1eb0f43faa.jpeg

目录

 

🍔 梯度基本计算

1.1 单标量梯度的计算

1.2 单向量梯度的计算

1.3 多标量梯度计算

1.4 多向量梯度计算

1.5 运行结果💯

🍔 控制梯度计算

2.1 控制不计算梯度

2.2 注意: 累计梯度

2.3 梯度下降优化最优解

2.4 运行结果💯

🍔 梯度计算注意

3.1 detach 函数用法

3.2 detach 前后张量共享内存

3.3 运行结果💯

🍔 小节


 

学习目标

🍀 掌握梯度计算


自动微分(Autograd)模块对张量做了进一步的封装,具有自动求导功能。自动微分模块是构成神经网络训练的必要模块,在神经网络的反向传播过程中,Autograd 模块基于正向计算的结果对当前的参数进行微分计算,从而实现网络权重参数的更新。

🍔 梯度基本计算

我们使用 backward 方法、grad 属性来实现梯度的计算和访问.

import torch

1.1 单标量梯度的计算

   

 # y = x**2 + 20def test01():# 定义需要求导的张量# 张量的值类型必须是浮点类型x = torch.tensor(10, requires_grad=True, dtype=torch.float64)# 变量经过中间运算f = x ** 2 + 20# 自动微分f.backward()# 打印 x 变量的梯度# backward 函数计算的梯度值会存储在张量的 grad 变量中print(x.grad)


1.2 单向量梯度的计算

# y = x**2 + 20
def test02():# 定义需要求导张量x = torch.tensor([10, 20, 30, 40], requires_grad=True, dtype=torch.float64)# 变量经过中间计算f1 = x ** 2 + 20# 注意:# 由于求导的结果必须是标量# 而 f 的结果是: tensor([120., 420.])# 所以, 不能直接自动微分# 需要将结果计算为标量才能进行计算f2 = f1.mean()  # f2 = 1/2 * x# 自动微分f2.backward()# 打印 x 变量的梯度print(x.grad)

1.3 多标量梯度计算

# y = x1 ** 2 + x2 ** 2 + x1*x2
def test03():# 定义需要计算梯度的张量x1 = torch.tensor(10, requires_grad=True, dtype=torch.float64)x2 = torch.tensor(20, requires_grad=True, dtype=torch.float64)# 经过中间的计算y = x1**2 + x2**2 + x1*x2# 将输出结果变为标量y = y.sum()# 自动微分y.backward()# 打印两个变量的梯度print(x1.grad, x2.grad)


1.4 多向量梯度计算

def test04():# 定义需要计算梯度的张量x1 = torch.tensor([10, 20], requires_grad=True, dtype=torch.float64)x2 = torch.tensor([30, 40], requires_grad=True, dtype=torch.float64)# 经过中间的计算y = x1 ** 2 + x2 ** 2 + x1 * x2print(y)# 将输出结果变为标量y = y.sum()# 自动微分y.backward()# 打印两个变量的梯度print(x1.grad, x2.grad)if __name__ == '__main__':test04()

1.5 运行结果💯

tensor(20., dtype=torch.float64)
tensor([ 5., 10., 15., 20.], dtype=torch.float64)
tensor(40., dtype=torch.float64) tensor(50., dtype=torch.float64)
tensor([1300., 2800.], dtype=torch.float64, grad_fn=<AddBackward0>)
tensor([50., 80.], dtype=torch.float64) tensor([ 70., 100.], dtype=torch.float64)

🍔 控制梯度计算

我们可以通过一些方法使得在 requires_grad=True 的张量在某些时候计算不进行梯度计算。

import torch

2.1 控制不计算梯度

def test01():x = torch.tensor(10, requires_grad=True, dtype=torch.float64)print(x.requires_grad)# 第一种方式: 对代码进行装饰with torch.no_grad():y = x ** 2print(y.requires_grad)# 第二种方式: 对函数进行装饰@torch.no_grad()def my_func(x):return x ** 2print(my_func(x).requires_grad)# 第三种方式torch.set_grad_enabled(False)y = x ** 2print(y.requires_grad)


2.2 注意: 累计梯度

def test02():# 定义需要求导张量x = torch.tensor([10, 20, 30, 40], requires_grad=True, dtype=torch.float64)for _ in range(3):f1 = x ** 2 + 20f2 = f1.mean()# 默认张量的 grad 属性会累计历史梯度值# 所以, 需要我们每次手动清理上次的梯度# 注意: 一开始梯度不存在, 需要做判断if x.grad is not None:x.grad.data.zero_()f2.backward()print(x.grad)


2.3 梯度下降优化最优解

def test03():# y = x**2x = torch.tensor(10, requires_grad=True, dtype=torch.float64)for _ in range(5000):# 正向计算f = x ** 2# 梯度清零if x.grad is not None:x.grad.data.zero_()# 反向传播计算梯度f.backward()# 更新参数x.data = x.data - 0.001 * x.gradprint('%.10f' % x.data)if __name__ == '__main__':test01()test02()test03()

2.4 运行结果💯

True
False
False
False
tensor([ 5., 10., 15., 20.], dtype=torch.float64)
tensor([ 5., 10., 15., 20.], dtype=torch.float64)
tensor([ 5., 10., 15., 20.], dtype=torch.float64)

🍔 梯度计算注意

当对设置 requires_grad=True 的张量使用 numpy 函数进行转换时, 会出现如下报错:

Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.

此时, 需要先使用 detach 函数将张量进行分离, 再使用 numpy 函数.

注意: detach 之后会产生一个新的张量, 新的张量作为叶子结点,并且该张量和原来的张量共享数据, 但是分离后的张量不需要计算梯度。

import torch

3.1 detach 函数用法

def test01():x = torch.tensor([10, 20], requires_grad=True, dtype=torch.float64)# Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.# print(x.numpy())  # 错误print(x.detach().numpy())  # 正确


3.2 detach 前后张量共享内存

def test02():x1 = torch.tensor([10, 20], requires_grad=True, dtype=torch.float64)# x2 作为叶子结点x2 = x1.detach()# 两个张量的值一样: 140421811165776 140421811165776print(id(x1.data), id(x2.data))x2.data = torch.tensor([100, 200])print(x1)print(x2)# x2 不会自动计算梯度: Falseprint(x2.requires_grad)if __name__ == '__main__':test01()test02()

3.3 运行结果💯

10. 20.]
140495634222288 140495634222288
tensor([10., 20.], dtype=torch.float64, requires_grad=True)
tensor([100, 200])
False

🍔 小节

本小节主要讲解了 PyTorch 中非常重要的自动微分模块的使用和理解。我们对需要计算梯度的张量需要设置 requires_grad=True 属性,并且需要注意的是梯度是累计的,在每次计算梯度前需要先进行梯度清零。

 54b39e35553446379cc448d7586a957b.jpeg

😀 小言在此感谢大家的支持😀 

顺便问一下大佬们,最擅长使用的编程语言是什么呢~

欢迎评论区讨论哦~

 

 

 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • kotlin—— withTimeoutOrNull的介绍和使用场景
  • js中正则表达式中【exec】用法深度解读
  • Linux相关概念和重要知识点(7)(git、冯诺依曼体系结构)
  • python爬虫:从12306网站获取火车站信息
  • YOLOv9改进策略【注意力机制篇】| CVPR2024 CAA上下文锚点注意力机制
  • neo4j(spring) 使用示例
  • 如何快速上手一个Github的开源项目
  • 【深度】为GPT-5而生的「草莓」模型!从快思考—慢思考到Self-play RL的强化学习框架
  • vue组件的生命周期
  • 常用集合(Set等)
  • CTF夺旗赛经验总结及落地实践,零基础入门到精通,收藏这一篇就够了
  • 跟着问题学12——GRU详解
  • 应用targetSdkVersion升级指导
  • 探索C语言与Linux编程:获取当前用户ID与进程ID
  • 中秋节特别游戏:给玉兔投喂月饼
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • angular学习第一篇-----环境搭建
  • Codepen 每日精选(2018-3-25)
  • es的写入过程
  • golang 发送GET和POST示例
  • JS+CSS实现数字滚动
  • Linux链接文件
  • 编写高质量JavaScript代码之并发
  • 程序员该如何有效的找工作?
  • 动态规划入门(以爬楼梯为例)
  • 观察者模式实现非直接耦合
  • 讲清楚之javascript作用域
  • 类orAPI - 收藏集 - 掘金
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 如何胜任知名企业的商业数据分析师?
  • 深入浅出Node.js
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 微信小程序开发问题汇总
  • 做一名精致的JavaScripter 01:JavaScript简介
  • raise 与 raise ... from 的区别
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • #C++ 智能指针 std::unique_ptr 、std::shared_ptr 和 std::weak_ptr
  • #laravel部署安装报错loadFactoriesFrom是undefined method #
  • #微信小程序(布局、渲染层基础知识)
  • $().each和$.each的区别
  • (007)XHTML文档之标题——h1~h6
  • (04)odoo视图操作
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (五)Python 垃圾回收机制
  • (限时免费)震惊!流落人间的haproxy宝典被找到了!一切玄妙尽在此处!
  • (转)视频码率,帧率和分辨率的联系与区别
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • .NET 8 编写 LiteDB vs SQLite 数据库 CRUD 接口性能测试(准备篇)
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现