基于变量的Tensorflow切片

时间:2015-11-30 15:53:28

标签: python tensorflow

我发现索引仍然是张量流(#206)中的一个开放问题,所以我想知道我目前可以使用什么作为解决方法。我想基于每个训练示例更改的变量来索引/切片矩阵的行/列。

到目前为止我尝试过:

  1. 基于占位符切片(不起作用)
  2. 以下(工作)基于固定数字的代码片。

    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:预期单个Tensor时的张量列表。”

    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] 周围的括号太多了,但删除它们也无济于事。如何使用占位符/变量作为索引?

    1. 基于python变量进行切片(没有正确地进行反向提升/更新)
    2. 我也尝试使用普通的python变量作为索引。这不会导致错误,但网络在训练时不会学到任何东西。我想因为更改的变量没有正确注册,图表格式错误,更新不起作用?

      1. 通过单热矢量+乘法切片(有效,但很慢)
      2. 我发现一个解决方法是使用单热矢量。在numpy中创建一个热矢量,使用占位符传递它,然后通过矩阵乘法进行切片。这有效,但速度很慢。

        如何根据变量有效切片/索引?

3 个答案:

答案 0 :(得分:16)

基于占位符切片应该可以正常工作。由于形状和类型的一些微妙问题,您似乎遇到了类型错误。你有以下地方:

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])

...然后,您应该在i的调用中将[0]作为sess.run()提供。

为了使这一点更清晰,我建议按如下方式重写代码:

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)

shape操作的其他tf.placeholder参数有助于确保您提供的值具有适当的形状,并且如果形状不正确,TensorFlow也会引发错误。

答案 1 :(得分:0)

如果您有额外的尺寸,可以使用。

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)

答案 2 :(得分:0)

如果在构建模型时未知大小,请使用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)
相关问题