我想使用预训练的 GloVe 嵌入作为 RNN 编码器/解码器中嵌入层的初始权重。代码在 TensorFlow 2.0 中。简单地将嵌入矩阵作为 weights = [embedding_matrix] 参数添加到 tf.keras.layers.Embedding 层不会这样做,因为编码器是一个对象,我现在不确定是否有效地将 embedding_matrix 传递给这个对象训练时间。
我的代码紧跟Tensorflow 2.0 文档中的神经机器翻译示例。在这个例子中,我如何向编码器添加一个预训练的嵌入矩阵?编码器是一个对象。当我开始训练时,Tensorflow 图无法使用 GloVe 嵌入矩阵。我收到错误消息:
RuntimeError:无法在 Tensorflow 图函数中获取值。
该代码在训练过程中使用了 GradientTape 方法和教师强制。
我尝试修改编码器对象以在各个点包含 embedding_matrix,包括在编码器的init、call 和 initialize_hidden_state 中。所有这些都失败了。关于 stackoverflow 和其他地方的其他问题是针对 Keras 或更旧版本的 Tensorflow,而不是 Tensorflow 2.0。
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)))