拥有database
数千/数百万个有效句子。
创建一个字典,其中每个单词代表一个数字(保留 0 表示“无”,1 表示“句子开头”,2 表示“句子结尾”)。
word_dic = { "_nothing_": 0, "_start_": 1, "_end_": 2, "word1": 3, "word2": 4, ...}
reverse_dic = {v:k for k,v in word_dic.items()}
请记住在数据库中所有句子的开头和结尾添加"_start_"
和,并在结尾完成能够包含所有句子的所需长度。(理想情况下,使用 10 个或更少单词的句子,因此您的模型不会尝试创建更大的句子)。"_end_"
"_nothing_"
将所有句子转换为索引序列:
#supposing you have an array of shape (sentences, length) as string:
indices = []
for word in database.reshape((-1,)):
indices.append(word_dic[word])
indices = np.array(indices).reshape((sentences,length))
使用 keras 函数将其转换为分类词to_categorical()
cat_sentences = to_categorical(indices) #shape (sentences,length,dictionary_size)
提示:keras在这里有很多有用的文本预处理功能。
分离训练输入和输出数据:
#input is the sentences except for the last word
x_train = cat_sentences[:,:-1,:]
y_train = cat_sentences[:,1:,:]
让我们创建一个基于 LSTM 的模型,该模型将从之前的单词中预测下一个单词:
model = Sequential()
model.add(LSTM(dontKnow,return_sequences=True,input_shape=(None,dictionary_size)))
model.add(.....)
model.add(LSTM(dictionary_size,return_sequences=True,activation='sigmoid'))
#or a Dense(dictionary_size,activation='sigmoid')
x_train
用和编译和拟合这个模型y_train
:
model.compile(....)
model.fit(x_train,y_train,....)
stateful=True
在所有LSTM
层中使用相同的模型:
newModel = ......
从训练模型转移权重:
newModel.set_weights(model.get_weights())
以明确的方式创建您的包,形状(10, dictionary_size)
。
使用模型从单词中预测一个_start_
单词。
#reset the states of the stateful model before you start a 10 word prediction:
newModel.reset_states()
firstWord = newModel.predict(startWord) #startword is shaped as (1,1,dictionary_size)
这firstWord
将是一个向量,其大小dictionary_size
告诉(某种程度上)每个现有单词的概率。比较一下袋子里的字。您可以选择最高的概率,或者如果包中其他单词的概率也不错,则使用一些随机选择。
#example taking the most probable word:
firstWord = np.array(firstWord == firstWord.max(), dtype=np.float32)
再次执行相同操作,但现在firstWord
在模型中输入:
secondWord = newModel.predict(firstWord) #respect the shapes
重复这个过程,直到你得到一个句子。请注意,您可能会_end_
在包中的 10 个单词都满意之前找到。你可能会决定用更短的句子来完成这个过程,尤其是在其他单词概率很低的情况下。