【问题标题】:Tensorflow aggregates scalar-tensor multiplication gradientTensorflow 聚合标量-张量乘法梯度
【发布时间】:2021-04-16 23:15:10
【问题描述】:

假设我将一个向量与一个标量相乘,例如:

a = tf.Variable(3.)
b = tf.Variable([1., 0., 1.])

with tf.GradientTape() as tape:
   c = a*b

grad = tape.gradient(c, a)

我得到的梯度是一个标量,

<tf.Tensor: shape=(), dtype=float32, numpy=2.0>

而我们期望向量:

<tf.Variable 'Variable:0' shape=(3,) dtype=float32, numpy=array([1., 0., 1.], dtype=float32)>

查看其他示例,似乎 tensorflow 对预期向量求和,也用于标量矩阵乘法等。 为什么张量流会这样做?使用@custum_gradient 可能可以避免这种情况,是否有另一种不太麻烦的方法来获得正确的渐变?

似乎有一些相关的问题,但这些似乎都考虑了在训练批次上聚合的损失函数的梯度。这里没有使用损失函数或聚合,所以我认为问题是别的?

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    您获得了缩放器的价值,因为您使用了梯度 wrt 缩放器。如果您将 grad wrt 带入某个向量,您将得到一个向量。看看下面的例子:

    import tensorflow as tf 
    
    a = tf.Variable(3.,  trainable=True)
    b = tf.Variable([1., 0, 1.],  trainable=True)
    c = tf.Variable(2., trainable=True)
    d = tf.Variable([2., 1, 2.],  trainable=True)
    
    with tf.GradientTape(persistent=True) as tape:
       e = a*b*c*d # abcd , abcd , abcd
       tf.print(e)
    
    grad = tape.gradient(e, [a, b, c, d])
    grad[0].numpy(), grad[1].numpy(), grad[2].numpy(), grad[3].numpy()
    
    [12 0 12]
    (8.0,
     array([12.,  6., 12.], dtype=float32),
     12.0,
     array([6., 0., 6.], dtype=float32))
    

    【讨论】:

      【解决方案2】:

      形式上,我正在寻找的是向量场的微分,它是变量a 的函数。对于向量场,微分与雅可比相同。原来我要找的可以通过tape.jacobian来完成。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-08-21
        • 2016-08-20
        • 1970-01-01
        • 1970-01-01
        • 2022-01-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多