title: How to use a pre-trained embedding matrix in tensorflow 2.0 RNN as initial weights in an embedding layer?
body: <p>I'd like to use a pretrained GloVe embedding as the initial weights for an embedding layer in an RNN encoder/decoder. The code is in Tensorflow 2.0. Simply adding the embedding matrix as a weights = [embedding_matrix] parameter to the tf.keras.layers.Embedding layer won't do it because the encoder is an object and I'm not sure now to effectively pass the embedding_matrix to this object at training time.</p>
  
  <p>My code closely follows the <a href="https://www.tensorflow.org/alpha/tutorials/text/nmt_with_attention" rel="noreferrer">neural machine translation example in the Tensorflow 2.0 documentation</a>. How would I add a pre-trained embedding matrix to the encoder in this example? The encoder is an object. When I get to training, the GloVe embedding matrix is unavailable to the Tensorflow graph. I get the error message: </p>
  
  <p>RuntimeError: Cannot get value inside Tensorflow graph function. </p>
  
  <p>The code uses the GradientTape method and teacher forcing in the training process. </p>
  
  <p>I've tried modifying the encoder object to include the embedding_matrix at various points, including in the encoder's <strong>init</strong>, call and initialize_hidden_state. All of these fail. The other questions on stackoverflow and elsewhere are for Keras or older versions of Tensorflow, not Tensorflow 2.0.</p>
  
  <pre><code>class Encoder(tf.keras.Model):
      def __init__(self, vocab_size, embedding_dim, enc_units, batch_sz):
          super(Encoder, self).__init__()
          self.batch_sz = batch_sz
          self.enc_units = enc_units
          self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim, weights=[embedding_matrix])
          self.gru = tf.keras.layers.GRU(self.enc_units,
                                         return_sequences=True,
                                         return_state=True,
                                         recurrent_initializer='glorot_uniform')
  
      def call(self, x, hidden):
          x = self.embedding(x)
          output, state = self.gru(x, initial_state = hidden)
          return output, state
  
      def initialize_hidden_state(self):
          return tf.zeros((self.batch_sz, self.enc_units))
  
  encoder = Encoder(vocab_inp_size, embedding_dim, units, BATCH_SIZE)
  
  # sample input
  sample_hidden = encoder.initialize_hidden_state()
  sample_output, sample_hidden = encoder(example_input_batch, sample_hidden)
  print ('Encoder output shape: (batch size, sequence length, units) {}'.format(sample_output.shape))
  print ('Encoder Hidden state shape: (batch size, units) {}'.format(sample_hidden.shape))
  
  # ... Bahdanau Attention, Decoder layers, and train_step defined, see link to full tensorflow code above ...
  
  # Relevant training code
  
  EPOCHS = 10
  
  training_record = pd.DataFrame(columns = ['epoch', 'training_loss', 'validation_loss', 'epoch_time'])
  
  
  for epoch in range(EPOCHS):
      template = 'Epoch {}/{}'
      print(template.format(epoch +1,
                   EPOCHS))
      start = time.time()
  
      enc_hidden = encoder.initialize_hidden_state()
      total_loss = 0
      total_val_loss = 0
  
      for (batch, (inp, targ)) in enumerate(dataset.take(steps_per_epoch)):
          batch_loss = train_step(inp, targ, enc_hidden)
          total_loss += batch_loss
  
          if batch % 100 == 0:
              template = 'batch {} ============== train_loss: {}'
              print(template.format(batch +1,
                              round(batch_loss.numpy(),4)))
  </code></pre>