Tensorflow2.1计算梯度的tf.GradienTape()函数

TensorFlow 2.0默认是eager模式,每行代码顺序执行。有一个上下文管理器(context manager)来连接需要计算梯度的函数和变量,方便求解同时也提升效率。

tf.GradientTape
(
    persistent=False,
     watch_accessed_variables=True
)

参数说明:

persistent - 布尔值,用来指定新创建的gradient tape是否是可持续性的。默认是False,意味着只能够调用一次gradient()函数。

watch_accessed_variables: 布尔值,表明这个gradien tap是不是会自动追踪任何能被训练(trainable)的变量。默认是True。要是为False的话,意味着你需要手动去指定你想追踪的那些变量。

举个例子1:计算下列函数的导数

y = x 2 y = x^2 y=x2

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

print(dy_dx)
# tf.Tensor(6.0, shape=(), dtype=float32)

注:例子中的watch函数把需要计算梯度的变量x加进来了。GradientTape默认只监控由tf.Variable创建的traiable=True属性(默认)的变量。上面例子中的x是constant,因此计算梯度需要增加g.watch(x)函数。当然,也可以设置不自动监控可训练变量,完全由自己指定,设置watch_accessed_variables=False就行了(一般用不到)。

举个例子2:一元和二元求导

import tensorflow as tf

def gradient_test():
    #-------------------一元梯度案例---------------------------
    print("一元梯度")
    x=tf.constant(value=3.0)
    with tf.GradientTape(persistent=True,watch_accessed_variables=True) as tape:
        tape.watch(x)
        y1=2*x
        y2=x*x+2
        y3=x*x+2*x
    #一阶导数
    dy1_dx=tape.gradient(target=y1,sources=x)
    dy2_dx = tape.gradient(target=y2, sources=x)
    dy3_dx = tape.gradient(target=y3, sources=x)
    print("dy1_dx:",dy1_dx)
    print("dy2_dx:", dy2_dx)
    print("dy3_dx:", dy3_dx)


    # # -------------------二元梯度案例---------------------------
    print("二元梯度")
    x = tf.constant(value=3.0)
    y = tf.constant(value=2.0)
    with tf.GradientTape(persistent=True,watch_accessed_variables=True) as tape:
        tape.watch([x,y])
        z1=x*x*y+x*y
    # 一阶导数
    dz1_dx=tape.gradient(target=z1,sources=x)
    dz1_dy = tape.gradient(target=z1, sources=y)
    dz1_d=tape.gradient(target=z1,sources=[x,y])
    print("dz1_dx:", dz1_dx)
    print("dz1_dy:", dz1_dy)
    print("dz1_d:",dz1_d)
    print("type of dz1_d:",type(dz1_d))


if __name__=="__main__":
    gradient_test()

# 一元梯度
# dy1_dx: tf.Tensor(2.0, shape=(), dtype=float32)
# dy2_dx: tf.Tensor(6.0, shape=(), dtype=float32)
# dy3_dx: tf.Tensor(8.0, shape=(), dtype=float32)
# 二元梯度
# dz1_dx: tf.Tensor(14.0, shape=(), dtype=float32)
# dz1_dy: tf.Tensor(12.0, shape=(), dtype=float32)
# dz1_d: [<tf.Tensor: id=55, shape=(), dtype=float32, numpy=14.0>, <tf.Tensor: id=56, shape=(), dtype=float32, numpy=12.0>]
# type of dz1_d: <class 'list'>

watch(tensor)

作用:确保某个tensor被tape追踪

参数:

  • tensor: 一个Tensor或者一个Tensor列表

gradient(target,sources,output_gradients=None,unconnected_gradients=tf.UnconnectedGradients.NONE)

作用:根据tape上面的上下文来计算某个或者某些tensor的梯度

*输入参数:

  • target: 被微分的Tensor或者Tensor列表,你可以理解为经过某个函数之后的值
  • sources: Tensors 或者Variables列表(当然可以只有一个值). 你可以理解为函数的某个变量
  • output_gradients: a list of gradients, one for each element of target. Defaults to None.
  • unconnected_gradients: a value which can either hold ‘none’ or ‘zero’ and alters the value which will be returned if the target and sources are unconnected. The possible values and effects are detailed in ‘UnconnectedGradients’ and it defaults to ‘none’.

返回参数
一个列表表示各个变量的梯度值,和source中的变量列表一一对应,表明这个变量的梯度。

计算二阶导数

例如下列的计算公式:
y = x w + b y = xw + b y=xw+b
一阶导为:
ϕ y ϕ w = x \frac{\phi y}{\phi w} = x ϕwϕy=x
二阶导数为:
ϕ 2 y ϕ w 2 = ϕ y ′ ϕ w = ϕ x ϕ w = N o n e \frac{\phi ^2y}{\phi w^2} = \frac {\phi y'}{\phi w} = \frac{\phi x}{\phi w} = \color{blue}{None} ϕw2ϕ2y=ϕwϕy=ϕwϕx=None

实现如下:

import tensorflow as tf

w = tf.Variable(1.0)
b = tf.Variable(2.0)
x = tf.Variable(3.0)

with tf.GradientTape() as t1:
  with tf.GradientTape() as t2:
    y = x * w + b
  dy_dw, dy_db = t2.gradient(y, [w, b])
d2y_dw2 = t1.gradient(dy_dw, w)

print(dy_dw)
print(dy_db)
print(d2y_dw2)

# tf.Tensor(3.0, shape=(), dtype=float32)
# tf.Tensor(1.0, shape=(), dtype=float32)
# None
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值