2017-01-12 9 views
5

Próbuję użyć tf.while_loop() do przetwarzania wejść o zmiennej długości. Mogę jednak używać go tylko dla określonej długości. Kod nie działa już po zmianie kształtu = (4) na kształt = (Brak). tf.dynamic_rnn wydaje się obsługiwać wejścia o zmiennej długości. Nie jestem pewien, jak tf.dynamic_rnn osiąga to za pomocą tf.while_loop().Jak korzystać z tf.while_loop() dla wejść o zmiennej długości w tensorflow?

import tensorflow as tf 
import numpy as np 
from tensorflow.python.ops import tensor_array_ops 
from tensorflow.python.ops import array_ops 

with tf.Graph().as_default(), tf.Session() as sess: 
    initial_m = tf.Variable(0.0, name='m') 

    inputs = tf.placeholder(dtype='float32', shape=(4)) 
    #The code no longer works after I change shape=(4) to shape=(None) 
    #inputs = tf.placeholder(dtype='float32', shape=(None)) 

    time_steps = tf.shape(inputs)[0] 

    initial_outputs = tf.TensorArray(dtype=tf.float32, size=time_steps) 
    initial_t = tf.constant(0, dtype='int32') 

    def should_continue(t, *args): 
    return t < time_steps 

    def iteration(t, m, outputs_): 
    cur = tf.gather(inputs, t) 
    m = m * 0.5 + cur * 0.5 
    outputs_ = outputs_.write(t, m) 
    return t + 1, m, outputs_ 

    t, m, outputs = tf.while_loop(
    should_continue, iteration, 
    [initial_t, initial_m, initial_outputs]) 

    outputs = outputs.pack() 
    init = tf.global_variables_initializer() 
    sess.run([init]) 
    print sess.run([outputs], feed_dict={inputs: np.asarray([1,1,1,1])}) 

wyjściowego (przed zmianą):

[array([ 0.5 , 0.75 , 0.875 , 0.9375], dtype=float32)] 

wyjścia (po zmianie):

Traceback (most recent call last): 
    File "simple.py", line 26, in <module> 
    [initial_t, initial_m, initial_outputs]) 
    File "/usr/local/lib/python2.7/site-packages/tensorflow/python/ops/control_flow_ops.py", line 2636, in while_loop 
    result = context.BuildLoop(cond, body, loop_vars, shape_invariants) 
    File "/usr/local/lib/python2.7/site-packages/tensorflow/python/ops/control_flow_ops.py", line 2469, in BuildLoop 
    pred, body, original_loop_vars, loop_vars, shape_invariants) 
    File "/usr/local/lib/python2.7/site-packages/tensorflow/python/ops/control_flow_ops.py", line 2450, in _BuildLoop 
    _EnforceShapeInvariant(m_var, n_var) 
    File "/usr/local/lib/python2.7/site-packages/tensorflow/python/ops/control_flow_ops.py", line 586, in _EnforceShapeInvariant 
    % (merge_var.name, m_shape, n_shape)) 
ValueError: The shape for while/Merge_1:0 is not an invariant for the loop. It enters the loop with shape(), but has shape <unknown> after one iteration. Provide shape invariants using either the `shape_invariants` argument of tf.while_loop or set_shape() on the loop variables. 

Odpowiedz

6

To działa, jeśli usuwanie kształtów ze wszystkich zmiennych:

import tensorflow as tf 
import numpy as np 

config = tf.ConfigProto(graph_options=tf.GraphOptions(
    optimizer_options=tf.OptimizerOptions(opt_level=tf.OptimizerOptions.L0))) 
tf.reset_default_graph() 
sess = tf.Session("", config=config) 
#initial_m = tf.Variable(0.0, name='m') 

#The code no longer works after I change shape=(4) to shape=(None) 
inputs = tf.placeholder(dtype='float32', shape=(None)) 
time_steps = tf.shape(inputs)[0] 
initial_outputs = tf.TensorArray(dtype=tf.float32, size=time_steps) 
initial_t = tf.placeholder(dtype='int32') 
initial_m = tf.placeholder(dtype=tf.float32) 

def should_continue(t, *args): 
    return t < time_steps 

def iteration(t, m, outputs_): 
    cur = tf.gather(inputs, t) 
    m = m * 0.5 + cur * 0.5 
    outputs_ = outputs_.write(t, m) 
    return t + 1, m, outputs_ 

t, m, outputs = tf.while_loop(should_continue, iteration, 
           [initial_t, initial_m, initial_outputs]) 

outputs = outputs.stack() 
init = tf.global_variables_initializer() 
sess.run([init]) 
print(sess.run([outputs], 
       feed_dict={inputs: np.asarray([1, 1, 1, 1]), initial_t: 0, 
          initial_m: 0.})) 
+0

To działa. Dzięki! –

+0

BTW, czy można uniknąć używania placeholder? initial_t i initial_m są zwykłymi zerami. Czy mogę za każdym razem unikać podawania im zer? –

+0

Potrzebujesz tylko czegoś o nieznanym kształcie. Wygląda na to, że nie da się uczynić stałym z nieznanym kształtem. Ale możesz użyć zmiennej lub placeholder –

Powiązane problemy