LSTM如何处理变长序列

我在《Python深度学习》的第7章第1节中发现了一段代码如下:

from keras.models import Modelfrom keras import layersfrom keras import Inputtext_vocabulary_size = 10000question_vocabulary_size = 10000answer_vocabulary_size = 500# Our text input is a variable-length sequence of integers.# Note that we can optionally name our inputs!text_input = Input(shape=(None,), dtype='int32', name='text')# Which we embed into a sequence of vectors of size 64embedded_text = layers.Embedding(64, text_vocabulary_size)(text_input)# Which we encoded in a single vector via a LSTMencoded_text = layers.LSTM(32)(embedded_text)# Same process (with different layer instances) for the questionquestion_input = Input(shape=(None,), dtype='int32', name='question')embedded_question = layers.Embedding(32, question_vocabulary_size)(question_input)encoded_question = layers.LSTM(16)(embedded_question)# We then concatenate the encoded question and encoded textconcatenated = layers.concatenate([encoded_text, encoded_question], axis=-1)# And we add a softmax classifier on topanswer = layers.Dense(answer_vocabulary_size, activation='softmax')(concatenated)# At model instantiation, we specify the two inputs and the output:model = Model([text_input, question_input], answer)model.compile(optimizer='rmsprop',              loss='categorical_crossentropy',              metrics=['acc'])

如您所见,这个模型的输入没有原始数据的形状信息,然后在Embedding层之后,LSTM的输入或Embedding的输出是一些变长序列。

model_summary

所以我想知道:

  • 在这个模型中,Keras如何确定LSTM层中的lstm_unit数量
  • 如何处理变长序列

附加信息:为了解释lstm_unit是什么(我不知道该如何称呼它,所以就展示图片):

lstm_unit


回答:

提供的循环层继承自基础实现keras.layers.Recurrent,它包括选项return_sequences,默认值为False。这意味着默认情况下,循环层将消耗变长输入,并最终仅在最后一个序列步骤输出层的输出。

因此,使用None来指定变长输入序列维度是没有问题的。

但是,如果您希望层返回完整的输出序列,即输入序列每个步骤的输出张量,那么您将需要进一步处理该输出的变长大小。

您可以通过让下一层进一步接受变长输入来做到这一点,并推迟到网络后期解决这个问题,最终您必须从某个变长事物中计算损失函数,或者在继续到后续层之前计算某个固定长度的表示,这取决于您的模型。

或者,您可以通过要求固定长度的序列来做到这一点,可能需要在序列末尾填充特殊的哨兵值,这些值仅用于填充长度,指示一个空序列项。

另外,Embedding层是一个非常特殊的层,它也被设计为处理变长输入。输出形状将为输入序列的每个标记提供不同的嵌入向量,因此形状将是(批次大小,序列长度,嵌入维度)。由于下一层是LSTM,这没有问题…它也会愉快地消耗变长序列。

但正如在Embedding的文档中提到的:

input_length: 当输入序列长度恒定时,输入序列的长度。      如果您打算连接      `Flatten`然后是`Dense`层,则需要此参数      (没有它,无法计算密集输出的形状)。

如果您想直接从Embedding转换到非变长表示,那么您必须在层中提供固定的序列长度。

最后,请注意,当您表达LSTM层的维度时,例如LSTM(32),您是在描述该层的输出空间的维度。

# 输入序列的示例,例如批次大小为1。[ [34],  [27],  ...] --> # 输入到嵌入层[  [34标记的64-d表示 ...],  [27标记的64-d表示 ...],  ...] --> # 输入到LSTM层[32-d的LSTM最终序列步骤的输出向量]

为了避免批次大小为1的低效性,一种策略是按每个示例的序列长度对输入训练数据进行排序,然后根据常见的序列长度分组成批次,例如使用自定义的Keras DataGenerator。

这样做的优点是允许使用较大的批次大小,特别是如果您的模型可能需要批量归一化或涉及GPU密集型训练,甚至只是为了批量更新的梯度估计更不嘈杂的好处。但它仍然允许您处理具有不同示例不同批次长度的输入训练数据集。

更重要的是,它还具有一个很大的优势,即您不必管理任何填充以确保输入中的常见序列长度。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注