You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TensorFlow中标量与矩阵逐元素乘积的导数计算结果异常问题

TensorFlow中逐元素乘积对标的量导数的形状不符问题

问题背景

x为标量(或形状为(1,1)的张量),B是5×5的二维张量,f是x与B的逐元素乘积(即f[i,j] = x*B[i,j]),需要计算f对x的导数,但得到的结果形状与预期不符。

测试环境:TensorFlow 2.17.0、2.12.0

复现代码

import tensorflow as tf
import numpy as np

with tf.GradientTape(persistent=True) as g:
    x = tf.Variable(np.random.uniform(size=(1,1)), dtype=tf.float64)
    B = tf.convert_to_tensor(np.random.normal(size=(5,5)), dtype=tf.float64)
    g.watch(x)
    g.watch(B)

    f = tf.multiply(B, x)

    gr = g.gradient(f, x)

结果对比

  • 预期结果:gr.shape为(5, 5),每个元素对应f[i,j]对x的导数(即B[i,j])
  • 实际结果:gr.shape为(1, 1)(若x是纯标量则为()),且值等于B所有元素的总和
  • 验证:f.shape为(5, 5),符合逐元素乘积的预期

原因分析

TensorFlow的GradientTape.gradient()方法默认会对输出张量的所有元素求和,再计算该总和对自变量的导数。对于本场景:

  • sum(f) = sum(x*B[i,j]) = x * sum(B)
  • 该总和对x的导数就是sum(B),因此结果的形状与x一致((1,1)或标量),而非与f一致。

解决方案

如果需要得到输出张量每个元素对x的导数(即形状与f匹配的梯度),需要使用GradientTape.jacobian()方法——它会计算输出张量每个元素对输入变量的导数,生成雅可比矩阵:

import tensorflow as tf
import numpy as np

with tf.GradientTape(persistent=True) as g:
    x = tf.Variable(np.random.uniform(size=(1,1)), dtype=tf.float64)
    B = tf.convert_to_tensor(np.random.normal(size=(5,5)), dtype=tf.float64)
    g.watch(x)
    g.watch(B)

    f = tf.multiply(B, x)

    # 计算雅可比矩阵,默认形状为(5,5,1,1)
    gr = g.jacobian(f, x)
    # 压缩多余维度,得到(5,5)的结果
    gr = tf.squeeze(gr, axis=[2, 3])

此时gr.shape为(5,5),每个元素gr[i,j]等于B[i,j],完全符合数学推导的结果。

内容的提问来源于stack exchange,提问作者Yose Keiree

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 20:00:02