Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python GradientTape.gradient的概念性理解 背景_Python_Deep Learning_Neural Network_Tensorflow2.0 - Fatal编程技术网

Python GradientTape.gradient的概念性理解 背景

Python GradientTape.gradient的概念性理解 背景,python,deep-learning,neural-network,tensorflow2.0,Python,Deep Learning,Neural Network,Tensorflow2.0,在Tensorflow 2中,存在一个名为GradientTape的类,该类用于记录对张量的操作,然后可以区分这些操作的结果并将其提供给某些最小化算法。例如,我们有以下示例: x = tf.constant(3.0) with tf.GradientTape() as g: g.watch(x) y = x * x dy_dx = g.gradient(y, x) # Will compute to 6.0 gradient方法的参数表示第一个参数不仅可以是张量,还可以是张量列表:

在Tensorflow 2中,存在一个名为
GradientTape
的类,该类用于记录对张量的操作,然后可以区分这些操作的结果并将其提供给某些最小化算法。例如,我们有以下示例:

x = tf.constant(3.0)
with tf.GradientTape() as g:
  g.watch(x)
  y = x * x
dy_dx = g.gradient(y, x) # Will compute to 6.0
gradient
方法的参数表示第一个参数不仅可以是张量,还可以是张量列表:

 def gradient(self,
               target,
               sources,
               output_gradients=None,
               unconnected_gradients=UnconnectedGradients.NONE):
    """Computes the gradient using operations recorded in context of this tape.

    Args:
      target: a list or nested structure of Tensors or Variables to be
        differentiated.
      sources: a list or nested structure of Tensors or Variables. `target`
        will be differentiated against elements in `sources`.
      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'.

    Returns:
      a list or nested structure of Tensors (or IndexedSlices, or None),
      one for each element in `sources`. Returned structure is the same as
      the structure of `sources`.

    Raises:
      RuntimeError: if called inside the context of the tape, or if called more
       than once on a non-persistent tape.
      ValueError: if the target is a variable or if unconnected gradients is
       called with an unknown value.
    """
在上面的示例中,很容易看出,
y
目标
,是要区分的函数,
x
是关于“梯度”的因变量

根据我有限的经验,
梯度
方法似乎会返回一个张量列表,每个
元素一个,这些梯度中的每个都是与
对应成员形状相同的张量

问题: 如果
目标
包含要区分的单个1x1“张量”,则上述对
梯度行为的描述是有意义的,因为从数学上讲,梯度向量应该与函数域的维数相同


但是,如果
target
是张量列表,则
渐变的输出仍然是相同的形状。为什么会这样?如果
target
被认为是一个函数列表,那么输出不应该类似于雅可比矩阵吗?我如何从概念上解释这种行为?

这就是
tf.GradientTape().gradient()
的定义。它与tf.gradients()具有相同的功能,只是后者不能在急切模式下使用。从
tf.gradients()的

它返回长度
len(xs)
的张量列表,其中每个张量是y在ys中的
和(dy/dx)

其中,
xs
ys
目标

示例1

所以让我们假设
target=[y1,y2]
sources=[x1,x2]
。结果将是:

[dy1/dx1 + dy2/dx1, dy1/dx2 + dy2/dx2]
示例2

计算每个样本的损失(张量)与减少的损失(标量)的梯度

上述片段的Tensorflow示例:

将tensorflow导入为tf
打印(tf.uuu版本)#2.1.0
输入=tf。将_转换为_张量([[0.1,0],[0.5,0.51]])#两个二维样本
w=tf.变量(初始值=输入)
b=tf.变量(tf.零((2,))
labels=tf.convert_to_tensor([0,1])
def转发(输入、标签、变量列表):
w、 b=变量列表
logits=tf.matmul(输入,w)+b
xentropy=tf.nn.sparse\u softmax\u cross\u熵(
标签=标签,登录=登录)
返回熵
#“xentropy”有两个元素(张量梯度-梯度)
#(一批中每个样品的数量)
将tf.GradientTape()作为g:
xentropy=正向(输入、标签、[w、b])
减少的X熵=tf.减少的X熵平均值(X熵)
梯度=梯度(X熵,[w,b])
打印(xentropy.numpy())#[0.6881597 0.71584916]
打印(grads[0].numpy())#[0.20586157-0.20586154]
#  [ 0.2607238  -0.26072377]]
#`reduced_xentropy`是标量(标量的梯度)
将tf.GradientTape()作为g:
xentropy=正向(输入、标签、[w、b])
减少的X熵=tf.减少的X熵平均值(X熵)
梯度减少=梯度(减少的熵,[w,b])

print(reduced_xentropy.numpy())35; 0.70200443这很有意义,是对文档的一个很好的解释,但它仍然回避了一个问题:为什么梯度不是雅可比矩阵的列表。现在我有一个场景,我想要一个雅可比矩阵列表,而不是偏导数的总和……啊,我现在看到了tf.python.ops.gradients.jacobian。我还没有让它在TF1.12中工作,但至少它存在。。。
Let w, b be two variables. 
xentropy = [y1, y2] # tensor
reduced_xentropy = 0.5 * (y1 + y2) # scalar
grads = [dy1/dw + dy2/dw, dy1/db + dy2/db]
reduced_grads = [d(reduced_xentropy)/dw, d(reduced_xentropy)/db]
              = [d(0.5 * (y1 + y2))/dw, d(0.5 * (y1 + y2))/db] 
              == 0.5 * grads