张量大小范围 - 尺寸 - 范围

时间:2017-03-30 18:50:02

标签: python tensorflow neural-network deep-learning

我试图为NN实现定义操作,但是为了这样做,我需要迭代张量的维度。我在下面有一个小工作示例。

X = tf.placeholder(tf.float32, shape=[None, 10])
idx = [[i] for i in tf.range(X.get_shape()[0])]

这会产生错误陈述

ValueError: Cannot convert an unknown Dimension to a Tensor: ?

使用相同的代码但使用tf.shape代替,导致代码

X = tf.placeholder(tf.float32, shape=[None, 10])
idx = [[i] for i in tf.range(tf.shape(X)[0])]

给出以下错误

TypeError: 'Tensor' object is not iterable.

我实现此NN的方式,batch_size未定义,直到训练函数(位于代码末尾)。这就是我自己构建图表的地方,因此batch_size在这一点上并不为人所知,并且无法将其修复为培训batch_size和测试集batch_sizes是不同的。

解决此问题的最佳方法是什么?这是保持我的代码不运行的最后一件事,因为我让它以固定的batch_size运行,尽管这些结果并不有用。我已经倾覆了TensorFlow API文档和堆栈溢出数周无济于事。

我还试图将占位符输入到范围内,因此当我运行测试/训练集时,代码将是以下

X = tf.placeholder(tf.float32, shape=[None, 10])
bs = tf.placeholder(tf.int32)

def My_Function(X):
    # Do some stuff to X
    idx = [[i] for i in tf.range(bs)]
    # return some tensor

A = tf.nn.relu(My_Function(X))

但是,这会产生与上面相同的错误

TypeError: 'Tensor' object is not iterable.

4 个答案:

答案 0 :(得分:1)

tf.map_fn可以成为您想要的吗?

x = tf.placeholder(tf.float32, shape=[None, 10])
f = tf.map_fn(lambda y: y, x) # or perhaps something more useful than identity

修改

现在我理解得更好了,我认为问题在于您在创建图表时尝试获取范围,而不是在图表运行时。

此外,您需要使用tf.range在运行时查询形状。

In [2]: import numpy as np
   ...: import tensorflow as tf
   ...: x = tf.placeholder(tf.float32, shape=[None, 10])
   ...: sess = tf.InteractiveSession()
   ...: sess.run(tf.range(tf.shape(x)[0]), {x: np.zeros((7,10))})
Out[2]: array([0, 1, 2, 3, 4, 5, 6])

答案 1 :(得分:1)

你不能以这种方式对张量进行操作。您需要使用tf.map_fn作为用户1735003提及。

以下是我使用tf.map_fn将每个时间步长的LSTM输出传递到由weights['out']biases['out']定义的线性图层的示例。

x = tf.placeholder("float", [features_dimension, None, n_timesteps])

weights = {'out': tf.Variable(tf.zeros([N_HIDDEN_LSTM, labels_dimension]))}
biases = {'out': tf.Variable(tf.zeros([labels_dimension]))}

def LSTM_model(x, weights, biases):
        lstm_cell = rnn.LSTMCell(N_HIDDEN_LSTM)
        # outputs is a Tensor of shape (n_timesteps, n_observations, N_HIDDEN_LSTM)
        outputs, states = tf.nn.dynamic_rnn(lstm_cell, x, dtype=tf.float32, time_major=True)
        # Linear activation
        def pred_fn(current_output):
            return tf.matmul(current_output, weights['out']) + biases['out']
        # Use tf.map_fn to apply pred_fn to each tensor in outputs, along
        # dimension 0 (timestep dimension)
        pred = tf.map_fn(pred_fn, outputs)

        return pred

答案 2 :(得分:0)

我认为你应该改用tf.shape(x)。

x = tf.placeholder(..., shape=[None, ...])
batch_size = tf.shape(x)[0]  # Returns a scalar `tf.Tensor`

print x.get_shape()[0]  # ==> "?"

# You can use `batch_size` as an argument to other operators.
some_other_tensor = ...
some_other_tensor_reshaped = tf.reshape(some_other_tensor, [batch_size, 32, 32])

# To get the value, however, you need to call `Session.run()`.
sess = tf.Session()
x_val = np.random.rand(37, 100, 100)
batch_size_val = sess.run(batch_size, {x: x_val})
print x_val  # ==> "37"

请参阅:get the size of a variable batch dimension

答案 3 :(得分:0)

如果您使用的是tensorflow> = 1.13,可以使用一个小技巧,尽管效率不高,因为它使用了排序。

x=tf.placeholder(dtype=tf.float32, shape=[None])
xargs=tf.argsort(x)
range=tf.sort(xargs)