在 tensorflow gradients 中哪里是 y 元素的总和?
Where in tensorflow gradients is the sum over the elements of y made?
我正在尝试对张量流中的 tf.gradient
进行黑客攻击,对于等级为 (M,N) 的张量 y
和等级为 (的张量 x
Q,P) 等级为 (M,N,Q,P) 的梯度张量,正如人们自然期望的那样。
正如本站多个问题中所指出的*,得到的是一个等级(Q,P),它是y
的元素之和的梯度。现在我想不通的是,查看 tensorflow 代码是在哪里对 y
的元素求和?它是开始还是结束?有人可以帮我查明完成的代码行吗?
*
- Tensorflow gradients: without automatic implicit sum
- Separate gradients in tf.gradients
我已经回答了它 here 但我猜它不是很有用,因为你不能使用这些知识来区分非标量 y
。标量假设是反向 AD 算法设计的核心,没有一个地方可以修改以支持非标量 y
s。由于这种困惑不断出现,让我更详细地说明一下为什么它很重要:
首先,反向 AD 是如何工作的——假设我们有一个函数 f,它是组件函数的组合 f_i。每个分量函数接受一个长度为 n 的向量并生成一个长度为 n 的向量。
它的导数可以表示为一系列矩阵乘法。整个表达式可以表示如下。
微分时,函数组合变成对应分量函数雅可比矩阵乘法。
请注意,这涉及 matrix/matrix 产品,这些产品被证明对于神经网络而言过于昂贵。 IE,AlexNet 在其 convnet->fc 转换层中包含 8k 个激活。在每个矩阵为 8k x 8k 的情况下进行矩阵乘法会花费太长时间。使其高效的技巧是假设链中的最后一个函数产生一个标量。然后它的雅可比矩阵是一个向量,整个事情可以用向量-矩阵乘法而不是矩阵-矩阵乘法来重写。
可以通过从左到右进行乘法来高效计算该乘积,因此您所做的一切都是 nxn 向量-矩阵乘法,而不是 nxn 矩阵-矩阵乘法。
您可以通过从不首先形成那些 nxn 导数矩阵并将每个分量函数与隐式执行向量 x 雅可比矩阵乘积的运算相关联来使其更加高效。这就是 TensorFlow tf.RegisterGradient
所做的。这是与组件函数关联的 "grad" 的示例。
现在,这是针对向量值函数完成的,如果您的函数是矩阵值呢?这是我们在神经网络中处理的典型情况。 IE,在一个做矩阵乘法的层中,你乘以的矩阵是一个未知数,它是矩阵值。在这种情况下,最后一个导数的秩为 2,其余导数的秩为 3。
现在要应用链式法则,您必须处理额外的符号,因为现在 "x" 在链式法则中意味着矩阵乘法推广到 3 阶张量。
但是请注意,由于我们使用的是渐变运算符,因此我们不必显式地进行乘法运算。所以现在在实践中,这个运算符现在采用 rank-2 的值并产生 rank-2 的值。
所以在所有这些中,假设最终目标是标量,它允许通过传递矩阵来区分完全连接的层。
如果您想扩展它以支持非标量向量,您需要修改反向 AD 算法以传播更多信息。 IE,对于完全连接的前馈网络,您将传播 rank-3 张量而不是矩阵。
使用 Tensorflow 2 中的 jacobian 函数,这是一项简单的任务。
with tf.GradientTape() as tape1:
with tf.GradientTape() as tape2:
y = layer(x)
loss = tf.reduce_mean(y ** 2)
first_order_gradient = tape2.gradient(loss, layer.trainable_weights)
hessian = tape1.jacobian(first_order_gradient, layer.trainable_weights)
我正在尝试对张量流中的 tf.gradient
进行黑客攻击,对于等级为 (M,N) 的张量 y
和等级为 (的张量 x
Q,P) 等级为 (M,N,Q,P) 的梯度张量,正如人们自然期望的那样。
正如本站多个问题中所指出的*,得到的是一个等级(Q,P),它是y
的元素之和的梯度。现在我想不通的是,查看 tensorflow 代码是在哪里对 y
的元素求和?它是开始还是结束?有人可以帮我查明完成的代码行吗?
*
- Tensorflow gradients: without automatic implicit sum
- Separate gradients in tf.gradients
我已经回答了它 here 但我猜它不是很有用,因为你不能使用这些知识来区分非标量 y
。标量假设是反向 AD 算法设计的核心,没有一个地方可以修改以支持非标量 y
s。由于这种困惑不断出现,让我更详细地说明一下为什么它很重要:
首先,反向 AD 是如何工作的——假设我们有一个函数 f,它是组件函数的组合 f_i。每个分量函数接受一个长度为 n 的向量并生成一个长度为 n 的向量。
它的导数可以表示为一系列矩阵乘法。整个表达式可以表示如下。
微分时,函数组合变成对应分量函数雅可比矩阵乘法。
请注意,这涉及 matrix/matrix 产品,这些产品被证明对于神经网络而言过于昂贵。 IE,AlexNet 在其 convnet->fc 转换层中包含 8k 个激活。在每个矩阵为 8k x 8k 的情况下进行矩阵乘法会花费太长时间。使其高效的技巧是假设链中的最后一个函数产生一个标量。然后它的雅可比矩阵是一个向量,整个事情可以用向量-矩阵乘法而不是矩阵-矩阵乘法来重写。
可以通过从左到右进行乘法来高效计算该乘积,因此您所做的一切都是 nxn 向量-矩阵乘法,而不是 nxn 矩阵-矩阵乘法。
您可以通过从不首先形成那些 nxn 导数矩阵并将每个分量函数与隐式执行向量 x 雅可比矩阵乘积的运算相关联来使其更加高效。这就是 TensorFlow tf.RegisterGradient
所做的。这是与组件函数关联的 "grad" 的示例。
现在,这是针对向量值函数完成的,如果您的函数是矩阵值呢?这是我们在神经网络中处理的典型情况。 IE,在一个做矩阵乘法的层中,你乘以的矩阵是一个未知数,它是矩阵值。在这种情况下,最后一个导数的秩为 2,其余导数的秩为 3。
现在要应用链式法则,您必须处理额外的符号,因为现在 "x" 在链式法则中意味着矩阵乘法推广到 3 阶张量。
但是请注意,由于我们使用的是渐变运算符,因此我们不必显式地进行乘法运算。所以现在在实践中,这个运算符现在采用 rank-2 的值并产生 rank-2 的值。
所以在所有这些中,假设最终目标是标量,它允许通过传递矩阵来区分完全连接的层。
如果您想扩展它以支持非标量向量,您需要修改反向 AD 算法以传播更多信息。 IE,对于完全连接的前馈网络,您将传播 rank-3 张量而不是矩阵。
使用 Tensorflow 2 中的 jacobian 函数,这是一项简单的任务。
with tf.GradientTape() as tape1:
with tf.GradientTape() as tape2:
y = layer(x)
loss = tf.reduce_mean(y ** 2)
first_order_gradient = tape2.gradient(loss, layer.trainable_weights)
hessian = tape1.jacobian(first_order_gradient, layer.trainable_weights)