我已经回答了here,但我猜它不是很有用,因为您不能使用这些知识来区分非标量y。标量假设是反向 AD 算法设计的核心,没有一个地方可以修改以支持非标量 ys。由于这种混乱不断出现,让我更详细地解释一下为什么它不是微不足道的:
首先,逆向 AD 是如何工作的——假设我们有一个函数 f,它是组件函数 f_i 的组合。每个分量函数接受一个长度为 n 的向量,并产生一个长度为 n 的向量。
它的导数可以表示为一系列矩阵乘法。整个表达式可以如下表示。
在微分时,函数组合变成对应分量函数雅可比矩阵的矩阵乘法。
请注意,这涉及矩阵/矩阵乘积,这对于神经网络来说太昂贵了。 IE,AlexNet 在其 convnet->fc 转换层中包含 8k 个激活。在每个矩阵为 8k x 8k 的情况下进行矩阵倍数会花费太长时间。使其高效的技巧是假设链中的最后一个函数产生一个标量。那么它的雅可比是一个向量,整个事情可以用向量-矩阵乘法来重写,而不是矩阵-矩阵乘法。
这个乘积可以通过从左到右进行乘法有效地计算,因此您所做的一切都是 nxn 向量矩阵乘法而不是 nxn 矩阵矩阵乘法。
您可以通过从不首先形成那些 nxn 导数矩阵来提高效率,并将每个分量函数与隐式执行向量 x Jacobian 矩阵乘积的运算相关联。这就是 TensorFlow tf.RegisterGradient 所做的。这是与组件函数关联的“grad”的图示。
现在,这是为向量值函数完成的,如果你的函数是矩阵值怎么办?这是我们在神经网络中处理的典型情况。 IE,在进行矩阵乘法的层中,您乘以的矩阵是未知数,它是矩阵值。在这种情况下,最后一个导数的秩为 2,其余导数的秩为 3。
现在要应用链式法则,您必须处理额外的符号,因为现在链式法则中的“x”表示矩阵乘法泛化到 3 阶张量。
但是,请注意,由于我们使用的是 grad 运算符,因此我们不必显式地进行乘法运算。所以现在在实践中,这个运算符现在采用 rank-2 的值并产生 rank-2 的值。
所以在所有这些中,假设最终目标是标量,这允许通过传递矩阵来区分完全连接的层。
如果您想扩展它以支持非标量向量,您需要修改反向 AD 算法以传播更多信息。 IE,对于完全连接的前馈网络,您将传播 rank-3 张量而不是矩阵。