目录

  • 自动微分和梯度
  • 中间结果
  • 多目标的梯度
  • 控制流
  • 获取None的梯度
  • 零而不是None

自动微分和梯度

Tensorflow为自动微分提供了 tf.GradientTape API,将tf.GradientTape上下文内执行的相关运算记录到“条带”上,随后使用该条带通过反向传播模式计算梯度。

要实现自动微分,Tensorflow需要记忆前向传播过程中的运算顺序;
后向传播期间,Tensorflow以相反的顺序遍历此运算列表来计算梯度。

使用 GradientTape.gradient(target,sources) 计算某个目标相对于模型变量的梯度。
使用GradientTape.watch(x) 可以设置要监视的变量。

x = tf.constant(3.0)
with tf.GradientTape() as tape:tape.watch(x)y = x**2dy_dx = tape.gradient(y,x)
dy_dx.numpy()

6.0

要停用监视所有 tf.Variables 的默认行为,请在创建梯度带时设置 watch_accessed_variables=False.

中间结果

如果要在统一计算中计算多个梯度,需要创建一个 persistent=True 的梯度带。

x = tf.constant([1,3.0])with tf.GradientTape(persistent = True) as tape:tape.watch(x)y = x*xz = y*yprint(tape.gradient(z,x).numpy())
print(tape.gradient(y,x).numpy())

[ 4. 108.]
[2. 6.]

如果不设置 persistent=True,计算y对x梯度时会报错。

多目标的梯度

单目标的梯度:

x = tf.Variable(2.0)
with tf.GradientTape(persistent=True) as tape:y0 = x**2;y1 = 1/x
print(tape.gradient(y0,x).numpy())
print(tape.gradient(y1,x).numpy())

4.0
-0.25

多目标的梯度:

tape.gradient({'y0':y0, 'y1':y1},x).numpy()

3.75

多个目标的梯度即:单目标梯度的总和

这样一来,就可以轻松获取损失集合总和的梯度。

控制流

梯度在控制语句(例如if while语句)中,仅记录使用到的变量。

x = tf.constant(1.0)
v0 = tf.Variable(2.0)
v1 = tf.Variable(2.0)with tf.GradientTape(persistent=True) as tape:tape.watch(x)if x > 0.0:result = v0else:result = v1**2dv0, dv1 = tape.gradient(result,[v0,v1])print(dv0)
print(dv1)

tf.Tensor(1.0, shape=(), dtype=float32)
None

只有v0有梯度,v1未使用到,故梯度为None

获取None的梯度

当目标未连接到变量时,您将获得None的梯度。

x = tf.Variable(2.)
y = tf.Variable(3.)with tf.GradientTape() as tape:z = y * y
print(tape.gradient(z, x))

None

此处 z 显然未连接到 x,因此梯度为None。

  1. 一种常见错误是不经意间用tensor替换了Variable,而得不到梯度。
# 1.使用张量替换变量, 梯度带自动监视tf.Variable,但不会监视tf.tensor
x = tf.Variable(2.0)for epoch in range(2):with tf.GradientTape() as tape:y = x+1print(type(x).__name__, ":", tape.gradient(y,x))x = x+1

ResourceVariable : tf.Tensor(1.0, shape=(), dtype=float32)
EagerTensor : None

正确的做法是:用assign()更新 x.assign(x+1)

  1. 在tensorflow之外进行了计算
    如果计算退出 TensorFlow,梯度带将无法记录梯度路径。
import numpy as np
x = tf.Variable([[1.0,2.0],[3.0,4.0]], dtype=tf.float32)with tf.GradientTape() as tape:x2 = x**2y = np.mean(x2, axis=0)    # 不在tensorflow内的运算y = tf.reduce_mean(y,axis=0)print(tape.gradient(y,x))

None

  1. 通过整数或字符串获取梯度

整数和字符串不可微分。如果计算路径使用这些数据类型,则不会出现梯度。

x = tf.constant(10)with tf.GradientTape() as g:g.watch(x)y = x*xprint(g.gradient(y,x))

WARNING:tensorflow:The dtype of the watched tensor must be floating (e.g. tf.float32), got tf.int32
WARNING:tensorflow:The dtype of the target tensor must be floating (e.g. tf.float32) when calling GradientTape.gradient, got tf.int32
WARNING:tensorflow:The dtype of the source tensor must be floating (e.g. tf.float32) when calling GradientTape.gradient, got tf.int32
None

上述例子只要把x替换为 10.0 即可正常运行。

  1. 通过有状态对象获取梯度。
    tf.Variable 具有内部状态,即它的值。使用变量时,会读取状态。计算相对于变量的梯度是正常操作,但是变量的状态改变会阻止梯度计算进一步向后移动。 例如:
x0 = tf.Variable(3.0)
x1 = tf.Variable(0.0)with tf.GradientTape() as tape:# Update x1 = x1 + x0.x1.assign_add(x0)# The tape starts recording from x1.y = x1**2   # y = (x1 + x0)**2# This doesn't work.
print(tape.gradient(y, x0))   #dy/dx0 = 2*(x1 + x0)

None

类似地,tf.data.Dataset 迭代器和 tf.queue 也有状态,会停止经过它们的张量上的所有梯度。

