Tensorflow tf.gradients 详解

tf.gradients

gradients(
ys,
xs,
grad_ys=None,
name=‘gradients’,
colocate_gradients_with_ops=False,
gate_gradients=False,
aggregation_method=None
)
在 xs 中构造了 ys 的 w.r.t. x 和的符号偏导数.
ys 和 xs 是一个张量或一个张量的列表.grad_ys 是一个张量列表,持有由 ys 接收的梯度.该列表必须与 ys 具有相同长度.

gradients() 向图形添加操作以输出 ys 相对于的偏导数 xs.它返回长度为 len (xs) 的张量列表,其中每个张量 ys 中 y 的 sum(dy/dx).
grad_ys 是与 ys 相同长度的张量列表,它包含 y 的初始梯度.当 grad_ys 是 None 时,我们在 ys 中为每个 y 填入一个1的形状的张量.用户可以提供自己的初始 grad_ys,使用不同的初始梯度为每个 y 计算导数 (例如:如果你想为每个 y 中的每个值不同地加权梯度).

参数:

ys:要区分的张量或者张量列表.
xs:用于微分的张量或者张量列表.
grad_ys:(可选)与 ys 具有相同大小的张量或张量列表,并且对 ys 中的每个 y 计算的梯度.
name:用于将所有渐变操作组合在一起的可选名称.默认为“渐变”.
colocate_gradients_with_ops:如果为 True,请尝试使用相应的操作对齐梯度.
gate_gradients:如果为True,则在操作返回的梯度周围添加一个元组.这避免了一些竞态条件.
aggregation_method:指定用于组合渐变项的方法.接受的值是在类 AggregationMethod 中定义的常量.

返回值:
该函数返回 xs 中每个 x 的 sum(dy/dx) 的列表.

可能引发的异常:
LookupError:如果 x 和 y 之间的一个操作是没有注册的梯度函数.
ValueError:如果参数无效.

对求导函数而言,其主要功能即求导公式:∂y/∂x。在tensorflow中,y和x都是tensor。
更进一步,tf.gradients()接受求导值ys和xs不仅可以是tensor,还可以是list,形如[tensor1, tensor2, …, tensorn]。当ys和xs都是list时,它们的求导关系为:
gradients() adds ops to the graph to output the derivatives of ys with respect to xs. It returns a list of Tensor of length len(xs) where each tensor is the sum(dy/dx) for y in ys.

意思是:
1 tf.gradients()实现ys对xs求导
2.求导返回值是一个list,list的长度等于len(xs)
3.假设返回值是[grad1, grad2, grad3],ys=[y1, y2],xs=[x1, x2, x3]。则,真实的计算过程为:
grad1=∂y1/∂x1+∂y2/∂x1
grad2=∂y1/∂x2+∂y2/∂x2
grad3=∂y1/∂x3+∂y2/∂x3

测试1如下:
import tensorflow as tf
tf.reset_default_graph()
w1 = tf.get_variable(‘w1’, shape=[3])
w2 = tf.get_variable(‘w2’, shape=[3])

w3 = tf.get_variable(‘w3’, shape=[3])
w4 = tf.get_variable(‘w4’, shape=[3])

z1 = 3 * w1 + 2 * w2+ w3
z2 = -1 * w3 + w4

grads = tf.gradients([z1, z2], [w1, w2, w3, w4])

with tf.Session() as sess:
tf.global_variables_initializer().run()
print(sess.run(grads))

输出:
[array([3., 3., 3.], dtype=float32), array([2., 2., 2.], dtype=float32), array([0., 0., 0.], dtype=float32), array([1., 1., 1.], dtype=float32)]

计算过程如下:
array([3., 3., 3.], dtype=float32)=z1/w1+z2/w1=3+0=3
array([2., 2., 2.], dtype=float32)=z1/w2+z2/w2=2+0=2
array([0., 0., 0.], dtype=float32)=z1/w3+z2/w3=1+(-1)=0
array([1., 1., 1.], dtype=float32)=z1/w4+z2/w4=0+1=1
因为w1,w2,w3,w4是3维的,所以返回的梯度Tensor也是3维的,例如:[3., 3., 3.]

测试2,加grad_ys测试:
import tensorflow as tf
tf.reset_default_graph()
w1 = tf.get_variable(‘w1’, shape=[3])
w2 = tf.get_variable(‘w2’, shape=[3])

w3 = tf.get_variable(‘w3’, shape=[3])
w4 = tf.get_variable(‘w4’, shape=[3])

z1 = 3 * w1 + 2 * w2+ w3
z2 = -1 * w3 + w4

grads = tf.gradients([z1, z2], [w1, w2, w3, w4], grad_ys=[[-2.0, -3.0, -4.0], [-1.0, -2.0, -3.0]])

