Python 获取LSTMs中的预测状态
我正在尝试使用以下模型生成莎士比亚文本:Python 获取LSTMs中的预测状态,python,keras,lstm,Python,Keras,Lstm,我正在尝试使用以下模型生成莎士比亚文本: model = Sequential() model.add(Embedding(len_vocab, 64)) model.add(LSTM(256, return_sequences=True)) model.add(TimeDistributed(Dense(len_vocab, activation='softmax'))) model.compile(loss='sparse_categorical_crossentropy', optimi
model = Sequential()
model.add(Embedding(len_vocab, 64))
model.add(LSTM(256, return_sequences=True))
model.add(TimeDistributed(Dense(len_vocab, activation='softmax')))
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam')
model.summary()
训练集由转换为数字的字符组成。其中x
的形状为(句子数,句子长度)
,而y
的形状相同,其中y
仅为x
偏移一个字符。在这种情况下,句子长度=40
然而,当我预测时,我一次预测一个字符。关于我如何使用模型进行拟合和预测,请参见下文:
for i in range(2):
model.fit(x,y, batch_size=128, epochs=1)
sentence = []
letter = np.random.choice(len_vocab,1).reshape((1,1)) #choose a random letter
for i in range(100):
sentence.append(val2chr(letter))
# Predict ONE letter at a time
p = model.predict(letter)
letter = np.random.choice(27,1,p=p[0][0])
print(''.join(sentence))
然而,不管我训练了多少个阶段,我得到的都是jibberish的输出其中一个可能的原因是我没有从之前的预测中获得单元内存
所以问题是,在我预测之前,如何确保状态被发送到下一个单元格
完整的jupyter笔记本示例如下
编辑1:
我刚刚意识到我需要以先前的LSTMs隐藏状态发送,而不仅仅是单元内存。
此后,我尝试将模型重做为:
batch_size = 64
model = Sequential()
model.add(Embedding(len_vocab, 64, batch_size=batch_size))
model.add(LSTM(256, return_sequences=True, stateful=True))
model.add(TimeDistributed(Dense(len_vocab, activation='softmax')))
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam')
model.summary()
但是,现在我无法一次预测一个字母,因为它需要
批量大小的输入。使用Keras训练字符rnn的标准方法可以在官方示例中找到:
该模型基于maxlen字符序列进行训练。
训练此网络时,LSTM状态在每个序列后重置(默认情况下,stateful=False)
一旦训练了这样的网络,您可能希望一次输入和预测一个角色。最简单的方法(据我所知)是构建另一个具有相同结构的Keras模型,使用第一个模型的权重对其进行初始化,但使用Keras“有状态”模式下的RNN层:
在这种模式下,Keras必须知道批次的完整形状(参见文档)。
由于您只想向网络提供一步字符的一个样本,因此批处理的形状为(1,1,len(chars))。正如@j-c-doe所指出的,您可以对一个批处理使用有状态选项并传递权重。我发现的另一种方法是继续展开LSTM并预测如下:
for i in range(150):
sentence.append(int2char[letter[-1]])
p = model.predict(np.array(letter)[None,:])
letter.append(np.random.choice(len(char2int),1,p=p[0][-1])[0])
注意:预测的维度非常重要<代码>np。数组(字母)[None,:]
给出一个(1,i+1)
形状。这样就不需要对模型进行修改
最重要的是,它不断地传递细胞状态记忆和隐藏状态。我不能完全确定它是否也通过了隐藏状态,或者它是否只是细胞状态。也许可以看看?@Yu-Yang我恐怕这不是我想要的。这是一个多对一的预测(即在我的场景中,40个字母用于预测一个字母)。我的重点是如何将状态传递到下一个元素问题上。
model = Sequential()
model.add(LSTM(128, stateful=True, batch_input_shape=(1, 1, len(chars))))
model.add(Dense(len(chars)))
model.add(Activation('softmax'))
for i in range(150):
sentence.append(int2char[letter[-1]])
p = model.predict(np.array(letter)[None,:])
letter.append(np.random.choice(len(char2int),1,p=p[0][-1])[0])