零而不是None

在某些情况下,对于未连接到的梯度,得到0而不是None比较方便。
您可以使用 unconnected_gradients 参数决定具有未连接的梯度时的返回值。

x = tf.Variable([2.0,2.0])
y = tf.Variable(3.0)with tf.GradientTape() as tape:z = y**2print(tape.gradient(z, x, unconnected_gradients=tf.UnconnectedGradients.ZERO))

tf.Tensor([0. 0.], shape=(2,), dtype=float32)

z未连接到x,得到梯度为0。

Tensorflow2.x 利用“GradientTape 梯度带”自动求梯度相关推荐

  1. Pytorch总结一之 数据操作、类型转换、数学计算、自动求梯度

    Pytorch总结一 在PyTorch中, torch.Tensor 是存储和变换数据的主要⼯具.如果你之前⽤过NumPy,你会发现Tensor 和NumPy的多维数组⾮常类似.然⽽, Tensor ...

  2. pytorch学习笔记(二):自动求梯度

    文章目录 前言 1 概念 2 Tensor 3 梯度 前言 在深度学习中,我们经常需要对函数求梯度(gradient).PyTorch提供的autograd包能够根据输入和前向传播过程自动构建计算图, ...

  3. torch.Tensor常用数据操作汇总与自动求梯度

    在深度学习中,通常会频繁地对数据进行操作,在PyTorch中,torch.Tensor是存储和变换数据的主要工具(Tensor和NumPy的多维数组非常类似,Tensor提供GPU计算和自动求梯度等更 ...

  4. PyTorch入门学习(二):Autogard之自动求梯度

    autograd包是PyTorch中神经网络的核心部分,简单学习一下. autograd提供了所有张量操作的自动求微分功能. 它的灵活性体现在可以通过代码的运行来决定反向传播的过程, 这样就使得每一次 ...

  5. 《动手学深度学习 PyTorch版》学习笔记(二):自动求梯度

    一.自动求梯度 1.requires_grad_(), detach(), torch.no_grad()的区别 参考博客:https://www.jianshu.com/p/ff74ccae25f3 ...

  6. 《动手学深度学习》 第二天 (自动求梯度)

    2.3.自动求梯度 MXNet提供的autograd模块可以用来自动求梯度. 2.3.1 一个简单的栗子 这里我们要求对函数 y = 2xTx (2乘以x的转秩乘以X)求关于列向量 x 的梯度.(使用 ...

  7. python自动求梯度

    from mxnet import autograd, nd 方法 x = nd.arange(4).reshape((4, 1)) 方法 结果 x.attach_grad() 申请求梯度所需内存 a ...

  8. pytorch自动求梯度—详解

    构建深度学习模型的基本流程就是:搭建计算图,求得损失函数,然后计算损失函数对模型参数的导数,再利用梯度下降法等方法来更新参数.搭建计算图的过程,称为"正向传播",这个是需要我们自己 ...

  9. Pytorch自动求梯度

    求梯度 微分 Pytorch自动微分 微分 通常我们见到的微分方法有两种: ·符号微分法: ·数值微分法: Pytorch自动微分 对于一个Tensor,如果它的属性requires_grad 设置为 ...

最新文章

  1. 关闭oracle服务 linux,Linux下启动和关闭Oracle服务与数据库
  2. HashMap 散列初体验
  3. mysql2008安装中文_Microsoft SQL Server 2008 R2 中文安装说明
  4. snake4444勒索病毒成功处理教程方法工具达康解密金蝶/用友数据库sql后缀snake4444...
  5. bootstraptable treeGrid 懒加载_Java类加载机制及自定义加载器
  6. android 饿了么地图,饿了么送餐位置地图定位代码
  7. 百度官方wormHole后门检测记录(转)
  8. 使用wininet的InternetReadFile下载文件
  9. Python单例模式4种方式
  10. 调试运行计算机程序的目的是,软件调试的目的是什么
  11. js数组对象重复的数据添加标识
  12. Telemetry原理
  13. C#方法讲解——飞行棋画地图
  14. 大疆FPGA/芯片开发工程师(B卷)笔试题(含详解)
  15. 给1078万考生批卷的,可能不是个人
  16. Python+Vue计算机毕业设计酒店管理系统g72sp(源码+程序+LW+部署)
  17. 300张现场照片,揭秘移动云大会!
  18. 一瓶OTC,药店被罚10万,原因是...
  19. 云计算实战:Amazon EC2之初体验
  20. 调用顺丰API实现电商专递下单和获取面单功能

热门文章

  1. python format是什么
  2. 老男孩之猛龙过江电影高清版迅雷下载
  3. PHP之自定义阿里云客服在线访客名片
  4. php网页可视化调试工具,php-xdebug调试工具
  5. matlab 示波器模块,matlab示波器模块
  6. 最全介绍的代理模式---第一节-静态代理
  7. 品牌数字化升级,如何借力用户画像实现精准营销? - whale 帷幄
  8. 国际知名营养品牌排行榜前十位
  9. nested exception is java.lang.NoClassDefFoundError:org/sprin
  10. 天空之城 10孔口琴