2016-10-14 3 views
0

Я пытаюсь создать генеративную модель RNN в тензорном потоке. Меня раздражает то, что с новым переключателем state_is_tupe по умолчанию в RNN-библиотеке мне трудно найти лучший способ сохранить состояние между партиями. Я знаю, что могу изменить его на Ложь, но я не хочу этого делать, поскольку он устарел. Когда я закончил тренировку, мне нужно уметь скрывать состояния между вызовами session.run, так как я буду генерировать последовательности по одному образцу за раз. Я понял, что могу вернуть состояние rnn следующим образом.Tensorflow, как передать состояние MultiRNN в feed_dict

 rnn = tf.nn.rnn_cell.MultiRNNCell(cells) 
     zero_state = rnn.zero_state(batch_size, tf.float32) 
     output, final_state = tf.nn.dynamic_rnn(rnn, self.input_sound, initial_state = zero_state) 
     sess = tf.Session() 
     sess.run(tf.initialize_all_variables()) 
     state_output = sess.run(final_state, feed_dict = {self.input_sound: np.zeros((64, 32, 512))}) 

Это было бы замечательно, но проблема возникает, когда я хочу передать state_output обратно в модель. Поскольку placeholder может быть только тензорным объектом, я не могу передать его обратно в state_output tupel.

Я ищу очень общее решение. Rnn может быть MultiRNNCell или одним LSTMCell или любой другой возможной комбинацией.

ответ

0

Я думаю, что понял. Я использовал следующий код, чтобы сгладить правильные кортежи в один одномерный тензор. Я могу, чем рубить его, когда я передаю его обратно в модель в соответствии со спецификацией размера ячейки rnn.

def flatten_state_tupel(x): 
    result = [] 
    for x_ in x: 
     if isinstance(x_, tf.Tensor) or not hasattr(x_, '__iter__'): 
      result.append(x_) 
     else: 
      result.extend(flatten_state_tupel(x_)) 
    return result 

def pack_state_tupel(state): 
    return tf.concat(0, [tf.reshape(s, (-1,)) for s in flatten_state_tupel(state)]) 

def unpack_state_tupel(state, size): 
    state = tf.reshape(state, (-1, tf.reduce_sum(flatten_state_tupel(size)))) 
    def _make_state_tupel(sz, i): 
     if hasattr(sz, '__iter__'): 
      result = [] 
      for s in sz: 
       base_index, y = _make_state_tupel(s, i) 
       result.append(y) 
      return base_index, tf.nn.rnn_cell.LSTMStateTuple(*result) if isinstance(sz, tf.nn.rnn_cell.LSTMStateTuple) else tuple(result) 
     else: 
      return i + sz, state[..., i : i + sz] 
    return _make_state_tupel(size, 0)[-1] 

Я использую следующие функции.

rnn = tf.nn.rnn_cell.MultiRNNCell(cells) 
zero_state = pack_state_tupel(rnn.zero_state(batch_size, tf.float32)) 
self.initial_state = tf.placeholder_with_default(zero_state, None) 

output, final_state = tf.nn.dynamic_rnn(rnn, self.input_sound, initial_state = unpack_state_tupel(self.initial_state, rnn.state_size)) 

packed_state = pack_state_tupel(final_state) 

sess = tf.Session() 
sess.run(tf.initialize_all_variables()) 

state_output = sess.run(packed_state, feed_dict = {self.input_sound: np.zeros((64, 32, 512))}) 
print(state_output.shape) 
state_output = sess.run(packed_state, feed_dict = {self.input_sound: np.zeros((64, 32, 512)), self.initial_state: np.zeros(state_output.shape[0])}) 
print(state_output) 

Таким образом, он будет обнулить состояние, если я что-нибудь (что будет иметь место, во время тренировки), однако я могу сохранить и передать состояние между партиями во время генерации не прохожу.

Смежные вопросы