2017-12-15 1 views
0

인코더의 각 단계에서 사용자 지정 계산을 수행해야하는 인코더 - 디코더 lstm을 구현하고 있습니다. 그래서 raw_rnn을 사용하고 있습니다. 그러나 시간 단계 에서 Batch x Time steps x Embedding dimensionality이라는 모양의 요소를 액세스 할 때 문제가 발생합니다. 여기 Tensorflow raw_rnn 텐서 형상 검색 BATCH x DIM from embedding matrix

내 설정이다 :

import tensorflow as tf 
import numpy as np 

batch_size, max_time, input_embedding_size = 5, 10, 16 
vocab_size, num_units = 50, 64 

encoder_inputs = tf.placeholder(shape=(None, None), dtype=tf.int32, name='encoder_inputs') 
encoder_inputs_length = tf.placeholder(shape=(None,), dtype=tf.int32, name='encoder_inputs_length') 

embeddings = tf.Variable(tf.random_uniform([vocab_size + 2, input_embedding_size], -1.0, 1.0), 
         dtype=tf.float32, name='embeddings') 
encoder_inputs_embedded = tf.nn.embedding_lookup(embeddings, encoder_inputs) 

cell = tf.contrib.rnn.LSTMCell(num_units) 

주요 부분 :

with tf.variable_scope('ReaderNetwork'): 
def loop_fn_initial(): 
    init_elements_finished = (0 >= encoder_inputs_length) 
    init_input = cell.zero_state(batch_size, tf.float32) 
    init_cell_state = None 
    init_cell_output = None 
    init_loop_state = None 
    return (init_elements_finished, init_input, 
      init_cell_state, init_cell_output, init_loop_state) 


def loop_fn_transition(time, previous_output, previous_state, previous_loop_state): 
    def get_next_input(): 
     # **TODO** read tensor of shape BATCH X EMBEDDING_DIM from encoder_inputs_embedded 
     # which has shape BATCH x TIME_STEPS x EMBEDDING_DIM 

    elements_finished = (time >= encoder_inputs_length) 
    finished = tf.reduce_all(elements_finished) # boolean scalar 
    input_val = tf.cond(finished, 
         true_fn=lambda: tf.zeros([batch_size, input_embedding_size]), false_fn=get_next_input) 
    state = previous_state 
    output = previous_output 
    loop_state = None 
    return elements_finished, input_val, state, output, loop_state 


def loop_fn(time, previous_output, previous_state, previous_loop_state): 
    if previous_state is None: # time = 0 
     assert previous_output is None and previous_state is None 
     return loop_fn_initial() 
    return loop_fn_transition(time, previous_output, previous_state, previous_loop_state) 

실행중인 부분 :

reader_loop = loop_fn 
encoder_outputs_ta, encoder_final_state, _ = tf.nn.raw_rnn(cell, loop_fn=reader_loop) 
outputs = encoder_outputs_ta.stack() 

def next_batch(): 
    return { 
     encoder_inputs: np.random.random((batch_size, max_time)), 
     encoder_inputs_length: [max_time] * batch_size 
    } 

init = tf.global_variables_initializer() 
with tf.Session() as s: 
    s.run(init) 
    outs = s.run([outputs], feed_dict=next_batch()) 
    print len(outs), outs[0].shape 

질문 : 방법에 묻어의 일부에 액세스 할 수 시간 단계와 모양의 텐서를 반환 batch x embedding dim? loop_fn_transition 내의 get_next_input 기능을 참조하십시오.

감사합니다.

답변

0

문제를 해결할 수있었습니다. 삽입은 모양이 Batch x Time steps x Embedding dimensionality이므로 time 치수로 잘라냅니다. 결과 텐서는 모양이 (?, embedding dimensionality)입니다. 이것은 올바른 방법 인 경우

def get_next_input(): 
    embedded_value = encoder_inputs_embedded[:, time, :] 
    embedded_value.set_shape([batch_size, input_embedding_size]) 
    return embedded_value 

사람이 확인할 수 있습니다 여기에

ValueError: The shape for rnn/while/Merge_2:0 is not an invariant for the loop

는 관련 부분이다 : 명시 적 오류를 방지하기 위해 결과 텐서의 모양을 설정하는 데 필요 문제를 해결하려면?

import tensorflow as tf 
import numpy as np 

batch_size, max_time, input_embedding_size = 5, 10, 16 
vocab_size, num_units = 50, 64 

encoder_inputs = tf.placeholder(shape=(None, None), dtype=tf.int32, name='encoder_inputs') 
encoder_inputs_length = tf.placeholder(shape=(None,), dtype=tf.int32, name='encoder_inputs_length') 

embeddings = tf.Variable(tf.random_uniform([vocab_size + 2, input_embedding_size], -1.0, 1.0), 
         dtype=tf.float32, name='embeddings') 
encoder_inputs_embedded = tf.nn.embedding_lookup(embeddings, encoder_inputs) 

cell = tf.contrib.rnn.LSTMCell(num_units) 
W = tf.Variable(tf.random_uniform([num_units, vocab_size], -1, 1), dtype=tf.float32, name='W_reader') 
b = tf.Variable(tf.zeros([vocab_size]), dtype=tf.float32, name='b_reader') 
go_time_slice = tf.ones([batch_size], dtype=tf.int32, name='GO') * 1 
go_step_embedded = tf.nn.embedding_lookup(embeddings, go_time_slice) 


with tf.variable_scope('ReaderNetwork'): 
    def loop_fn_initial(): 
     init_elements_finished = (0 >= encoder_inputs_length) 
     init_input = go_step_embedded 
     init_cell_state = cell.zero_state(batch_size, tf.float32) 
     init_cell_output = None 
     init_loop_state = None 
     return (init_elements_finished, init_input, 
       init_cell_state, init_cell_output, init_loop_state) 

    def loop_fn_transition(time, previous_output, previous_state, previous_loop_state): 
     def get_next_input(): 
      embedded_value = encoder_inputs_embedded[:, time, :] 
      embedded_value.set_shape([batch_size, input_embedding_size]) 
      return embedded_value 

     elements_finished = (time >= encoder_inputs_length) 
     finished = tf.reduce_all(elements_finished) # boolean scalar 
     next_input = tf.cond(finished, 
          true_fn=lambda: tf.zeros([batch_size, input_embedding_size], dtype=tf.float32), 
          false_fn=get_next_input) 
     state = previous_state 
     output = previous_output 
     loop_state = None 
     return elements_finished, next_input, state, output, loop_state 


    def loop_fn(time, previous_output, previous_state, previous_loop_state): 
     if previous_state is None: # time = 0 
      return loop_fn_initial() 
     return loop_fn_transition(time, previous_output, previous_state, previous_loop_state) 

reader_loop = loop_fn 
encoder_outputs_ta, encoder_final_state, _ = tf.nn.raw_rnn(cell, loop_fn=reader_loop) 
outputs = encoder_outputs_ta.stack() 


def next_batch(): 
    return { 
     encoder_inputs: np.random.randint(0, vocab_size, (batch_size, max_time)), 
     encoder_inputs_length: [max_time] * batch_size 
    } 


init = tf.global_variables_initializer() 
with tf.Session() as s: 
    s.run(init) 
    outs = s.run([outputs], feed_dict=next_batch()) 
    print len(outs), outs[0].shape 
: 여기

참조에 대한 전체 코드입니다

관련 문제