将标量变量插入张量的正确方法

时间:2018-12-11 18:16:15

标签: python tensorflow

我想创建一个张量,其中的条目是相同变量(例如,不同幂)的不同“版本”,最终需要为其计算梯度。例如

v: Variable
# Now the corresponding tensor should look like:
M = [[ 1    , v    ],
     [ v**2 , v**3 ]]
# Followed by some computation involving `M`,
# then compute gradient w.r.t. `v`.

我不确定实现此目标的最佳方法是什么。现在,我想出了两种选择,但它们都以某种方式感到“ hacky”:

  • 使用多次致电tf.stack
  • 或结合使用辅助张量的乘法和求和。

这是代码示例:

import tensorflow as tf


x = tf.placeholder(tf.float32, shape=(1, 2))
v = tf.Variable(2, dtype=tf.float32)
# Option 1.
M = tf.stack(
    [tf.stack([1   , v   ]),
     tf.stack([v**2, v**3])]
)
# Option 2.
M = (
             tf.constant([[1, 0], [0, 0]], dtype=tf.float32)
    + v**1 * tf.constant([[0, 1], [0, 0]], dtype=tf.float32)
    + v**2 * tf.constant([[0, 0], [1, 0]], dtype=tf.float32)
    + v**3 * tf.constant([[0, 0], [0, 1]], dtype=tf.float32)
)
z = tf.matmul(x, M)
result = tf.tensordot(z, z, (1, 1))
gradient = tf.gradients(result, v)

init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    r, g = sess.run([result, gradient], feed_dict={x: [[1, 2]]})

是否存在另一种(更专用的)方法来完成此任务?是否有理由偏爱以上一种方法?

编辑

上面的示例表明张量元素对变量v的多项式依赖性,但是我对更常见的情况感兴趣,在这种情况下,元素可以具有 any (可微分)函数依赖变量v;例如:

# More general example.
M = [[ v**2         , sin(v) / v        ],
     [ cos(sqrt(v)) , exp(v + constant) ]]

1 个答案:

答案 0 :(得分:1)

您可以使用tf.rangetf.reshape一行进行操作。

import tensorflow as tf
v = tf.Variable(2)
M = tf.reshape(v ** tf.range(4), (2,2))
# becomes: tf.reshape(v ** [0,1,2,3], (2,2))
# becomes: [[v**0, v**1], [v**2, v**3]]
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    g = sess.run(M)

# result is: 
# array([[1, 2],
#       [4, 8]], dtype=int32)