【问题标题】:How to transform vector into unit vector in Tensorflow如何在Tensorflow中将向量转换为单位向量
【发布时间】:2016-10-29 21:18:36
【问题描述】:

这是一个非常简单的问题,我似乎无法弄清楚。我正在使用形状为 [100, 250] 的输出张量。我希望能够在百位的任何位置访问 250 维数组并分别修改它们。我发现的张量流数学工具要么对整个张量进行逐元素修改,要么进行标量修改。但是,我正在尝试对张量的子集进行标量修改。

编辑:

这是我想用 tensorflow 方法重新创建的 numpy 代码:

update = sess.run(y, feed_dict={x: batch_xs})
for i in range(len(update)):
        update[i] = update[i]/np.sqrt(np.sum(np.square(update[i])))
        update[i] = update[i] * magnitude

这个 for 循环在 250 维而不是 3 维中遵循这个公式 .然后,我将每个单位向量乘以幅度,将其重新整形为我想要的长度。

所以这里更新的是 numpy [100, 250] 维度的输出。我想将每个 250 维向量转换为其单位向量。这样我就可以将它的长度更改为我选择的大小。使用这个 numpy 代码,如果我运行我的 train_step 并将更新传递给我的占位符之一

sess.run(train_step, feed_dict={x: batch_xs, prediction: output}) 

它返回错误:

No gradients provided for any variable

这是因为我已经在 numpy 中完成了数学运算并将其移植回 tensorflow。 Here 是一个相关的 stackoverflow 问题,没有得到回答。

tf.nn.l2_normalize 非常接近我正在寻找的内容,但它除以 最大 平方和的平方根。而我试图将每个向量除以其自己的平方和。

谢谢!

【问题讨论】:

  • 所以,表达这个问题的另一种方式是:如果我有一个 [x, y] 形状的张量和一个 [x, 1] 形状的张量,我可以做数学运算,使得值在“1”类别中影响“y”类别中的每个相应值?不是元素明智的,但也不是具体的标量乘法。
  • 我觉得你的问题很不清楚。你能给出你在 numpy 中如何做的代码吗?
  • 也许使用了张量流的地图功能?它适用于 0.9
  • tf.nn.l2_normalize 做你想做的事吗?
  • 您好,很抱歉回复晚了。我已经编辑了我的帖子,希望能更清楚地解释一切。

标签: python numpy tensorflow


【解决方案1】:

这里没有真正的技巧,你可以像在 numpy 中那样做。
唯一需要确定的是norm 的形状是[100, 1],这样它才能在x / norm 分区中很好地广播。

x = tf.ones([100, 250])

norm = tf.sqrt(tf.reduce_sum(tf.square(x), axis=1, keepdims=True))
assert norm.shape == [100, 1]

res = x / norm

【讨论】:

  • 天哪!我一直认为keepdims 没用。最后是一个有意义的用例。谢谢!
【解决方案2】:

您可以使用tf.norm 获取平方和的平方根。 (我的代码中的 tf 版本 == 1.4。)

示例代码:

  import  tensorflow as tf
  a = tf.random_uniform((3, 4))
  b = tf.norm(a, keep_dims=True)
  c = tf.norm(a, axis=1, keep_dims=True)
  d = a / c
  e = a / tf.sqrt(tf.reduce_sum(tf.square(a), axis=1, keep_dims=True) + 1e-8)
  f = a / tf.sqrt(tf.reduce_sum(tf.square(a), axis=1, keep_dims=True))
  g = tf.sqrt(tf.reduce_sum(tf.square(a), axis=1, keep_dims=True))
  with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    a_eval, b_eval, c_eval, d_eval, e_eval, f_eval, g_eval = sess.run([a, b, c, d, e, f, g])
    print(a_eval)
    print(b_eval)
    print(c_eval)
    print(d_eval)
    print(e_eval)
    print(f_eval)
    print(g_eval)

输出:

[[ 0.29823065  0.76523042  0.40478575  0.44568062]
 [ 0.0222317   0.12344956  0.39582515  0.66143286]
 [ 0.01351094  0.38285756  0.46898723  0.34417391]]
[[ 1.4601624]]
[[ 1.01833284]
 [ 0.78096414]
 [ 0.6965394 ]]
[[ 0.29286167  0.75145411  0.39749849  0.43765712]
 [ 0.02846699  0.15807328  0.50684166  0.84694397]
 [ 0.01939724  0.54965669  0.6733104   0.49411979]]
[[ 0.29286167  0.75145411  0.39749849  0.43765712]
 [ 0.02846699  0.15807328  0.50684166  0.84694397]
 [ 0.01939724  0.54965669  0.6733104   0.49411979]]
[[ 0.29286167  0.75145411  0.39749849  0.43765712]
 [ 0.02846699  0.15807328  0.50684166  0.84694397]
 [ 0.01939724  0.54965669  0.6733104   0.49411979]]
[[ 1.01833284]
 [ 0.78096414]
 [ 0.6965394 ]]

您可以看到a / tf.norm(a, axis=1, keep_dims=True)a / tf.sqrt(tf.reduce_sum(tf.square(a), axis=1, keep_dims=True) + 1e-8) 之间没有区别。

a / tf.sqrt(tf.reduce_sum(tf.square(a), axis=1, keep_dims=True) + 1e-8) 是首选,因为它可以处理零大小写。

【讨论】:

  • 在 TensorFlow 2 中,关键字参数的名称应为 keepdims
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 2018-09-06
  • 1970-01-01
  • 2011-08-15
  • 1970-01-01
相关资源
最近更新 更多