【问题标题】:tensorflow embeddings don't exist after first RNN example在第一个 RNN 示例之后不存在张量流嵌入
【发布时间】:2016-12-22 01:22:57
【问题描述】:

我已经设置了一个打印语句,并且我注意到在第一批输入 RNN 时,嵌入存在,但在第二批之后它们不存在,并且我收到以下错误:

ValueError:变量 RNNLM/RNNLM/Embedding/Adam_2/ 不存在,或者不是使用 tf.get_variable() 创建的。您的意思是在 VarScope 中设置 reuse=None 吗?

这是我生成嵌入的代码:

def add_embedding(self):
    with tf.device('/gpu:0'):
      embedding = tf.get_variable("Embedding", [len(self.vocab), self.config.embed_size])
      e_x = tf.nn.embedding_lookup(embedding, self.input_placeholder)
      inputs = [tf.squeeze(s, [1]) for s in tf.split(1, self.config.num_steps, e_x)] 
      return inputs

这是模型的 seutp 方式,这就是我怀疑问题所在

def model(self, inputs):
   with tf.variable_scope("input_drop"):
      inputs_drop = [tf.nn.dropout(i, self.dropout_placeholder) for i in inputs]

    with tf.variable_scope("RNN") as scope:
      self.initial_state = tf.zeros([self.config.batch_size, self.config.hidden_size], tf.float32)
      state = self.initial_state
      states = []
      for t, e in enumerate(inputs_drop):
        print "t is {0}".format(t)
        if t > 0:
          scope.reuse_variables()
        H = tf.get_variable("Hidden", [self.config.hidden_size, self.config.hidden_size])
        I = tf.get_variable("I", [self.config.embed_size, self.config.hidden_size])
        b_1 = tf.get_variable("b_1", (self.config.hidden_size,))

        state = tf.sigmoid(tf.matmul(state, H) + tf.matmul(e, I) + b_1)
        states.append(state)

    with tf.variable_scope("output_dropout"):
      rnn_outputs = [tf.nn.dropout(o, self.dropout_placeholder) for o in states]
    return rnn_outputs

当我到达损失函数时,问题就出现了,定义如下

def add_training_op(self, loss):
    opt = tf.train.AdamOptimizer(self.config.lr)
    train_op = opt.minimize(loss)
    return train_op

编辑:这里有一些更新的代码可以帮助大家

 def __init__(self, config):
    self.config = config
    self.load_data(debug=False)
    self.add_placeholders()
    self.inputs = self.add_embedding()
    self.rnn_outputs = self.add_model(self.inputs)
    self.outputs = self.add_projection(self.rnn_outputs)
    self.predictions = [tf.nn.softmax(tf.cast(o, 'float64')) for o in self.outputs]
    output = tf.reshape(tf.concat(1, self.outputs), [-1, len(self.vocab)])
    self.calculate_loss = self.add_loss_op(output)
    self.train_step = self.add_training_op(self.calculate_loss)

这里有其他方法,与 add_projectioncalculate_loss 有关,因此我们可以排除它们。

def add_loss_op(self, output):
   weights = tf.ones([self.config.batch_size * self.config.num_steps], tf.int32)
    seq_loss = tf.python.seq2seq.sequence_loss(
      [output], 
      tf.reshape(self.labels_placeholder, [-1]), 
      weights
      )
    tf.add_to_collection('total_loss', seq_loss)
    loss = tf.add_n(tf.get_collection('total_loss')) 
    return loss

def add_projection(self, rnn_outputs):
   with tf.variable_scope("Projection", initializer=tf.contrib.layers.xavier_initializer()) as scope:
      U = tf.get_variable("U", [self.config.hidden_size, len(self.vocab)])
      b_2 = tf.get_variable("b_2", [len(self.vocab)])

      outputs = [tf.matmul(x, U) + b_2 for x in rnn_outputs]
      return outputs


def train_RNNLM():
  config = Config()
  gen_config = deepcopy(config)
  gen_config.batch_size = gen_config.num_steps = 1

  with tf.variable_scope('RNNLM') as scope:
    model = RNNLM_Model(config)
    # This instructs gen_model to reuse the same variables as the model above
    scope.reuse_variables()
    gen_model = RNNLM_Model(gen_config)

  init = tf.initialize_all_variables()
  saver = tf.train.Saver()

  with tf.Session() as session:
    best_val_pp = float('inf')
    best_val_epoch = 0

    session.run(init)
    for epoch in xrange(config.max_epochs):
      print 'Epoch {}'.format(epoch)
      start = time.time()
      ###
      train_pp = model.run_epoch(
          session, model.encoded_train,
          train_op=model.train_step)
      valid_pp = model.run_epoch(session, model.encoded_valid)
      print 'Training perplexity: {}'.format(train_pp)
      print 'Validation perplexity: {}'.format(valid_pp)
      if valid_pp < best_val_pp:
        best_val_pp = valid_pp
        best_val_epoch = epoch
        saver.save(session, './ptb_rnnlm.weights')
      if epoch - best_val_epoch > config.early_stopping:
        break
      print 'Total time: {}'.format(time.time() - start)

【问题讨论】:

  • 您能提供更多代码吗?我似乎无法理解函数 add_training_opadd_embedding 如何与其余代码一起发挥作用
  • @martianwars 我继续添加代码设置。

标签: python tensorflow


【解决方案1】:

似乎代码正在尝试在每个批次中创建一个新的 Adam 变量。 add_training_op 可能被调用两次? 另外def add_training_op的sn-p是不完整的,因为没有return语句。

【讨论】:

  • 缺少返回语句是一个错字,现已修复。我将继续添加打印语句以查看调用该代码的频率。
  • 我添加了另一个我正在调用的方法,可能它会导致问题。
【解决方案2】:

问题原来是下面这行代码:

model = RNNLM_Model(config)
    # This instructs gen_model to reuse the same variables as the model above
    scope.reuse_variables()
    gen_model = RNNLM_Model(gen_config)

事实证明,使用reuse_variables() 时,第二个模型存在问题。通过删除这条线,问题就消失了。

【讨论】:

    猜你喜欢
    • 2016-03-28
    • 2017-12-05
    • 2019-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-02
    相关资源
    最近更新 更多