我遵循tutorial使用LSTM并将莎士比亚的著作用作培训文件来生成英语文本。这是我参考的模型-
model = Sequential()
model.add(LSTM(HIDDEN_DIM, input_shape=(None, VOCAB_SIZE), return_sequences=True))
model.add(Dropout(0.2))
for i in range(LAYER_NUM - 1):
model.add(LSTM(HIDDEN_DIM, return_sequences=True))
model.add(TimeDistributed(Dense(VOCAB_SIZE)))
model.add(Activation('softmax'))
model.compile(loss="categorical_crossentropy", optimizer="rmsprop")
经过30个时期的训练,我使用model.save('model.h5')
保存了模型。至此,模型已经学习了基本格式,并且学到了一些单词。但是,当我尝试使用load_model('model.h5')
在新程序中加载模型并尝试生成一些文本时,最终会预测完全随机的字母和符号。这导致我认为模型权重没有正确还原,因为我在仅存储模型权重时遇到了相同的问题。那么,有没有其他方法可以存储和恢复经过训练的带有LSTM层的模型?
作为参考,为了生成文本,该函数随机生成一个字符并将其输入到模型中以预测下一个字符。这是功能-
def generate_text(model, length):
ix = [np.random.randint(VOCAB_SIZE)]
y_char = [ix_to_char[ix[-1]]]
X = np.zeros((1, length, VOCAB_SIZE))
for i in range(length):
X[0, i, :][ix[-1]] = 1
print(ix_to_char[ix[-1]], end="")
ix = np.argmax(model.predict(X[:, :i+1, :])[0], 1)
y_char.append(ix_to_char[ix[-1]])
return ('').join(y_char)
编辑
用于培训的代码段-
for nbepoch in range(1, 11):
print('Epoch ', nbepoch)
model.fit(X, y, batch_size=64, verbose=1, epochs=1)
if nbepoch % 10 == 0:
model.model.save('checkpoint_{}_epoch_{}.h5'.format(512, nbepoch))
generate_text(model, 50)
print('\n\n\n')
generate_text()只是从随机生成的字符开始预测新字符的函数。每隔10个训练周期,整个模型将保存为.h5文件。
用于加载模型的代码-
print('Loading Model')
model = load_model('checkpoint_512_epoch_10.h5')
print('Model loaded')
generate_text(model, 400)
就预测而言,通常在训练时构造文本生成,并且模型学习一些单词。但是,当加载保存的模型时,文本生成是完全随机的,就像权重被随机初始化一样。
答案 0 :(得分:1)
经过一番挖掘,我终于发现问题是我在字符和单一向量之间创建字典映射的方式。我使用char = list(set(data))
函数来获取文件中所有字符的列表,然后将字符的索引分配为该字符的“代码号”。但是,显然list(set(data))
函数并不总是输出相同的列表,而是针对python的每个“会话”随机化了顺序。因此,我的字典映射曾经在保存和加载模型之间进行切换,因为那是在不同的脚本中进行的。使用char = sorted(list(set(data)))
可解决此问题。