关于"了解Keras LSTM"的疑问

Jos*_*Jos 12 deep-learning lstm keras recurrent-neural-network

我是LSTM的新手,经历了理解Keras LSTM,并对Daniel Moller的漂亮答案产生了一些愚蠢的怀疑.

以下是我的一些疑问:

  1. Achieving one to many 编写的部分下指定了两种方法  ,我们可以使用stateful=True 这些方法循环地获取一步的输出并将其作为下一步的输入(需要output_features == input_features).

    在该One to many with repeat vector图中,重复矢量在所有时间步长中One to many with stateful=True作为输入馈送,而在输出中在下一个时间步骤中作为输入馈送.那么,我们不是通过使用stateful=True?来改变图层的工作方式吗?

    在构建RNN时,应遵循以上哪两种方法(使用重复向量或将前一时间步输出作为下一个输入)?

  2. 在该One to many with stateful=True部分下,为了改变one to many预测手动循环代码中的行为,我们将如何知道steps_to_predict变量,因为我们事先并不知道输出序列长度.

    我也不明白整个模型使用last_step output生成方式的方式next_step ouput.它使我对model.predict()功能的工作感到困惑.我的意思是,不是model.predict()同时预测整个输出序列而不是循环通过no. of output sequences(我仍然不知道它的值)生成并做model.predict()预测给定迭代中的特定时间步输出?

  3. 我无法理解整个Many to many案例.任何其他链接都会有所帮助.

  4. 我知道我们model.reset_states()用来确保新批次独立于前一批次.但是,我们是否手动创建批次序列,以便一个批次跟随另一个批次,或者Kerasstateful=True模式下自动将序列分成这样的批次.

    如果它是手动完成的,那么为什么有人会将数据集划分为这样的批次,其中序列的一部分在一个批次中而另一个在下一批次中?

  5. 最后,将使用哪些实际实现或示例/用例stateful=True(因为这似乎是不寻常的)?我正在学习LSTM,这是我第一次被介绍到statefulKeras.

任何人都可以帮我解释我的愚蠢问题,以便我能清楚地了解Keras的LSTM实施情况吗?

编辑:询问其中一些是为了澄清当前的答案,还有一些是为了解决剩下的疑问

.因此,基本上有状态让我们keep OR reset在每批之后都处于内部状态.那么,如果我们在每批训练后一次又一次地重复重置内部状态,模型将如何学习?重置是否意味着重置参数(用于计算隐藏状态)?

.在线If stateful=False: automatically resets inner state, resets last output step.重置最后一个输出步骤是什么意思?我的意思是,如果每个时间步都产生自己的输出,那么重置最后一个输出步骤意味着什么呢?

Ç.作为对Question 2第二点的回应Question 4,我仍然没有得到你manipulate the batches between each iteration的需要stateful((最后一行Question 2)只重置状态).我发现我们不知道在时间步长中生成的每个输出的输入.

所以,你将序列分解为序列only one-step然后使用, new_step = model.predict(last_step)但是你怎么知道你需要多长时间一次又一次地做这个(必须有一个循环的停止点)?另外,请解释该stateful部分(在最后一行Question 2).

d.在下面的代码中One to many with stateful=True,似乎for循环(手动循环)用于预测下一个单词仅在测试时使用.模型是否在火车时刻将这个东西包含在内,还是我们还manually需要在火车时刻使用这个循环?

Ë.假设我们正在进行一些机器翻译工作,我认为在整个输入(要翻译的语言)被输入到输入时间步骤然后在每个时间步骤生成输出(翻译语言)之后,将发生序列中断.将通过manual loop因为现在我们最终得到输入并开始使用迭代在每个时间步产生输出.我做对了吗?

˚F.作为LSTMs的默认工作需要在答复中提到3分的东西,所以在序列的断裂的情况下,current_inputprevious_output馈送有相同的载体,因为它们在没有电流输入是可用的情况下,值是一样的吗?

.在Predicting:部分下,在manyful = True的多对多下,代码为:

predicted = model.predict(totalSequences)
firstNewStep = predicted[:,-1:]
Run Code Online (Sandbox Code Playgroud)

由于手动循环finding the very next word in the current sequence到目前为止还没有用完,我如何知道count预测的时间步长,model.predict(totalSequences)以便predicted[:,-1:]后来从predict()的最后一步用于生成其余的序列?我的意思是,我如何知道(之后使用)predicted = model.predict(totalSequences)之前生成的序列数manual for loop.

编辑2:

.作为D回答,我仍然没有得到如何训练我的模型?我知道使用手动循环(在训练期间)可能会非常痛苦,但如果我不使用它,那么在何种情况下如何训练模型we want the 10 future steps, we cannot output them at once because we don't have the necessary 10 input steps呢?将简单地用来model.fit()解决我的问题?

.D回答最后一段,You could train step by step using train_on_batch only in the case you have the expected outputs of each step. But otherwise I think it's very complicated or impossible to train..

你能更详细地解释一下吗?

