Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
259 views
in Technique[技术] by (71.8m points)

python - Using tf.unpack() when first dimension of Variable is None

I'm feeding in a dynamic shaped Tensor using:

x = tf.placeholder(tf.int32, shape=[None, vector_size])

I need to turn this into a list of Tensors that have shape=[1, vector_size] using x_list = tf.unpack(x, 0)

But it raises a ValueError because the length of the first dimension is not known i.e. it's None.

I've been trying to get around this by using another tf.placeholder to dynamically supply the shape of x but the parameter shape cannot be a Tensor.

How can I use tf.unpack() in this situation?

Or is there another function that can also turn the variable that I feed in into a list of Tensors?

Thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't think you can unpack a tensor with the argument num unspecified and non-inferrable. As their documentation says:

Raises ValueError if num is unspecified and cannot be inferred.

It has something to do with how TensorFlow's internal design for operations like unpack. In this other tread, Yaroslav Bulatov explained

Operations like unpack compile into "tensor-in/tensor-out" ops during graph construction time.

Hence TensorFlow needs to know the specific value of num to pass compiling.

Although, I'd try to get around this by using TensorArray. (see the following code for illustration).

import tensorflow as tf
import numpy as np
sess = tf.InteractiveSession()
# assume vector_size=2 for simplicity
x = tf.placeholder(tf.int32, shape=[None, 2])
TensorArr = tf.TensorArray(tf.int32, 1, dynamic_size=True, infer_shape=False)
x_array = TensorArr.unpack(x)

TensorArray is a class for wrapping dynamically sized arrays of Tensors. When initialize a TensorArray object in this application, TensorArr = tf.TensorArray(tf.int32, 1, dynamic_size=True, infer_shape=False), set dynamic_size=True and infer_shape=False since the shape of placeholder x is only partly defined.

To access each unpacked element:

# access the first element
x_elem0 = x_array.read(0)
# access the last element
last_idx = tf.placeholder(tf.int32)
x_last_elem = x_array.read(last_idx)

Then at evaluation time:

# generate random numpy array
dim0 = 4
x_np = np.random.randint(0, 25, size=[dim0, 2])
print x_np
# output of print x_np
[[17 15] 
[17 19]
[ 3  0]
[ 4 13]]

feed_dict = {x : x_np, last_idx : dim0-1} #python 0 based indexing
x_elem0.eval(feed_dict=feed_dict)
array([17, 15], dtype=int32) #output of x_elem0.eval(feed_dict)

x_last_elem.eval(feed_dict=feed_dict)
array([ 4, 13], dtype=int32) #output of x_last_elem.eval(feed_dict)
sess.close()

Note that when trying to access each unpacked element, if the index value is out of bound, you'd be able to pass the compiling but you'll get an error during runtime suggesting index out of bound. Additionally, the shape of the unpacked tensor would be TensorShape(None), since the shape of x is only partially determined until being evaluated.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...