Keras 3 API 文档 / 层 API / 循环层 / 基础 RNN 层

基础 RNN 层

[来源]

RNN

keras.layers.RNN(
    cell,
    return_sequences=False,
    return_state=False,
    go_backwards=False,
    stateful=False,
    unroll=False,
    zero_output_for_mask=False,
    **kwargs
)

循环层的基类。

参数

  • cell: 一个 RNN 单元实例或一个 RNN 单元实例列表。RNN 单元是一个类,它具有
    • 一个 call(input_at_t, states_at_t) 方法,返回 (output_at_t, states_at_t_plus_1)。单元的调用方法还可以接收可选参数 constants,请参见下面的“关于传递外部常量的说明”。
    • 一个 state_size 属性。这可以是一个单个整数(单个状态),在这种情况下,它表示循环状态的大小。这也可以是一个整数列表/元组(每个状态一个大小)。
    • 一个 output_size 属性,一个单个整数。
    • 一个 get_initial_state(batch_size=None) 方法,该方法创建一个张量,该张量旨在作为初始状态传递给 call(),如果用户没有通过其他方式指定任何初始状态。返回的初始状态应具有形状 (batch_size, cell.state_size)。单元可以选择创建充满零的张量,或根据单元的实现创建其他值。inputs 是 RNN 层的输入张量,形状为 (batch_size, timesteps, features)。如果该方法没有由单元实现,RNN 层将创建一个形状为 (batch_size, cell.state_size) 的填充零的张量。在 cell 是 RNN 单元实例列表的情况下,单元将按顺序堆叠在 RNN 之上,从而形成一个高效的堆叠 RNN。
  • return_sequences: 布尔值(默认 False)。是否返回输出序列中的最后一个输出,或返回完整序列。
  • return_state: 布尔值(默认 False)。是否除了输出之外还返回最后一个状态。
  • go_backwards: 布尔值(默认 False)。如果 True,则反向处理输入序列并返回反转后的序列。
  • stateful: 布尔值(默认 False)。如果为 True,则批次中索引为 i 的每个样本的最后一个状态将用作后续批次中索引为 i 的样本的初始状态。
  • unroll: 布尔值(默认 False)。如果为 True,则网络将被展开,否则将使用符号循环。展开可以加速 RNN,但往往会更加占用内存。展开只适用于短序列。
  • zero_output_for_mask: 布尔值(默认 False)。是否输出应该对被掩盖的时间步使用零。请注意,此字段仅在 return_sequencesTrue 且提供 mask 时使用。如果您想要重用 RNN 的原始输出序列而不受被掩盖时间步的影响,例如,合并双向 RNN,则它很有用。

调用参数

  • inputs: 输入张量。
  • initial_state: 传递给单元的第一次调用的初始状态张量列表。
  • mask: 形状为 [batch_size, timesteps] 的二进制张量,指示是否应该掩盖给定的时间步。单个 True 条目表示应使用对应的时间步,而 False 条目表示应忽略对应的时间步。
  • training: Python 布尔值,指示层应该以训练模式还是推理模式运行。此参数在调用单元时传递给它。这用于使用 dropout 的单元。

输入形状

形状为 (batch_size, timesteps, features) 的 3D 张量。

输出形状

  • 如果 return_state: 一个张量列表。第一个张量是输出。其余张量是最后的状态,每个张量的形状为 (batch_size, state_size),其中 state_size 可以是一个高维张量形状。
  • 如果 return_sequences: 形状为 (batch_size, timesteps, output_size) 的 3D 张量。

掩盖

此层支持对具有可变时间步数量的输入数据进行掩盖。要在数据中引入掩码,请使用一个 keras.layers.Embedding 层,并将 mask_zero 参数设置为 True

关于在 RNN 中使用状态化的说明

您可以将 RNN 层设置为“有状态的”,这意味着为一个批次中的样本计算的状态将被重新用作下一个批次中的样本的初始状态。这假设不同连续批次中的样本之间存在一对一映射。

要启用状态化

  • 在层构造函数中指定 stateful=True
  • 为您的模型指定一个固定批次大小,方法是传递给第一个层:如果为顺序模型,则传递 batch_input_shape=(...)。否则,对于具有一个或多个输入层的函数式模型,则传递 batch_shape=(...) 给模型中的所有第一层。这是您输入的预期形状,包括批次大小。它应该是一个整数元组,例如 (32, 10, 100)
  • 调用 fit() 时指定 shuffle=False

要重置模型的状态,请在特定层或整个模型上调用 .reset_states()

关于指定 RNN 的初始状态的说明

您可以通过使用关键字参数 initial_state 调用 RNN 层来符号地指定 RNN 层的初始状态。initial_state 的值应为一个张量或张量列表,表示 RNN 层的初始状态。

您可以通过使用关键字参数 states 调用 reset_states 来数值地指定 RNN 层的初始状态。states 的值应为一个 NumPy 数组或 NumPy 数组列表,表示 RNN 层的初始状态。

示例

from keras.src.layers import RNN
from keras.src import ops

# First, let's define a RNN Cell, as a layer subclass.
class MinimalRNNCell(keras.layers.Layer):

    def __init__(self, units, **kwargs):
        super().__init__(**kwargs)
        self.units = units
        self.state_size = units

    def build(self, input_shape):
        self.kernel = self.add_weight(shape=(input_shape[-1], self.units),
                                      initializer='uniform',
                                      name='kernel')
        self.recurrent_kernel = self.add_weight(
            shape=(self.units, self.units),
            initializer='uniform',
            name='recurrent_kernel')
        self.built = True

    def call(self, inputs, states):
        prev_output = states[0]
        h = ops.matmul(inputs, self.kernel)
        output = h + ops.matmul(prev_output, self.recurrent_kernel)
        return output, [output]

# Let's use this cell in a RNN layer:

cell = MinimalRNNCell(32)
x = keras.Input((None, 5))
layer = RNN(cell)
y = layer(x)

# Here's how to use the cell to build a stacked RNN:

cells = [MinimalRNNCell(32), MinimalRNNCell(64)]
x = keras.Input((None, 5))
layer = RNN(cells)
y = layer(x)