with tf.Session() as sess:
tf.global_variables_initializer().run()
print(sess.run(grads))

输出如下:
[array([ -6., -9., -12.], dtype=float32), array([-4., -6., -8.], dtype=float32), array([-1., -1., -1.], dtype=float32), array([-1., -2., -3.], dtype=float32)]

grad_ys 为什么是两个张量,因为grad_ys是和ys具有相同长度的。而这里ys有两个张量z1,z2,所以grad_ys也需要两个张量。

计算过程如下:
array([ -6., -9., -12.], dtype=float32)
-6= z1*(-2)/w1+z2*(-1)/w1=3*(-2)+0=-6
-9= z1*(-3)/w1+z2*(-2)/w1=3*(-3)+0=-9
-12= z1*(-4)/w1+z2*(-3)/w1=3*(-4)+0=-12

array([-4., -6., -8.], dtype=float32)
-4= z1*(-2)/w2+z2*(-1)/w2=2*(-2)+0=-4
-6= z1*(-3)/w2+z2*(-2)/w2=2*(-3)+0=-6
-8= z1*(-4)/w2+z2*(-3)/w2=2*(-4)+0=-8

array([-1., -1., -1.], dtype=float32)
-1= z1*(-2)/w3+z2*(-1)/w3=1*(-2)+(-1)(-1)=-1
-1= z1
(-3)/w3+z2*(-2)/w3=1*(-3)+(-2)(-1)=-1
-1= z1
(-4)/w3+z2*(-3)/w3=1*(-4)+(-3)*(-1)=-1

array([-1., -2., -3.], dtype=float32)
-1= z1*(-2)/w4+z2*(-1)/w4=0*(-2)+(1)(-1)=-1
-2= z1
(-3)/w4+z2*(-2)/w4=0*(-3)+(1)(-2)=-2
-3= z1
(-4)/w4+z2*(-3)/w4=0*(-4)+(1)*(-3)=-3

测试3:
import tensorflow as tf
weight = tf.Variable([[1., 2.]])
y = tf.matmul(weight, [[9.], [10.]])
grads = tf.gradients(y, weight)

with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
grad_val = sess.run(grads)
print(grad_val)

输出:
[array([[ 9., 10.]], dtype=float32)]

测试4 stop_gradient:
a = tf.Variable(1.0)
b = tf.Variable(1.0)

c = tf.add(a, b)
c_stoped = tf.stop_gradient( c)
d = tf.add(a, b)
e = tf.add(c_stoped, d)

gradients = tf.gradients(e, xs=[a, b])

with tf.Session() as sess:
tf.global_variables_initializer().run()
print(sess.run(gradients))

输出:
[1.0, 1.0]

测试5,stop_gradient的使用:
import tensorflow as tf
a = tf.Variable(1.0)
b = tf.Variable(1.0)

c = tf.add(a, b)

c_stoped = tf.stop_gradient( c)
d = tf.add(a, b)
e = tf.add(c, d)

gradients = tf.gradients(e, xs=[a, b])

with tf.Session() as sess:
tf.global_variables_initializer().run()
print(sess.run(gradients))

输出:[2.0, 2.0]

测试6,高阶导数计算:
import tensorflow as tf
with tf.device(’/cpu:0’):
a = tf.constant(2.)
b = tf.pow(a, 2.)
grad = tf.gradients(ys=b, xs=a) # 一阶导
grad_2 = tf.gradients(ys=grad[0], xs=a) # 二阶导
grad_3 = tf.gradients(ys=grad_2[0], xs=a) # 三阶导

with tf.Session() as sess:
print(sess.run(grad))
print(sess.run(grad_2))
print(sess.run(grad_3))

输出:
[4.0]
[2.0]
[0.0]

计算过程如下:
a=2, b=a^2
grad=∂a^2/∂a=2a=2*2=4
grad_2=∂2a/∂a=2
grad_3=∂2/∂a=0

测试7:
import tensorflow as tf
a = tf.constant(0.)
b=2*a
c = a + b
g = tf.gradients(c, [a, b])

with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(g))
输出:
[3.0, 1.0]

测试8:
import tensorflow as tf
a = tf.constant(0.)
b=2*a
g = tf.gradients(a + b, [a, b], stop_gradients=[a, b])

with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(g))
输出:
[1.0, 1.0]

或者等价于下面的代码:
import tensorflow as tf
a = tf.stop_gradient(tf.constant(0.))
b = tf.stop_gradient(2 * a)
g = tf.gradients(a + b, [a, b])

with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(g))

输出:[1.0, 1.0]

