为什么为tf.keras.layers.LSTM设置return_sequences = True和stateful = True?

问题描述 投票:1回答:3

我正在学习tensorflow2.0并遵循tutorial。在rnn示例中,我找到了代码:

def build_model(vocab_size, embedding_dim, rnn_units, batch_size):
  model = tf.keras.Sequential([
    tf.keras.layers.Embedding(vocab_size, embedding_dim, 
                              batch_input_shape=[batch_size, None]),
    tf.keras.layers.LSTM(rnn_units, 
                        return_sequences=True, 
                        stateful=True, 
                        recurrent_initializer='glorot_uniform'),
    tf.keras.layers.Dense(vocab_size)
  ])
  return model

我的问题是:为什么代码设置参数return_sequences=Truestateful=True?如何使用默认参数?

tensorflow keras lstm recurrent-neural-network
3个回答
2
投票

Return Sequences

让我们看一下使用LSTM构建的典型模型架构。

序列模型序列:

enter image description here

我们输入一系列输入(x),一次一批,每个LSTM单元返回一个输出(y_i)。因此,如果您的输入大小为batch_size x time_steps X input_size,则LSTM输出将为batch_size X time_steps X output_size。这称为序列到序列模型,因为输入序列被转换为输出序列。该模型的典型用法是tagger(POS tagger,NER Tagger)。在keras中,这是通过设置return_sequences=True来实现的。

序列分类 - 多对一架构

enter image description here

在多对一架构中,我们使用唯一最后一个LSTM单元的输出状态。这种架构通常用于分类问题,例如预测电影评论(表示为单词序列)是否是-ve的+ ve。在keras中,如果我们设置return_sequences=False,模型将返回仅最后一个LSTM单元的输出状态。

Statefull

LSTM单元由许多门组成,如下图所示from。前一个单元的状态/门用于计算当前单元的状态。在keras,如果statefull=False然后状态在每批后重置。如果statefull=True指数i的前一批状态将在下一批中用作指数i的初始状态。所以状态信息在statefull=True批次之间传播。通过一个例子检查这个link有关statefullness有用性的解释。

http://colah.github.io/posts/2015-08-Understanding-LSTMs/


2
投票

本教程中的示例是关于文本生成的。这是批量输入网络的输入:

(64,100,65)#(batch_size,sequence_length,vocab_size)

  1. return_sequences=True

由于意图是为每个时间步骤预测一个字符,即对于序列中的每个字符,需要预测下一个字符。

因此,参数return_sequences=True设置为true,以获得(64,100,65)的输出形状。如果此参数设置为False,则仅返回最后一个输出,因此对于64的批处理,输出将是(64,65),即对于100个字符的每个序列,仅返回最后预测的字符。

  1. stateful=True

从文档中,“如果为True,则批次中索引i处的每个样本的最后状态将用作下一批次中索引i的样本的初始状态。”

在本教程的下图中,您可以看到设置有状态有助于LSTM通过提供先前预测的上下文来做出更好的预测。

enter image description here


1
投票

让我们看看玩弄参数时的不同之处:

tf.keras.backend.clear_session()
tf.set_random_seed(42)
X = np.array([[[1,2,3],[4,5,6],[7,8,9]],[[1,2,3],[4,5,6],[0,0,0]]], dtype=np.float32)
model = tf.keras.Sequential([tf.keras.layers.LSTM(4, return_sequences=True, stateful=True, recurrent_initializer='glorot_uniform')])
print(tf.keras.backend.get_value(model(X)).shape)
# (2, 3, 4)
print(tf.keras.backend.get_value(model(X)))
# [[[-0.16141939  0.05600287  0.15932009  0.15656665]
#  [-0.10788933  0.          0.23865232  0.13983202]
   [-0.          0.          0.23865232  0.0057992 ]]

# [[-0.16141939  0.05600287  0.15932009  0.15656665]
#  [-0.10788933  0.          0.23865232  0.13983202]
#  [-0.07900514  0.07872108  0.06463861  0.29855606]]]

因此,如果return_sequences设置为True,则模型返回它预测的完整序列。

tf.keras.backend.clear_session()
tf.set_random_seed(42)
model = tf.keras.Sequential([
tf.keras.layers.LSTM(4, return_sequences=False, stateful=True, recurrent_initializer='glorot_uniform')])
print(tf.keras.backend.get_value(model(X)).shape)
# (2, 4)
print(tf.keras.backend.get_value(model(X)))
# [[-0.          0.          0.23865232  0.0057992 ]
#  [-0.07900514  0.07872108  0.06463861  0.29855606]]

因此,正如文档所述,如果return_sequences设置为False,则模型仅返回最后一个输出。

至于stateful,有点难以深入研究。但基本上,它的作用是当有多批输入时,批处理i的最后一个单元状态将是批处理i+1的初始状态。但是,我认为你使用默认设置会更好。

热门问题
推荐问题
最新问题