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

时间:2019-03-22 08:56:18

标签: tensorflow keras lstm recurrent-neural-network

我正在学习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?如何使用默认参数?

3 个答案:

答案 0 :(得分: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 :(得分:2)

返回顺序

让我们看一下使用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。这称为序列到序列模型,因为输入序列被转换为输出序列。该模型的典型用法是在标记器(POS标记器,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,以获取有关示例示例的状态充满性说明。

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

答案 2 :(得分: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的初始状态。但是,我认为使用默认设置会更好。