测试9:
import tensorflow as tf
tf.reset_default_graph()
weight1 = tf.get_variable(‘weight1’, shape=[2])
weight2 = tf.get_variable(‘weight2’, shape=[2])
weight3 = tf.get_variable(‘weight3’, shape=[2])
weight4 = tf.get_variable(‘weight4’, shape=[2])

a = weight1 + weight2
a_stopped = tf.stop_gradient(a)
y3 = a_stopped + weight3

gradients1 = tf.gradients(y3, [weight1, weight2, weight3], grad_ys=[tf.convert_to_tensor([1., 2.])])
gradients2 = tf.gradients(y3, [weight3], grad_ys=[tf.convert_to_tensor([1., 2.])])
print(gradients1) # [None, None, < tf.Tensor ‘gradients_1/grad_ys_0:0’ shape = (2,) dtype = float32 >]
print(gradients2)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
‘’’
下面代码会报错
因为weight1、weight2 的梯度被停止,程序试图去求一个None的梯度,所以报错
注释掉求 gradients2 就又正确了
‘’’
#print(sess.run(gradients1))
print(sess.run(gradients2))

输出:
[None, None, <tf.Tensor ‘gradients/grad_ys_0:0’ shape=(2,) dtype=float32>]
[<tf.Tensor ‘gradients_1/grad_ys_0:0’ shape=(2,) dtype=float32>]
[array([1., 2.], dtype=float32)]

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: `tf.gradients()`是TensorFlow中用于计算梯度的函数,它的用法如下: ``` grads = tf.gradients(target, sources, colocate_gradients_with_ops=False) ``` 其中,`target`是需要计算梯度的Tensor或Operation,`sources`是需要计算`target`对其梯度的Tensor或Operation的列表(可以是一个Tensor或Operation,也可以是一个Tensor或Operation的列表),`colocate_gradients_with_ops`是一个布尔值,用于指定计算梯度的操作是否应该与源操作放在同一个设备上(默认为`False`)。 `tf.gradients()`的返回值`grads`是一个与`sources`相同长度的列表,其中每个元素是对应源Tensor或Operation的梯度。如果某个源Tensor或Operation的梯度不存在,则对应的元素为`None`。 需要注意的是,`tf.gradients()`只能计算标量对Tensor或Operation的梯度,因此如果`target`不是标量,则需要通过将`target`中的多个元素相加来将其转换为标量。另外,`tf.gradients()`计算出的梯度通常需要通过调用优化器来更新模型参数。 ### 回答2: tf.gradients 是 TensorFlow 中的一个函数,用于计算某个张量对于某些其他张量的梯度。梯度是一个向量,表示了张量在每个维度上的变化率。 该函数的输入参数包括目标张量和某个可训练的张量列表。目标张量是需要计算梯度的张量,而可训练的张量列表是计算梯度所需要的参考张量。 tf.gradients 函数利用 TensorFlow 中的自动微分技术(即反向传播算法)来计算张量的梯度。在计算过程中,TensorFlow 会自动构建计算图并追踪所有相关操作,然后根据链式法则计算梯度。 通过调用 tf.gradients 函数,我们可以获得目标张量对于参考张量的梯度。得到的梯度可以被用于更新模型参数、计算损失函数关于模型参数的梯度等。 总之,tf.gradients 函数在 TensorFlow 中扮演着重要的角色,用于计算张量的梯度。它使得我们可以方便地进行自动微分,并利用梯度来优化模型和进行训练。 ### 回答3: tf.gradients是TensorFlow中的一个函数,用于计算某个目标张量相对于输入张量的梯度。梯度可以理解为目标张量对输入张量的变化率。 tf.gradients函数接收两个参数:目标张量和输入张量(或一组输入张量)。它返回一个与输入张量维度相同的列表,表示目标张量相对于每个输入张量的梯度。 例如,假设有一个简单的线性模型y = mx + b,其中m和b是可训练的变量,x是输入张量。我们想要计算目标张量y相对于输入张量x的梯度。可以使用以下代码: import tensorflow as tf # 定义模型参数 m = tf.Variable(2.0) b = tf.Variable(1.0) # 定义输入张量 x = tf.constant(3.0) # 定义目标张量 y = tf.multiply(m, x) + b # 计算梯度 grads = tf.gradients(y, x) # 创建会话并运行计算图 with tf.Session() as sess: sess.run(tf.global_variables_initializer()) gradients = sess.run(grads) print(gradients) 运行上述代码,可以得到目标张量y相对于输入张量x的梯度,结果为[2.0]。这表示当输入张量x增加1个单位时,目标张量y增加2个单位。 通过使用tf.gradients函数,我们可以自动计算模型中各个参数相对于目标张量的梯度,进而使用梯度下降等优化算法来更新模型参数,使其不断逼近最优解。这是深度学习中非常重要的一个操作,有助于实现模型的训练和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值