Tensorflow 如何进行非累积张量流散射?
作为学习tensorflow方法的一部分,我正在转换一些现有的矩阵处理逻辑。其中一个步骤是散射操作,如下面示例中使用散射添加的操作。我在这个例子中遇到的问题是,每次对操作求值时,它都会在前面的结果的基础上累加。使用如下所示的3个run()调用,打印的结果如下:Tensorflow 如何进行非累积张量流散射?,tensorflow,Tensorflow,作为学习tensorflow方法的一部分,我正在转换一些现有的矩阵处理逻辑。其中一个步骤是散射操作,如下面示例中使用散射添加的操作。我在这个例子中遇到的问题是,每次对操作求值时,它都会在前面的结果的基础上累加。使用如下所示的3个run()调用,打印的结果如下: [[8 12 8]...] [[16 24 16]...] [[24 36 24]...] 而我想要的是每次都是[[8128]…]。索引向量包含重复项,更新中的相应元素需要一起添加,但不能添加到分散的中已保存的现有值 tensorflo
[[8 12 8]...]
[[16 24 16]...]
[[24 36 24]...]
而我想要的是每次都是[[8128]…]
。索引
向量包含重复项,更新
中的相应元素需要一起添加,但不能添加到分散的中已保存的现有值
tensorflow文档中的分散操作似乎都不是我想要的。是否有合适的操作可供使用?如果没有,实现我所需要的最好方法是什么
import tensorflow as tf
indices = tf.constant([0, 1, 0, 1, 0, 1, 0, 1], tf.int32)
updates = tf.constant([
[1., 2., 3., 4.],
[2., 3., 4., 1.],
[3., 4., 1., 2.],
[4., 1., 2., 3.],
[1., 2., 3., 4.],
[2., 3., 4., 1.],
[3., 4., 1., 2.],
[4., 1., 2., 3.]], tf.float32)
scattered = tf.Variable([
[0., 0., 0., 0.,],
[0., 0., 0., 0.,]], tf.float32)
# Requirement:
# scattered[i, j] = Sum of updates[k, j] where indices[k] == i
#
# i.e.
# scattered_data = [
# [1+3+1+3, 2+4+2+4, 3+1+3+1, 4+2+4+2],
# [2+4+2+4, 3+1+3+1, 4+2+4+2, 1+3+1+3]]
# == [
# [ 8, 12, 8, 12],
# [12, 8, 12, 8]]
scattered = tf.scatter_add(scattered, indices, updates, use_locking=True, name='scattered')
scattered_print = tf.Print(scattered, [scattered])
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
sess.run(scattered_print)
# Printout: [[8 12 8]...]
sess.run(scattered_print)
# Printout: [[16 24 16]...]
sess.run(scattered_print)
# Printout: [[24 36 24]...]
sess.close()
Scatter\u向变量引用添加更新。因此,您可以执行以下操作:
tf.matmul(tf.cast(tf.concat([indices[tf.newaxis,...], 1-indices[tf.newaxis,...]], axis=0), tf.float32),updates)
Scatter\u向变量引用添加更新。因此,您可以执行以下操作:
tf.matmul(tf.cast(tf.concat([indices[tf.newaxis,...], 1-indices[tf.newaxis,...]], axis=0), tf.float32),updates)
对scatter\u add
调用的以下修改似乎可以使事情按预期进行:
with tf.control_dependencies([scattered.initializer]):
scattered = tf.scatter_add(scattered, indices, updates, use_locking=True, name='scattered')
其基本原理是,由于我用零初始化变量,因此在每次scatter\u add
操作之前强制初始化器重新运行将清除它并避免累积更新
这对我来说仍然有点笨重——我本以为会有一个单一的呼叫解决方案。我不确定会有多少不必要的内存分配和释放,但我认为这是以后要研究的问题。下面对scatter\u add
调用的修改似乎可以使事情按预期工作:
with tf.control_dependencies([scattered.initializer]):
scattered = tf.scatter_add(scattered, indices, updates, use_locking=True, name='scattered')
其基本原理是,由于我用零初始化变量,因此在每次scatter\u add
操作之前强制初始化器重新运行将清除它并避免累积更新
这对我来说仍然有点笨重——我本以为会有一个单一的呼叫解决方案。我不确定会有多少不必要的内存分配和释放,但我想这是以后要研究的问题。谢谢你的回答。然而,显示的代码(当然)是真实问题的玩具版本。实际上,索引
中的值从0到大约15000不等,其长度约为10000000。转换为32位矩阵的乘法需要创建一个大约600GB的中间矩阵。我正试图把它输入GPU。现有的实现每个索引项使用16位,因此表示大约20MB的索引数组。感谢您的回复。然而,显示的代码(当然)是真实问题的玩具版本。实际上,索引
中的值从0到大约15000不等,其长度约为10000000。转换为32位矩阵的乘法需要创建一个大约600GB的中间矩阵。我正试图把它输入GPU。现有的实现每个索引项使用16位,因此表示大约20MB的索引数组。