什么step by step意思?如果我没有 OR 后续序列的输出,那将如何影响我的训练?在训练期间我还需要手动循环吗?如果没有,那么该model.fit()功能是否会按预期工作?

.我把它解释"repeat" option为使用了repeat vector.不会使用重复向量对one to many案例有利并且不适合这种many to many情况,因为后者将有许多输入向量可供选择(用作单个重复向量)?您将如何使用repeat vectormany to many呢?

Dan*_*ler 17

问题3

理解问题3是理解其他问题的关键,所以,让我们先尝试一下.

Keras中的所有重复层都执行隐藏循环.这些循环对我们来说完全不可见,但我们可以在最后看到每次迭代的结果.

不可见迭代的数量等于time_steps维度.因此,关于步骤,LSTM的重复计算发生.

如果我们使用X步传递输入,则会有X个不可见的迭代.

LSTM中的每次迭代都需要3个输入:

  • 此步骤的输入数据的相应切片
  • 图层的内部状态
  • 最后一次迭代的输出

因此,请使用以下示例图像,其中我们的输入有5个步骤:

很多很多

Keras会在一次预测中做些什么?

  • 第0步:
    • 采取输入的第一步,input_data[:,0,:]形状为切片(batch, 2)
    • 采取内部状态(此时为零)
    • 采取最后一个输出步骤(第一步不存在)
    • 通过计算到:
      • 更新内部状态
      • 创建一个输出步骤(输出0)
  • 步骤1:
    • 采取下一步输入: input_data[:,1,:]
    • 采取更新的内部状态
    • 获取最后一步生成的输出(输出0)
    • 通过相同的计算:
      • 再次更新内部状态
      • 再创建一个输出步骤(输出1)
  • 第2步:
    • 采取 input_data[:,2,:]
    • 采取更新的内部状态
    • 取输出1
    • 通过:
      • 更新内部状态
      • 创建输出2
  • 依此类推,直到第4步.

  • 最后:

    • 如果stateful=False:自动重置内部状态,则重置上一个输出步骤
    • 如果stateful=True:保持内部状态,请保持最后一步

您将看不到任何这些步骤.它看起来只是一次通过.

但你可以选择:

  • return_sequences = True:返回每个输出步骤,形状 (batch, steps, units)
    • 这对许多人来说确实很多.您在输出中获得的输出步数与输入中的步数相同
  • return_sequences = False:仅返回最后一个输出步骤,shape (batch, units)
    • 这是多对一的.您为整个输入序列生成单个结果.

现在,这回答了问题2的第二部分:是的,predict将在没有您注意的情况下计算所有内容.但:

输出步数将等于输入步数

问题4

现在,在回答问题2之前,让我们看看4,这实际上是答案的基础.

是的,批次分工应该手动完成.Keras不会改变您的批次.那么,为什么我要分割一个序列呢?

  • 1,序列太大,一批不适合计算机或GPU的内存
  • 2,你想做问题2中发生的事情:操纵每一步迭代之间的批次.

问题2

在问题2中,我们"预测未来".那么,输出步骤的数量是多少?嗯,这是你想要预测的数字.假设您正在尝试根据过去预测您将拥有的客户数量.您可以决定预测未来一个月或10个月.你的选择.

现在,你认为这predict会立即计算整个事情是正确的,但请记住上面的问题3,我说:

输出步数等于输入步数

还要记住,第一个输出步骤是第一个输入步骤的结果,第二个输出步骤是第二个输入步骤的结果,依此类推.

但我们想要的是未来,而不是一个接一个地与之前步骤相匹配的东西.我们希望结果步骤遵循"最后"步骤.

因此,我们面临一个限制:如果我们没有各自的输入,如何定义固定数量的输出步骤?(远期未来的投入也是未来,因此,它们不存在)

这就是为什么我们将序列分解为只有一步的序列.所以predict只会输出一步.

当我们这样做时,我们能够在每次迭代之间操纵批次.我们有能力将输出数据(我们之前没有)输入数据作为输入数据.

有状态是必要的,因为我们希望每个步骤都作为单个序列连接(不要丢弃状态).

问题5

stateful=True我所知道的最佳实际应用是问题2的答案.我们想要在步骤之间操纵数据.

这可能是一个虚拟示例,但另一个应用程序是您例如从互联网上的用户接收数据.用户每天使用您的网站时,您都会向模型再提供一步数据(并且您希望以相同的顺序继续此用户以前的历史记录).

问题1

然后,最后问题1.

我会说:总是避免stateful=True,除非你需要它.
您不需要它来构建一对多网络,因此,最好不要使用它.

请注意,此stateful=True示例与预测未来示例相同,但您从一个步骤开始.它很难实现,因为手动循环会有更快的速度.但是你可以控制输出步骤的数量,在某些情况下这可能是你想要的.

计算也会有所不同.在这种情况下,如果一个人比另一个人好,我真的无法回答.但我不相信会有很大的不同.但网络是某种"艺术",测试可能带来有趣的惊喜.

