Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Keras序列模型-如何在测试/生成期间生成数据?_Python_Keras_Recurrent Neural Network - Fatal编程技术网

Python 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

有没有办法使用已经训练过的RNN(SimpleRN或LSTM)模型在KERA中生成新序列

我试图修改Coursera Deep Learning Specialization-course中的一个练习,您可以训练RNN生成恐龙的名字。在本练习中,您仅使用numpy构建RNN,但我想使用Keras

其中一个问题是序列的长度不同(恐龙名称),因此我使用了填充,并将序列长度设置为数据集中出现的最大大小(我用0填充,这也是“\n”的代码)

我的问题是,一旦训练完成,如何生成实际序列?在本练习的numpy版本中,您获取上一个单元格的softmax输出,并将其用作分发,以对下一个单元格的新输入进行采样。但是,在测试/生成期间,有没有办法将前一个单元的输出连接到Keras中的下一个单元的输入

此外,还有一些附加问题:

  • 由于我使用了填充,我怀疑其准确性过于乐观。有没有办法告诉Keras不要在其精度计算中包含填充值
我做得对吗?有没有更好的方法将KERA用于不同长度的序列

您可以检查我的(WIP)代码。

从序列上训练过的模型推断 因此,在RNN模型和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,并将其用于推理模型,结果要好得多。将其作为单独的答案添加到解决方案中