Tensorflow 2 “自动求梯度” - tf.GradientTape.gradient()

Tensorflow 2 “自动求梯度” - tf.GradientTape.gradient

  • 一、单次调用(一阶导数)
  • 二、计算同个函数的多阶导数(注意要手动释放资源)
  • 三、高阶导数
  • 四、对python控制流求梯度
  • 五、举例-MSE Gradient、Crossentropy gradient

在深度学习中,我们经常需要对函数求梯度(gradient), tensorflow2.0 提供的 GradientTape 可自动求梯度。

一、单次调用(一阶导数)

x = tf.constant(3.0) #创建tensor
with tf.GradientTape() as g:  # 创建一个GradientTape对象
    g.watch(x)  # 监视watch要求导的变量
    y = x * x
dy_dx = g.gradient(y, x) # 对函数进行求导

二、计算同个函数的多阶导数(注意要手动释放资源)

默认情况下,调用 GradientTape.gradient() 方法时, GradientTape 占用的资源会立即得到释放。通过创建一个持久的梯度带, 参数 persistent=True, 可以计算同个函数的多个导数,但是注意要手动释放资源del tape。例如:

with tf.GradientTape(persistent=True) as g:
	g.watch(x)
	y = x * x
	z = y * Y
dz_dx = g.gradient(z, x)  # 求一阶导数
dy_dx = g.gradient(y, x)  # 求二阶导数
del g     #手动释放资源   

三、高阶导数

在 ‘GradientTape’ 上下文管理器中记录的操作会用于自动微分。如果导数是在上下文中计算的,导数的函数也会被记录下来,因此 “同个 API ” 可以用于高阶导数。例如:

二阶导数(高阶导数同理)

x = tf.Variable(1.0)  # 创建可优化的tensor(具有可求导的特性)

with tf.GradientTape() as t:
  with tf.GradientTape() as t2:
    y = x * x * x
  dy_dx = t2.gradient(y, x)      #计算一阶导数
d2y_dx2 = t.gradient(dy_dx, x)   #计算二阶导数

四、对python控制流求梯度

Tensorflow 2 “自动求梯度” - tf.GradientTape.gradient()_第1张图片

五、举例-MSE Gradient、Crossentropy gradient

##coding:utf-8
import tensorflow as tf

#举例-MSE Gradient
x = tf.random.normal([2,4],seed=1)
w = tf.random.normal([4,3],seed=1)
b = tf.zeros([3])
y = tf.constant([2,0])

with tf.GradientTape() as tape:
    tape.watch([w,b])
    prob = tf.nn.softmax(x@w+b,axis=1)
    loss = tf.reduce_mean(tf.losses.MSE(tf.one_hot(y,depth=3),prob))

grads = tape.gradient(loss,[w,b])


print(grads[0])
"""
输出:
tf.Tensor(
[[-5.5192433e-02 -4.8389734e-06  5.5197272e-02]
 [ 3.6337111e-02  1.7934163e-04 -3.6516447e-02]
 [-4.5821436e-02  1.3292905e-04  4.5688514e-02]
 [ 3.6436778e-02 -5.4880476e-04 -3.5887983e-02]], shape=(4, 3), dtype=float32)
"""


print(grads[1])
"""
输出:
tf.Tensor([-0.02586884  0.00025355  0.0256153 ], shape=(3,), dtype=float32)
"""



#举例-Crossentropy gradient
x = tf.random.normal([2,4],seed=1)
w = tf.random.normal([4,3],seed=1)
b = tf.zeros([3])
y = tf.constant([2,0])

with tf.GradientTape() as tape:
    tape.watch([w,b])
    logits = x@w+b
    loss = tf.reduce_mean(tf.losses.categorical_crossentropy(tf.one_hot(y,depth=3),logits))

grads = tape.gradient(loss,[w,b])

print(grads[0])
"""
输出:
tf.Tensor(
[[-0.08838065 -0.06390739  0.03672602]
 [ 0.08741999  0.23320754  0.04906246]
 [-0.0506487   0.09553305  0.0874298 ]
 [-0.03325637 -0.55674076 -0.25375524]], shape=(4, 3), dtype=float32)
"""

print(grads[1])
"""
输出:
tf.Tensor([0.00102822 0.24761406 0.12357714], shape=(3,), dtype=float32)
"""

参考:
https://blog.csdn.net/suiyueruge1314/article/details/103963598

你可能感兴趣的:(tensorflow2.0,tensorflow,python)