使用tf.shape(tensor)作为循环的边界

时间:2018-03-22 13:25:25

标签: python tensorflow deep-learning tensor

在Python中使用Tensorflow,我想使用占位符的形状作为for循环的边界。但是,当我尝试这样做时,我得到错误:'Tensor'对象不能被解释为整数。这种形状在数据中不是一个常数值,因此我们不能使用tf.constant。我们怎样才能解决这个问题?

以下是我们代码的一部分:

def Model(M, v_a, weights, biases, d, N):

c = multilayer_perceptron((tf.slice(M, [0, 0], ([d, 1]))), v_a, weights, 
    biases)

for i in range(1, N):

    c = tf.concat([c, multilayer_perceptron((tf.slice(M, [0, i], [d, 1])), 
    v_a, weights, biases)], axis=0)

alpha = tf.nn.softmax(tf.reshape(c, [-1]))

v_ns = tf.matmul(M, tf.reshape(alpha, [N, 1]))

layer_3 = tf.add(tf.matmul(weights['W4'], v_ns), biases['b2'])
v_ms = tf.nn.tanh(layer_3)

layer_4 = tf.add(tf.matmul(weights['W5'], v_ms), biases['b3'])
pred = tf.nn.softmax(tf.reshape(layer_4, [-1]))

return pred

M = tf.placeholder(tf.float32)

我需要N是一个整数,但它需要等于占位符M的列数,这在训练样例中不是常数。

1 个答案:

答案 0 :(得分:1)

编辑:

似乎我在第一时间没有正确理解这个问题。我将保留原始答案,因为它是相关的,以防有人发现它有用。

在任何情况下,如果要使用张量的维度作为循环中的迭代次数,则必须静态地知道维度的值(不能是None)。你只需要做这样的事情:

for i in range(my_tensor.shape[i_dim].value):
    # loop body...

i_dim是您想要迭代的维度。同样,如果您不知道张量维的大小,则需要求助于tf.while_loop

def body(dim, i):
    # loop body...
    return dim, i + 1

cond = lambda dim, i: dim > i

tf.while_loop(cond, body, [tf.shape(my_tensor)[i_dim], 0])

如何或者是否能够做到这一点取决于你在循环时对张量的了解程度。如果形状完全已知,您可以简单地执行:

for dim in my_tensor.shape.as_list():
    # loop body...

这里,dim将是已知维度的常规Python整数。但是,如果存在未知维度,则会将其读作None。如果你不知道确切的尺寸,但你知道张量的等级(即尺寸的数量),你可以这样做:

shape = tf.shape(my_tensor)
for i in range(my_tensor.shape.ndims):
    dim = shape[i]
    # loop body...

在这种情况下,dim将是包含张量尺寸的TensorFlow值,因此您只能使用它来计算其他张量,但保证定义所有尺寸。

最后,如果您甚至不知道张量中的尺寸数,您将无法使用形状进行常规循环。如果有的话,你可以使用tf.while_loop来做你需要的事情:

def body(shape, i):
    dim = shape[i]
    # loop body...
    return shape, i + 1

cond = lambda shape, i: tf.shape(shape)[0] > i

tf.while_loop(cond, body, [tf.shape(my_tensor), 0])