Python Keras序列模型-如何在测试/生成期间生成数据?
有没有办法使用已经训练过的RNN(SimpleRN或LSTM)模型在KERA中生成新序列 我试图修改Coursera Deep Learning Specialization-course中的一个练习,您可以训练RNN生成恐龙的名字。在本练习中,您仅使用numpy构建RNN,但我想使用Keras 其中一个问题是序列的长度不同(恐龙名称),因此我使用了填充,并将序列长度设置为数据集中出现的最大大小(我用0填充,这也是“\n”的代码) 我的问题是,一旦训练完成,如何生成实际序列?在本练习的numpy版本中,您获取上一个单元格的softmax输出,并将其用作分发,以对下一个单元格的新输入进行采样。但是,在测试/生成期间,有没有办法将前一个单元的输出连接到Keras中的下一个单元的输入 此外,还有一些附加问题:Python Keras序列模型-如何在测试/生成期间生成数据?,python,keras,recurrent-neural-network,Python,Keras,Recurrent Neural Network,有没有办法使用已经训练过的RNN(SimpleRN或LSTM)模型在KERA中生成新序列 我试图修改Coursera Deep Learning Specialization-course中的一个练习,您可以训练RNN生成恐龙的名字。在本练习中,您仅使用numpy构建RNN,但我想使用Keras 其中一个问题是序列的长度不同(恐龙名称),因此我使用了填充,并将序列长度设置为数据集中出现的最大大小(我用0填充,这也是“\n”的代码) 我的问题是,一旦训练完成,如何生成实际序列?在本练习的numpy
- 由于我使用了填充,我怀疑其准确性过于乐观。有没有办法告诉Keras不要在其精度计算中包含填充值
- 一个培训模型(使用序列而不是单个项目)
- 另一种预测模型(使用单个元素而不是序列)
from tensorflow.keras import models, layers
n_chars = 26
timesteps = 10
inp = layers.Input(shape=(timesteps, n_chars))
lstm = layers.LSTM(100, return_sequences=True)
out1 = lstm(inp)
dense = layers.Dense(n_chars, activation='softmax')
out2 = layers.TimeDistributed(dense)(out1)
model = models.Model(inp, out2)
model.summary()
现在,为了从这个模型中推断,您创建了另一个类似于下面的模型
inp_infer = layers.Input(shape=(1, n_chars))
# Inputs to feed LSTM states back in
h_inp_infer = layers.Input(shape=(100,))
c_inp_infer = layers.Input(shape=(100,))
# We need return_state=True so we are creating a new layer
lstm_infer = layers.LSTM(100, return_state=True, return_sequences=True)
out1_infer, h, c = lstm_infer(inp_infer, initial_state=[h_inp_infer, c_inp_infer])
out2_infer = layers.TimeDistributed(dense)(out1_infer)
# Our model takes the previous states as inputs and spits out new states as outputs
model_infer = models.Model([inp_infer, h_inp_infer, c_inp_infer], [out2_infer, h, c])
# We are setting the weights from the trained model
lstm_infer.set_weights(lstm.get_weights())
model_infer.summary()
那有什么不同呢。您可以看到,我们定义了一个新的输入层,它接受只有一个timestep(或者换句话说,只有一个项)的输入。然后模型输出一个具有单个时间步的输出(技术上我们不需要TimeDistributedLayer
。但为了一致性,我保留了它)。除此之外,我们将以前的LSTM状态输出作为输入,并生成新状态作为输出。更具体地说,我们有以下推理模型
- 输入:
张量列表[(无,1,n字符)(无,100),(无,100)]
- 输出:
张量列表[(无,1,n字符),(无,100),(无,100)]
import numpy as np
x = np.random.randint(0,2,size=(1, 1, n_chars))
h = np.zeros(shape=(1, 100))
c = np.zeros(shape=(1, 100))
seq_len = 10
for _ in range(seq_len):
print(x)
y_pred, h, c = model_infer.predict([x, h, c])
y_pred = x[:,0,:]
y_onehot = np.zeros(shape=(x.shape[0],n_chars))
y_onehot[np.arange(x.shape[0]),np.argmax(y_pred,axis=1)] = 1.0
x = np.expand_dims(y_onehot, axis=1)
此部分以首字母x,h,c
开头。获取预测值y\u pred,h,c
,并将其转换为以下行中的输入,然后将其分配回x,h,c
。因此,您可以选择继续进行n
迭代
关于屏蔽零
Keras确实提供了一个可用于此目的的层。问题的第二个答案似乎就是你想要的。我明白了-你创建一个lstm单元对象,然后训练它,在推理时使用它,这样你就可以将它与学习的权重和所有内容一起使用。很酷-会尝试一下的。是的。祝你好运我不确定,但是这个模型真的保留了以前单元格的状态吗?好的,所以我认为它没有。现在我将lstm单元格更改为返回_state=True,并将其用于推理模型,结果要好得多。将其作为单独的答案添加到解决方案中