【问题标题】:tf.gradient acting like tfp.math.diag_jacobiantf.gradient 表现得像 tfp.math.diag_jacobian
【发布时间】:2019-03-12 12:23:21
【问题描述】:

我尝试使用来自输入数据的损失函数的梯度来计算输入数据的噪声:

my_grad = tf.gradients(loss, input)

loss 是一个大小为 (n x 1) 的数组,其中 n 是数据集的数量,m 是数据集的大小,输入是一个 (n x m) 的数组,其中 m 是单个数据集的大小。

我需要 my_grad 的大小为 (n x m) - 因此对于每个数据集计算梯度。但根据定义,i!=j 的梯度为零 - 但 tf.gradients 分配了大量内存并且几乎可以运行...

一个版本,它只计算 i=j 的梯度 - 知道如何到达那里吗?

【问题讨论】:

    标签: python tensorflow diagonal gradient


    【解决方案1】:

    我想我已经找到了解决办法:

    my_grad = tf.gradients(tf.reduce_sum(loss), 输入)

    确保交叉依赖 i!=j 被忽略 - 效果非常好且快速..

    【讨论】:

    • 令人惊讶的是,tf.gradients(loss, input)tf.gradients(tf.reduce_sum(loss), input) 应该产生相同的结果并采取相似的计算工作。
    • 感谢您指出这一点。它对我有用的原因是: loss =[f(input[i]) for i in range(0, input.shape[0]] 因此,当 loss[i] 和 input[j] 之间根本没有导数i!=j
    【解决方案2】:

    这是一种可能的方法:

    import tensorflow as tf
    
    x = tf.placeholder(tf.float32, [20, 50])
    # Break X into its parts
    x_parts = tf.unstack(x)
    # Recompose
    x = tf.stack(x_parts)
    # Compute Y however
    y = tf.reduce_sum(x, axis=1)
    # Break Y into parts
    y_parts = tf.unstack(y)
    # Compute gradient part-wise
    g_parts = [tf.gradients(y_part, x_part)[0] for x_part, y_part in zip(x_parts, y_parts)]
    # Recompose gradient
    g = tf.stack(g_parts)
    print(g)
    # Tensor("stack_1:0", shape=(20, 50), dtype=float32)
    

    但这至少有两个问题:

    • 它要求您为n 使用固定大小(但不适用于m)。
    • 它将在图中创建O(n) 节点,如果您打算使用非常大的n,这可能会出现问题。

    理论上,可以使用 TensorFlow while 循环,但张量数组或循环中的某些内容不会根据需要传播梯度。

    import tensorflow as tf
    
    x = tf.placeholder(tf.float32, [None, None])
    n = tf.shape(x)[0]
    element_shape = x.shape[1:]
    x_parts = tf.TensorArray(x.dtype, size=n, dynamic_size=False,
                             element_shape=element_shape, clear_after_read=False)
    _, x_parts, _ = tf.while_loop(lambda i, x_parts, x: i < n,
                                  lambda i, x_parts, x: (i + 1, x_parts.write(i, x[i]), x),
                                  [tf.constant(0, n.dtype), x_parts, x])
    x = x_parts.stack()
    y = tf.reduce_sum(x, axis=1)
    g_parts = tf.TensorArray(y.dtype, size=n, dynamic_size=False,
                             element_shape=element_shape, clear_after_read=True)
    _, g_parts, _ = tf.while_loop(lambda i, g_parts, x_parts, y: i < n,
                                  lambda i, g_parts, x_parts, y:
                                    (i + 1, g_parts.write(i, tf.gradients(y[i], x_parts.read(i))[0]), x_parts, y),
                                  [tf.constant(0, n.dtype), g_parts, x_parts, y])
    # Fails due to None gradients
    g = g_parts.stack()
    print(g)
    

    【讨论】:

      猜你喜欢
      • 2021-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-08
      • 2014-05-02
      • 2013-04-30
      • 2012-05-18
      相关资源
      最近更新 更多