神经网络在更新参数时,梯度的计算十分重要
tensorflow 提供了GradientTape函数,实现梯度的计算。
GradientTape 意思为梯度带
GradientTape 参数
persistent : 默认是False.
如果是false,那么gradient()函数最多只能调用一次。反之可以调用多次,
watch_accessed_variables : 默认值是True,
可以自动对任何Tensorflow 的Variable求梯度。
如果是False,那么只能显示调用Watch()方法对某些变量就梯度了
案例1 persistent默认只能求一次梯度
import tensorflow as tf
x= tf.Variable(initial_value=3.0)
with tf.GradientTape() as g:
y = x * x
dy_dx = g.gradient(y, x) # Will compute to 6.0
print(dy_dx)
dy_dx = g.gradient(y, x)
print(dy_dx)
默认情况下(persistent 是false 意思为不连续的),GradientTape 只能计算一次第二次会报错
案例2 persistent设置为True可以求多次梯度
import tensorflow as tf
x= tf.Variable(initial_value=3.0)
with tf.GradientTape(persistent=True) as g:
y = x * x
dy_dx = g.gradient(y, x) # Will compute to 6.0
print(dy_dx)
dy_dx = g.gradient(y, x)
print(dy_dx)
将persistent 设置为true,可以多次计算了
案例3 常量怎么求梯度
import tensorflow as tf
x= tf.Variable(initial_value=3.0)
with tf.GradientTape(persistent=True) as g:
y = x * x
dy_dx = g.gradient(y, x) # Will compute to 6.0
print(dy_dx)
x = tf.constant(3.0)
with tf.GradientTape(persistent=True) as g1:
y = x * x
dy_dx = g1.gradient(y, x) # 我们对于常量是不能进行梯度计算的
print(dy_dx)
with tf.GradientTape(persistent=True) as g1:
g1.watch(x)
y = x * x
dy_dx = g1.gradient(y, x) # Will compute to 6.0
print(dy_dx)
执行结果是
那对于常量我们不能对其进行求梯度,虽然加上 watch函数就可以了,但我不知道为什么不直接设置x为变量呢?
是变量会比较节约资源吗?
案例4 梯度计算之后再进行梯度计算
import tensorflow as tf
x = tf.constant(3.0)
with tf.GradientTape() as g:
g.watch(x)
with tf.GradientTape() as gg:
gg.watch(x)
y = x * x
dy_dx = gg.gradient(y, x) # Will compute to 6.0
print(dy_dx)
d2y_dx2 = g.gradient(dy_dx, x) # Will compute to 2.
print(d2y_dx2)
由上述代码可见 y=x^2 ,第一层得到 y`=2x 第二层得到y``=2
案例5 梯度带中含有多个梯度
import tensorflow as tf
x = tf.constant(3.0)488
dz_dx = g.gradient(z, x) # 108.0 (4*x^3 at x = 3)
print(dz_dx)
dy_dx = g.gradient(y, x) # 6.0
print(dy_dx)
其他情况
- 对tf相关的函数求梯度
- 对二元函数求梯度 这个包含了偏导
更新梯度
Tensorflow 提供了 apply_gradients(grads_and_vars,name=None) 方法
num_epoch = 10000
optimizer = tf.keras.optimizers.SGD(learning_rate=5e-4)
for e in range(num_epoch):
with tf.GradientTape() as tape: # 使用tf.GradientTape()记录损失函数的梯度信息
y_pred = a * X + b
loss = tf.reduce_sum(tf.square(y_pred - y))
grads = tape.gradient(loss, variables) # TensorFlow自动计算损失函数关于自变量(模型参数)的梯度
optimizer.apply_gradients(grads_and_vars=zip(grads, variables))
参数是 损失函数对变量的导数(一般包含两个变量,权值w 和偏置 b)
即多元函数求导
with tf.GradientTape() as tape:
L = tf.reduce_sum(tf.square(tf.matmul(X, w) + b - y))
w_grad, b_grad = tape.gradient(L, [w, b]) # 计算L(w, b)关于w, b的偏导数
w_grad, b_grad 就是上文中的 grads