Keras 中 LSTM 层两个重要参数理解

keras.layers.LSTM 类中有两个常用但不容易理解的参数,分别是 return_sequencesreturn_state。对于两个参数,官方定义如下:

  • return_sequences: 布尔值。是返回输出序列中的最后一个输出,还是全部序列。
  • return_state: 布尔值。除了输出之外是否返回最后一个状态。

我们使用 Christopher Olah 撰写的 Understanding LSTM Networks 中的配图。

完整的 LSTM 输入门结构实际上就是完成对元状态的更新过程,得到 $C_t$:

而 LSTM 的输出门结构则使用 $tanh$ 促使 $C_{t}$ 变到 $[-1, 1]$ 的值域上,将两个输入 $h_{t-1}$ 和 $x_{t}$ 做 Sigmoid 激活后相乘,就得到最终输出 $h_t$:

keras.layers.LSTM 默认 return_sequences=Falsereturn_state=False。此时只会返回最终 $h_t$ 值。例如:

# 第一次实验
import numpy as np
import tensorflow as tf

# 建立模型
inputs = tf.keras.layers.Input(shape=(3, 1))
lstm = tf.keras.layers.LSTM(1)(inputs)
model = tf.keras.models.Model(inputs=inputs, outputs=lstm)
# t1, t2, t3 序列
data = np.atleast_3d([0.1, 0.2, 0.3])
model.predict(data)
array([[-0.07383346]], dtype=float32)

输出为 (samples,output_dim) 的 2D 张量。

如果设置 return_sequences=True,则输出全部序列,即每一个 Cell 的 $h_t$。

# 第二次实验
inputs = tf.keras.layers.Input(shape=(3, 1))
lstm = tf.keras.layers.LSTM(1, return_sequences=True)(inputs)
model = tf.keras.models.Model(inputs=inputs, outputs=lstm)

model.predict(data)
array([[[0.00679269],
        [0.01709353],
        [0.02898963]]], dtype=float32)

输出为 (samples,timesteps,output_dim) 的 3D 张量。

如果设置 return_state=True,则:

# 第三次实验
inputs = tf.keras.layers.Input(shape=(3, 1))
lstm = tf.keras.layers.LSTM(1, return_state=True)(inputs)
model = tf.keras.models.Model(inputs=inputs, outputs=lstm)

model.predict(data)
[array([[-0.01886126]], dtype=float32),
 array([[-0.01886126]], dtype=float32),
 array([[-0.04175678]], dtype=float32)]

输出 3 个值,第一个为最后一个步骤的 LSTM 隐藏状态输出 $h_t$。第二个同样为 LSTM 隐藏状态输出 $h_t$。最后一个为最后一步 LSTM 单元状态输出 $C_t$。

你可能奇怪了,前两个值一模一样。

接下来,我们看一下设置 return_sequences=Truereturn_state=True

# 第四次实验
inputs = tf.keras.layers.Input(shape=(3, 1))
lstm = tf.keras.layers.LSTM(
    1, return_sequences=True, return_state=True)(inputs)
model = tf.keras.models.Model(inputs=inputs, outputs=lstm)

model.predict(data)
[array([[[0.01515806],
         [0.04311799],
         [0.08097965]]], dtype=float32),
 array([[0.08097965]], dtype=float32),
 array([[0.15623903]], dtype=float32)]

现在明白第三次实验为什么会出现两个一模一样的值了吗?

实际上,因为第三次实验默认 return_sequences=False,所以第一个返回值为最后一步 $h_t$。所以,当我们设置 return_sequences=True 的时候,第一个返回值就是全部 Cell 的 $h_t$。同时,第二个参数始终返回最后一步 $h_t$。

最后需要注意,由于 Keras 会随机初始化参数,所以每一次实验的结果都是不一致的。