#tensorflow #nlp #recurrent-neural-network #embedding #glove
#tensorflow #nlp #рекуррентная нейронная сеть #встраивание #перчатка
Вопрос:
Я хотел бы использовать предварительно обученную перчатку встраивания в качестве начальных весов для слоя встраивания в кодировщик / декодер RNN. Код находится в Tensorflow 2.0. Просто добавьте матрицу встраивания в качестве параметра weights = [embedding_matrix] в tf.keras.слои.Слой встраивания этого не сделает, потому что кодировщик является объектом, и я не уверен, что теперь эффективно передавать embedding_matrix этому объекту во время обучения.
Мой код полностью соответствует примеру нейронного машинного перевода в документации Tensorflow 2.0. Как бы я добавил предварительно обученную матрицу встраивания в кодировщик в этом примере? Кодировщик — это объект. Когда я приступаю к обучению, матрица встраивания перчаток недоступна для графика Tensorflow. Я получаю сообщение об ошибке:
Ошибка RuntimeError: невозможно получить значение внутри графической функции Tensorflow.
Код использует метод GradientTape и принуждение преподавателя в процессе обучения.
Я попытался изменить объект encoder, чтобы включить 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)))
Ответ №1:
Я пытался сделать то же самое и получал точно такую же ошибку. Проблема заключалась в том, что веса в слое встраивания в настоящее время устарели. Изменение weights=
на embeddings_initializer=
сработало для меня.
self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim,
embeddings_initializer=tf.keras.initializers.Constant(embedding_matrix),
trainable=False)
Комментарии:
1. Красиво, но как я мог загрузить embedding_matrix?
Ответ №2:
во-первых: загрузите предварительно обученную матрицу встраивания, используя
def pretrained_embeddings(file_path, EMBEDDING_DIM, VOCAB_SIZE, word2idx):
# 1.load in pre-trained word vectors #feature vector for each word
print("graph in function",tf.get_default_graph())
print('Loading word vectors...')
word2vec = {}
with open(os.path.join(file_path '.%sd.txt' % EMBEDDING_DIM), errors='ignore', encoding='utf8') as f:
# is just a space-separated text file in the format:
# word vec[0] vec[1] vec[2] ...
for line in f:
values = line.split()
word = values[0]
vec = np.asarray(values[1:], dtype='float32')
word2vec[word] = vec
print('Found %s word vectors.' % len(word2vec))
# 2.prepare embedding matrix
print('Filling pre-trained embeddings...')
num_words = VOCAB_SIZE
# initialization by zeros
embedding_matrix = np.zeros((num_words, EMBEDDING_DIM))
for word, i in word2idx.items():
if i < VOCAB_SIZE:
embedding_vector = word2vec.get(word)
if embedding_vector is not None:
# words not found in embedding index will be all zeros.
embedding_matrix[i] = embedding_vector
return embedding_matrix
2-затем обновите класс Encoder следующим образом:
class Encoder(tf.keras.Model):
def __init__(self, vocab_size, embedding_dim, enc_units, batch_sz,embedding_matrix):
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))
3-вызывающая функция, которая загружает предварительно обученное встраивание для получения матрицы встраивания
embedding_matrix = pretrained_embeddings(file_path, EMBEDDING_DIM,vocab_size, word2idx)
encoder = Encoder(vocab_inp_size, embedding_dim, units, BATCH_SIZE,embedding_matrix)
# 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))
Примечание: это хорошо работает в tensorflow 1.13.1
Комментарии:
1. example_input_batch — это матрица слов с горячим кодированием, правильно?