повторное использование переменных и обучение / прогнозирование разделения в тензорном потоке - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь заставить работать мою языковую модель LSTM RNN, основанную на руководстве ptb tenorflow

Однако меня все путает с тем, как использовать и повторно использовать переменные и как организовать мой код в разделах обучения и тестирования (прогнозирования). Первоначально я код так:

class RNNModel(object):
    def __init__(self, input_data, config, is_training=True):
        self.input_x = input_data[0]
        input_y = input_data[1]

    with tf.device('/cpu:0'):
        self.embedding_table = tf.Variable(
            tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0),
            name="word_embeddings")
        self.embeddings = tf.nn.embedding_lookup(self.embedding_table, self.input_x)

        #LSTM layer

        output, final_state = self._build_rnn_graph(self.embeddings, config)

        self.softmax_w = tf.get_variable("W", [config.hidden_size, vocab_size], dtype=tf.float32, initializer=tf.contrib.layers.xavier_initializer()) 
        self.softmax_b = tf.get_variable("b", [vocab_size], dtype=tf.float32)  
        logits = tf.nn.xw_plus_b(output, self.softmax_w, self.softmax_b)


        # Reshape logits to be a 3-D tensor for sequence loss
        logits = tf.reshape(logits, [tf.shape(self.input_x)[0], config.num_steps, vocab_size])
        print ('logits shape=', logits.shape)

        # Use the contrib sequence loss and average over the batches
        loss = tf.contrib.seq2seq.sequence_loss(
            logits,
            input_y,
            tf.ones([tf.shape(self.input_x)[0], config.num_steps]),
            average_across_timesteps=True, # False
            average_across_batch=True)

        self._cost = loss
        self.train_op = optimizer.minimize(loss)



 def _build_rnn_graph(self, inputs, config, is_training):
    cell = tf.nn.rnn_cell.LSTMCell(config.hidden_size, forget_bias=0.0, state_is_tuple=True, reuse=not is_training)
    self._initial_state = cell.zero_state(tf.shape(self.input_x)[0], tf.float32)

    output, final_state = tf.nn.static_rnn(cell=cell, inputs=inputs, dtype=tf.float32, initial_state=self._initial_state)
    return output, final_state

после этого у меня есть:

 dataset = tf.data.Dataset.from_tensor_slices((x, y)).shuffle(buffer_size=100).batch(batch_size)
 iter = dataset.make_initializable_iterator()
 features, labels = iter.get_next()

 model = RNNLM(input_data = [features, labels], vocab=vocab, config=config, is_training=True)

 counter = 1
 with tf.Session() as sess:
     sess.run(iter.initializer, feed_dict={ x: inputs[0],
                                            y: inputs[1] }) 
     sess.run(tf.global_variables_initializer())
    for e in range(max_epoch):        
        try:
            while(True):
                _, x_entropy, cur_input = sess.run([model.train_op, model.cost, model.input_x])
                print('batch:%d, batch_shape=%s, cross entropy=%f, '%(counter, cur_input.shape, x_entropy)) 
                counter += 1
        except tf.errors.OutOfRangeError:
            counter = 1
            sess.run(iter.initializer, feed_dict={ x: inputs[0],
                                           y: inputs[1] }) 

Приведенный выше код работает, за исключением того, что я не могу запустить другой набор тестовых данных или предсказать следующее слово с новым вводом, потому что сеанс завершен.

Итак, мой первый вопрос: как я могу запустить другой набор данных без сохранения / перезагрузки модели с диска?

Я хочу такой подход:

Class RNNModel:
    def __init__(self):
        self.session = tf.Session()
        ...
   def train_batch(self, x,y):
       '''define embedding, lstm cell etc here'''
       cell = tf.nn.rnn_cell.LSTMCell(hidden_size, state_is_tuple=True, reuse=???)
       tf.nn.static_rnn(cell=cell, inputs=inputs)

   def train(self, X, Y):
      for e in epochs:
         for x, y in a_batch:
              self.session.run(train_batch(self, x,y))

   def predict(self, newX):
       cell = tf.nn.rnn_cell.LSTMCell(hidden_size, state_is_tuple=True, reuse=???)

       output, state = tf.nn.static_rnn(cell=cell, inputs=inputs)
       prediction = tf.nn.softmax(output)
       self.session.run(prediction)

наконец, в моем главном блоке я могу сделать:

model = RNNModel(...)
model.train(X, Y)
model.predict(new_X)

Не удивительно, это дает мне ошибки, в строке:

cell = tf.nn.rnn_cell.LSTMCell(hidden_size, state_is_tuple=True, reuse=???)

Либо говорят, что эта переменная не существует (если я установил reuse = False) или

Переменная rnn / lstm_cell / kernel уже существует, запрещено. Ты имел ввиду установить reuse = True или reuse = tf.AUTO_REUSE в VarScope? ...

Поскольку у меня будет много тренировочных циклов по сети, я бы подумал, что мне всегда нужно reuse = True ? Но опять же, почему мой оригинальный код не работает? что здесь отличается? и каков «правильный» подход для такого простого / стандартного сценария?

Большое спасибо!

...