编辑的答案:

一个

我们不应该将"状态"误认为是"权重".它们是两个不同的变量.

  • 权重:可学习的参数,它们永远不会重置.(如果重置重量,则会丢失模型学到的所有内容)
  • 状态:一批序列的当前记忆(涉及我现在的序列上的哪个步骤以及我从该批次中的特定序列"学到的"到本步骤).

想象一下,你正在看一部电影(一个序列).每一秒都会让你建立记忆,如角色的名字,他们做了什么,他们的关系是什么.

现在想象你得到一部你以前从未见过的电影并开始观看电影的最后一秒.你不会理解电影的结尾,因为你需要这部电影的前一个故事.(美国)

现在你想看完整部电影.现在你将开始观看一部新电影(一个新的序列).您不需要记住上次看过的电影中发生的事情.如果你试图"加入电影",你会感到困惑.

在这个例子中:

  • 重量:你的能力,理解和解读为此电影,记住重要的名字和行动
  • 状态:在一部停顿的电影中,状态是从一开始到现在发生的事情的记忆.

所以,国家"没有学到".状态是"计算的",逐步建立批次中的每个单独序列.这就是为什么:

  • 重置状态意味着从步骤0开始新序列(开始一部新电影)
  • 保持状态意味着从最后一步继续相同的序列(继续暂停的电影,或观看该故事的第2部分)

国家正是使经常性网络发挥作用的过程,好像它们具有"过去的记忆".

在LSTM中,最后一个输出步骤是"状态"的一部分.

LSTM状态包含:

  • 通过计算更新每一步的存储矩阵
  • 最后一步的输出

所以,是的:每一步产生自己的输出,但每一步都使用最后一步的输出作为状态.这就是LSTM的构建方式.

  • 如果要"继续"相同的序列,则需要记忆最后一步的结果
  • 如果要"启动"新序列,则不希望记忆最后一步结果(如果不重置状态,这些结果将保留存储)

C

你什么时候停下来.您想要预测未来几步?那是你的停止点.

想象一下,我有一个包含20个步骤的序列.我想预测未来的10个步骤.

在标准(非有状态)网络中,我们可以使用:

  • 一次输入19个步骤(从0到18)
  • 一次输出19个步骤(从1到19)

这是"预测下一步"(注意shift = 1步).我们可以这样做,因为我们拥有所有可用的输入数据.

但是当我们想要10个未来的步骤时,我们不能一次输出它们,因为我们没有必要的10个输入步骤(这些输入步骤是未来的,我们需要模型来预测它们).

因此,我们需要从现有数据预测未来的一个步骤,然后将此步骤用作下一步未来步骤的输入.

但我希望这些步骤都是相互关联的.如果我使用stateful=False,模型将看到很多"长度为1的序列".不,我们想要一个长度为30的序列.

d

这是一个非常好的问题,你让我....

一对一的有状态是我在写答案时的一个想法,但我从未使用过这个.我更喜欢"重复"选项.

train_on_batch只有在每个步骤具有预期输出的情况下,才可以逐步训练.但除此之外,我认为训练非常复杂或不可能.

Ë

这是一种常见的方法.

  • 使用网络生成精简向量(此向量可以是结果,也可以是生成的状态,或两者都是)
  • 使用此压缩向量作为另一个网络的初始输入/状态,手动逐步生成,并在模型生成"句末"单词或字符时停止.

还有固定尺寸的型号没有手动循环.您认为您的句子的最大长度为X个单词.比这短的结果句子用"句末"或"空"字/字符完成.一个Masking层是在这些模型中是非常有用的.

F

您只提供输入.另外两件事(最后输出和内部状态)已经存储在有状态层中.

我只输入input = last输出,因为我们的特定模型正在预测下一步.这就是我们想要的.对于每个输入,下一步.

我们用训练中的移位序列来教导它.

G

没关系.我们只想要最后一步.

  • 序列数由第一个保留:.
  • 并且只考虑最后一步-1:.

但如果你想知道,你可以打印predicted.shape.它等于totalSequences.shape这个模型.

编辑2

一世

首先,我们不能使用"一对多"模型来预测未来,因为我们没有这方面的数据.如果您没有序列步骤的数据,则无法理解"序列".

因此,这种类型的模型应该用于其他类型的应用程序.正如我之前所说,我对这个问题的答案并不是很好.首先要有一个"目标",然后我们决定哪种模型更适合该目标.

II

"一步一步"是指手动循环.

如果你没有后续步骤的输出,我认为不可能训练.它根本不是一个有用的模型.(但我不是那个知道一切的人)

如果您有输出,是的,您可以训练整个序列而fit不必担心手动循环.

III

你是对的III.您不会在多对多中使用重复向量,因为您有不同的输入数据.

"一对多"和"多对多"是两种不同的技术,每种技术都有其优点和缺点.一个适用于某些应用程序,另一个适用于其他应用程序.

  • 1+ 此答案应作为短论文提交:) (2认同)