NotImplementedError при использовании model.save () в Keras
Я пытаюсь использовать Keras для реализации простой модели кодер-декодер.Я не использовал Sequential ().Я попробовал Подкласс Модели.Я успешно обучил модель, но не смог ее сохранить.Сначала я не добавил input_shape
для первого слоя моделей.Но когда я добавляю его в модель, происходит такая же ошибка.И я не знаю, как его сохранить.
import tensorflow as tf
import numpy as np
import time
import matplotlib.pyplot as plt
import caption_preprocessing
import train_dataset_preparation
tf.enable_eager_execution()
# some parameters
voc_size = len(caption_preprocessing.tokenizer.word_index) # voc_size = 10001
embedding_output_dim = 256
lstm_output_dim = 512
encoder_output_dim = embedding_output_dim
EPOCHS = 1
# model definition
class EncoderPart(tf.keras.Model):
def __init__(self):
super(EncoderPart, self).__init__()
self.fc = tf.keras.layers.Dense(input_shape=(64, 2048), units=encoder_output_dim)
def call(self, inputs, training=None, mask=None):
y = self.fc(inputs)
output = tf.nn.relu(y)
return output
class EmbeddingPart(tf.keras.Model):
def __init__(self):
super(EmbeddingPart, self).__init__()
self.embedding = tf.keras.layers.Embedding(input_shape=(1,),
input_dim=voc_size,
output_dim=embedding_output_dim)
def call(self, inputs, training=None, mask=None):
output = self.embedding(inputs)
return output
class DecoderPart(tf.keras.Model):
def __init__(self):
super(DecoderPart, self).__init__()
self.lstm = tf.keras.layers.CuDNNLSTM(input_shape=(64, embedding_output_dim),
units=lstm_output_dim,
return_sequences=True,
return_state=True,
recurrent_initializer='glorot_uniform')
self.fc = tf.keras.layers.Dense(units=voc_size)
def call(self, inputs, training=None, mask=None):
y, state_h, state_c = self.lstm(inputs)
output = self.fc(y)
return output, state_c
def reset_states(self, batch_size):
return tf.zeros((batch_size, lstm_output_dim))
def _loss_function(real, pred):
mask = 1 - np.equal(real, 0) # ignore the loss of padding words
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=real, logits=pred) * mask
return tf.reduce_mean(loss)
if __name__ == '__main__':
# training model
encoder = EncoderPart()
embedding = EmbeddingPart()
decoder = DecoderPart()
optimizer = tf.train.AdamOptimizer()
loss_plot = []
time_per_epoch = time.time()
for epoch in range(EPOCHS):
start_time = time.time()
total_loss = 0
for (batch, (image_feature_vec, caption)) in enumerate(train_dataset_preparation.dataset):
# print(batch+1, caption.shape)
batch_loss = 0
decoder.reset_states(caption.shape[0]) # reset the states of the lstm layer
start_vec = [caption_preprocessing.tokenizer.word_index['<start>']] * caption.shape[0]
dec_input = tf.expand_dims(start_vec, 1) # shape=(BATCH_SIZE, 1)
with tf.GradientTape() as tape:
image_feature = encoder(image_feature_vec)
_, state = decoder(image_feature) # _.shape=(BATCH_SIZE, 64, 10001), state.shape=(BATCH_SIZE, 512)
for i in range(1, caption.shape[1]):
word_embedding = embedding(dec_input) # shape=(BATCH_SIZE, 1, embedding_output_dim)
predictions, _ = decoder(word_embedding) # shape=(BATCH_SIZE, 1, voc_size)
predictions = tf.reshape(predictions, (caption.shape[0], -1)) # shape=(BATCH_SIZE, embedding_output_dim)
batch_loss += _loss_function(caption[:, i], predictions)
dec_input = tf.expand_dims(caption[:, i], 1)
total_loss += (batch_loss / int(caption.shape[1]))
variables = encoder.variables + embedding.variables + decoder.variables
gradients = tape.gradient(batch_loss, variables)
optimizer.apply_gradients(zip(gradients, variables), tf.train.get_or_create_global_step())
if (batch + 1) % 100 == 0:
print('Epoch {} Batch {} Loss {:.4f}'.format(epoch + 1,
batch + 1,
batch_loss.numpy() / int(caption.shape[1])))
loss_plot.append(total_loss / len(caption_preprocessing.train_cap_vec))
print('Epoch {} Loss {:.6f}'.format(epoch + 1,
total_loss / len(caption_preprocessing.train_cap_vec)))
print('Time taken for 1 epoch {} sec\n'.format(time.time() - start_time))
time_per_epoch = (time.time() - time_per_epoch) / EPOCHS
# loss plot
plt.plot(loss_plot)
plt.xlabel('epochs')
plt.ylabel('loss')
plt.title('loss plot')
plt.show()
# save model
save_path = r'\20190326'
encoder _save_file = r'C:\Users\LZ_Jaja\PycharmProjects\Show_and_Tell_190314\model_and_eval' + save_path + r'\encoder.h5'
tf.keras.models.save_model(encoder, embedding_w_save_file)
Я пробовал model.save()
и tf.keras.models.save_model()
.Оба они вызывают одну и ту же ошибку.Ниже приведена ошибка:
Traceback (последний вызов был последним): файл "C: /Users/LZ_Jaja/PycharmProjects/Show_and_Tell_190314/model_train_and_save.py", строка 138, в файле tf.keras.models.save_model (кодировщик, embedding_w_save_file) Файл "C: \ Users \ LZ_Jaja \ Anaconda3 \ envs \ensorflow_gpu \ lib \ site-packages \ tenorflow \ python \ keras \ engine \ save.py", строка 101, в save_model 'config': модель.get_config () Файл "C: \ Users \ LZ_Jaja \ Anaconda3 \ envs \ensorflow_gpu \ lib \ site-packages \ensorflow \ python \ keras \ engine \ network.py", строка 1111, в get_config поднять NotImplementedError NotImplementedError
Я также пытался сохранить архитектуру и веса соответственно, но при использовании model.to_yaml()
также возникает ошибка.
model.save_weights()
действует.Но при загрузке весов с помощью model.load_weights()
возникает ошибка, в которой говорится, что я пытаюсь заполнить 0 слой весами с 1 слоем (я точно забываю информацию об ошибке).
Так что мне нужна помощь.Как сохранить модель и правильно загрузить ее?