基于变量的Tensorflow切片
Tensorflow slicing based on variable
我发现索引在 tensorflow (#206) 中仍然是一个未解决的问题,所以我想知道目前我可以使用什么作为解决方法。我想 index/slice row/column 一个基于变量的矩阵,该变量随每个训练示例而变化。
到目前为止我尝试过的:
- 基于占位符的切片(不起作用)
以下(有效)代码片基于固定数量。
import tensorflow as tf
import numpy as np
x = tf.placeholder("float")
y = tf.slice(x,[0],[1])
#initialize
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
#run
result = sess.run(y, feed_dict={x:[1,2,3,4,5]})
print(result)
但是,我似乎不能简单地将其中一个固定数字替换为 tf.placeholder。下面的代码给我错误 "TypeError: List of Tensors when single Tensor expected."
import tensorflow as tf
import numpy as np
x = tf.placeholder("float")
i = tf.placeholder("int32")
y = tf.slice(x,[i],[1])
#initialize
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
#run
result = sess.run(y, feed_dict={x:[1,2,3,4,5],i:0})
print(result)
这听起来好像 [i] 周围的括号太多了,但删除它们也无济于事。如何使用placeholder/variable作为索引?
- 基于 python 变量的切片(backprop/update 不正确)
我也试过使用普通的 python 变量作为索引。这不会导致错误,但网络在训练时不会学到任何东西。我想是因为变化的变量没有正确注册,图形格式不正确并且更新不起作用?
- 通过 one-hot 向量 + 乘法进行切片(有效,但很慢)
我发现的一种解决方法是使用单热向量。在 numpy 中制作一个单热向量,使用占位符传递它,然后通过矩阵乘法进行切片。这有效,但速度很慢。
有什么想法可以有效地 slice/index 基于变量吗?
基于占位符的切片应该可以正常工作。由于一些细微的形状和类型问题,您似乎 运行 遇到了类型错误。如果您有以下内容:
x = tf.placeholder("float")
i = tf.placeholder("int32")
y = tf.slice(x,[i],[1])
...你应该改为:
x = tf.placeholder("float")
i = tf.placeholder("int32")
y = tf.slice(x,i,[1])
...然后您应该在 sess.run()
.
的调用中将 i
作为 [0]
提供
为了更清楚一点,我建议重写代码如下:
import tensorflow as tf
import numpy as np
x = tf.placeholder(tf.float32, shape=[None]) # 1-D tensor
i = tf.placeholder(tf.int32, shape=[1])
y = tf.slice(x, i, [1])
#initialize
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
#run
result = sess.run(y, feed_dict={x: [1, 2, 3, 4, 5], i: [0]})
print(result)
tf.placeholder
操作的附加 shape
参数有助于确保您输入的值具有适当的形状,并且如果形状不正确,TensorFlow 将引发错误。
如果你有一个额外的维度,这行得通。
import tensorflow as tf
import numpy as np
def reorder0(e, i, length):
'''
e: a two dimensional tensor
i: a one dimensional int32 tensor, of shape (e.shape[0])
returns: a tensor of the same shape as e, where the jth entry is entry i[j] from e
'''
return tf.concat(
[ tf.expand_dims( e[i[j],:], axis=0) for j in range(length) ],
axis=0
)
e = tf.placeholder(tf.float32, shape=(2,3,5), name='e' ) # sentences, words, embedding
i = tf.placeholder(tf.int32, shape=(2,3), name='i' ) # for each word, index of parent
p = tf.concat(
[ tf.expand_dims(reorder0(e[k,:,:], i[k,:], 3), axis=0) for k in range(2) ],
axis=0,
name='p'
)
#initialize
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
#run
result = sess.run(p, feed_dict={
e: [
( (1.0,1.1,1.2,1.3,1.4),(2.0,2.1,2.2,2.3,2.4),(3.0,3.1,3.2,3.3,3.4) ),
( (21.0,21.1,21.2,21.3,21.4),(22.0,22.1,22.2,22.3,22.4),(23.0,23.1,23.2,23.3,23.4) ),
],
i: [ (1,1,1), (2,0,2)]
})
print(result)
如果在构建模型时不知道尺寸,请使用 TensorArray。
e = tf.placeholder(tf.float32, shape=(3,5) ) # words, embedding
i = tf.placeholder(tf.int32, shape=(3) ) # for each word, index of parent
#p = reorder0(e, i, 3)
a = tf.TensorArray(
tf.float32,
size=e.get_shape()[0],
dynamic_size=True,
infer_shape= True,
element_shape=e.get_shape()[1],
clear_after_read = False
)
#initialize
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
#run
result = sess.run(
a.unstack(e).gather(i),
feed_dict={
e: ( (1.0,1.1,1.2,1.3,1.4),(2.0,2.1,2.2,2.3,2.4),(3.0,3.1,3.2,3.3,3.4) ),
#( (21.0,21.1,21.2,21.3,21.4),(22.0,22.1,22.2,22.3,22.4),(23.0,23.1,23.2,23.3,23.4) ),
i: (2,0,2)
}
)
print(result)
我发现索引在 tensorflow (#206) 中仍然是一个未解决的问题,所以我想知道目前我可以使用什么作为解决方法。我想 index/slice row/column 一个基于变量的矩阵,该变量随每个训练示例而变化。
到目前为止我尝试过的:
- 基于占位符的切片(不起作用)
以下(有效)代码片基于固定数量。
import tensorflow as tf
import numpy as np
x = tf.placeholder("float")
y = tf.slice(x,[0],[1])
#initialize
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
#run
result = sess.run(y, feed_dict={x:[1,2,3,4,5]})
print(result)
但是,我似乎不能简单地将其中一个固定数字替换为 tf.placeholder。下面的代码给我错误 "TypeError: List of Tensors when single Tensor expected."
import tensorflow as tf
import numpy as np
x = tf.placeholder("float")
i = tf.placeholder("int32")
y = tf.slice(x,[i],[1])
#initialize
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
#run
result = sess.run(y, feed_dict={x:[1,2,3,4,5],i:0})
print(result)
这听起来好像 [i] 周围的括号太多了,但删除它们也无济于事。如何使用placeholder/variable作为索引?
- 基于 python 变量的切片(backprop/update 不正确)
我也试过使用普通的 python 变量作为索引。这不会导致错误,但网络在训练时不会学到任何东西。我想是因为变化的变量没有正确注册,图形格式不正确并且更新不起作用?
- 通过 one-hot 向量 + 乘法进行切片(有效,但很慢)
我发现的一种解决方法是使用单热向量。在 numpy 中制作一个单热向量,使用占位符传递它,然后通过矩阵乘法进行切片。这有效,但速度很慢。
有什么想法可以有效地 slice/index 基于变量吗?
基于占位符的切片应该可以正常工作。由于一些细微的形状和类型问题,您似乎 运行 遇到了类型错误。如果您有以下内容:
x = tf.placeholder("float")
i = tf.placeholder("int32")
y = tf.slice(x,[i],[1])
...你应该改为:
x = tf.placeholder("float")
i = tf.placeholder("int32")
y = tf.slice(x,i,[1])
...然后您应该在 sess.run()
.
i
作为 [0]
提供
为了更清楚一点,我建议重写代码如下:
import tensorflow as tf
import numpy as np
x = tf.placeholder(tf.float32, shape=[None]) # 1-D tensor
i = tf.placeholder(tf.int32, shape=[1])
y = tf.slice(x, i, [1])
#initialize
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
#run
result = sess.run(y, feed_dict={x: [1, 2, 3, 4, 5], i: [0]})
print(result)
tf.placeholder
操作的附加 shape
参数有助于确保您输入的值具有适当的形状,并且如果形状不正确,TensorFlow 将引发错误。
如果你有一个额外的维度,这行得通。
import tensorflow as tf
import numpy as np
def reorder0(e, i, length):
'''
e: a two dimensional tensor
i: a one dimensional int32 tensor, of shape (e.shape[0])
returns: a tensor of the same shape as e, where the jth entry is entry i[j] from e
'''
return tf.concat(
[ tf.expand_dims( e[i[j],:], axis=0) for j in range(length) ],
axis=0
)
e = tf.placeholder(tf.float32, shape=(2,3,5), name='e' ) # sentences, words, embedding
i = tf.placeholder(tf.int32, shape=(2,3), name='i' ) # for each word, index of parent
p = tf.concat(
[ tf.expand_dims(reorder0(e[k,:,:], i[k,:], 3), axis=0) for k in range(2) ],
axis=0,
name='p'
)
#initialize
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
#run
result = sess.run(p, feed_dict={
e: [
( (1.0,1.1,1.2,1.3,1.4),(2.0,2.1,2.2,2.3,2.4),(3.0,3.1,3.2,3.3,3.4) ),
( (21.0,21.1,21.2,21.3,21.4),(22.0,22.1,22.2,22.3,22.4),(23.0,23.1,23.2,23.3,23.4) ),
],
i: [ (1,1,1), (2,0,2)]
})
print(result)
如果在构建模型时不知道尺寸,请使用 TensorArray。
e = tf.placeholder(tf.float32, shape=(3,5) ) # words, embedding
i = tf.placeholder(tf.int32, shape=(3) ) # for each word, index of parent
#p = reorder0(e, i, 3)
a = tf.TensorArray(
tf.float32,
size=e.get_shape()[0],
dynamic_size=True,
infer_shape= True,
element_shape=e.get_shape()[1],
clear_after_read = False
)
#initialize
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
#run
result = sess.run(
a.unstack(e).gather(i),
feed_dict={
e: ( (1.0,1.1,1.2,1.3,1.4),(2.0,2.1,2.2,2.3,2.4),(3.0,3.1,3.2,3.3,3.4) ),
#( (21.0,21.1,21.2,21.3,21.4),(22.0,22.1,22.2,22.3,22.4),(23.0,23.1,23.2,23.3,23.4) ),
i: (2,0,2)
}
)
print(result)