如何在Keras中使用LSTM层还原保存的模型

时间:2018-08-12 13:09:48

标签: python tensorflow machine-learning keras lstm

我遵循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)

就预测而言,通常在训练时构造文本生成,并且模型学习一些单词。但是,当加载保存的模型时,文本生成是完全随机的,就像权重被随机初始化一样。

1 个答案:

答案 0 :(得分:1)

经过一番挖掘,我终于发现问题是我在字符和单一向量之间创建字典映射的方式。我使用char = list(set(data))函数来获取文件中所有字符的列表,然后将字符的索引分配为该字符的“代码号”。但是,显然list(set(data))函数并不总是输出相同的列表,而是针对python的每个“会话”随机化了顺序。因此,我的字典映射曾经在保存和加载模型之间进行切换,因为那是在不同的脚本中进行的。使用char = sorted(list(set(data)))可解决此问题。