Keras 3 API 文档 / Layer API / 基础 Layer 类

基础 Layer 类

[源码]

Layer

keras.layers.Layer(
    activity_regularizer=None,
    trainable=True,
    dtype=None,
    autocast=True,
    name=None,
    **kwargs
)

这是所有层继承的类。

Layer 是一个可调用对象,它接收一个或多个张量作为输入,并输出一个或多个张量。它包含在 call() 方法中定义的计算以及一个状态(权重变量)。状态可以在以下位置创建:

  • __init__() 中,例如通过 self.add_weight()
  • 在可选的 build() 方法中,该方法在第一次调用层(__call__())时被调用,并提供输入张量的形状,输入形状在初始化时可能未知。

层可以递归组合:如果你将一个 Layer 实例赋值给另一个 Layer 的属性,外部层将开始跟踪内部层创建的权重。嵌套层应在 __init__() 方法或 build() 方法中实例化。

用户只需实例化一个层,然后将其视为可调用对象即可。

参数

  • trainable: 布尔值,表示层的变量是否应该可训练。
  • name: 字符串,层的名称。
  • dtype: 层的计算和权重的 dtype(数据类型)。也可以是 keras.DTypePolicy,它允许计算和权重 dtype 不同。默认为 NoneNone 表示使用 keras.config.dtype_policy(),除非通过 keras.config.set_dtype_policy() 设置为其他值,否则默认为 float32 策略。

属性

  • name: 层的名称(字符串)。
  • dtype: 层权重的 dtype。是 layer.variable_dtype 的别名。
  • variable_dtype: 层权重的 dtype。
  • compute_dtype: 层计算的 dtype。层会自动将输入转换为此 dtype,从而使计算和输出也采用此 dtype。当与 keras.DTypePolicy 一起使用混合精度时,此值将与 variable_dtype 不同。
  • trainable_weights: 应包含在反向传播中的变量列表。
  • non_trainable_weights: 不应包含在反向传播中的变量列表。
  • weights: trainable_weights 和 non_trainable_weights 列表的拼接(按此顺序)。
  • trainable: 层是否应该被训练(布尔值),即其潜在可训练权重是否应作为 layer.trainable_weights 的一部分返回。
  • input_spec: 可选的 InputSpec 对象(或列表),用于指定层可以接受的输入的约束。

我们建议 Layer 的子类实现以下方法

  • __init__(): 定义自定义层属性,并使用 add_weight() 或其他状态创建不依赖于输入形状的层权重。
  • build(self, input_shape): 此方法可用于使用 add_weight() 或其他状态创建依赖于输入形状的权重。__call__() 将通过调用 build() 自动构建层(如果尚未构建)。
  • call(self, *args, **kwargs): 在确保 build() 已被调用后,在 __call__ 中调用。call() 执行将层应用于输入参数的逻辑。在 call() 中可以可选使用的两个保留关键字参数是:1. training(布尔值,表示调用处于推理模式还是训练模式)。2. mask(布尔张量,编码输入中的遮罩时间步长,例如在 RNN 层中使用)。此方法的典型签名是 call(self, inputs),如果层需要,用户可以可选地添加 trainingmask
  • get_config(self): 返回一个字典,其中包含用于初始化此层的配置。如果键与 __init__() 中的参数不同,则也应重写 from_config(self)。此方法在保存层或包含此层的模型时使用。

示例

这里有一个基本示例:一个包含两个变量 wb 的层,返回 y = w . x + b。它展示了如何实现 build()call()。设置为层属性的变量将被跟踪为层的权重(在 layer.weights 中)。

class SimpleDense(Layer):
    def __init__(self, units=32):
        super().__init__()
        self.units = units

    # Create the state of the layer (weights)
    def build(self, input_shape):
        self.kernel = self.add_weight(
            shape=(input_shape[-1], self.units),
            initializer="glorot_uniform",
            trainable=True,
            name="kernel",
        )
        self.bias = self.add_weight(
            shape=(self.units,),
            initializer="zeros",
            trainable=True,
            name="bias",
        )

    # Defines the computation
    def call(self, inputs):
        return ops.matmul(inputs, self.kernel) + self.bias

# Instantiates the layer.
linear_layer = SimpleDense(4)

# This will also call `build(input_shape)` and create the weights.
y = linear_layer(ops.ones((2, 2)))
assert len(linear_layer.weights) == 2

# These weights are trainable, so they're listed in `trainable_weights`:
assert len(linear_layer.trainable_weights) == 2

除了在训练期间通过反向传播更新的可训练权重外,层还可以拥有不可训练权重。这些权重应在 call() 期间手动更新。这里有一个计算其输入的运行总和的示例层

class ComputeSum(Layer):

  def __init__(self, input_dim):
      super(ComputeSum, self).__init__()
      # Create a non-trainable weight.
      self.total = self.add_weight(
        shape=(),
        initializer="zeros",
        trainable=False,
        name="total",
      )

  def call(self, inputs):
      self.total.assign(self.total + ops.sum(inputs))
      return self.total

my_sum = ComputeSum(2)
x = ops.ones((2, 2))
y = my_sum(x)

assert my_sum.weights == [my_sum.total]
assert my_sum.non_trainable_weights == [my_sum.total]
assert my_sum.trainable_weights == []

weights 属性

keras.layers.Layer.weights

层的所有权重变量列表。

layer.variables 不同,此属性不包含指标状态和随机种子。


trainable_weights 属性

keras.layers.Layer.trainable_weights

层的全部可训练权重变量列表。

这些是优化器在训练期间更新的权重。


non_trainable_weights 属性

keras.layers.Layer.non_trainable_weights

层的全部不可训练权重变量列表。

这些是优化器在训练期间不应更新的权重。与 layer.non_trainable_variables 不同,此属性不包含指标状态和随机种子。


[源码]

add_weight 方法

Layer.add_weight(
    shape=None,
    initializer=None,
    dtype=None,
    trainable=True,
    autocast=True,
    regularizer=None,
    constraint=None,
    aggregation="none",
    overwrite_with_gradient=False,
    name=None,
)

向层添加一个权重变量。

参数

  • shape: 变量的形状元组。必须完全定义(不能有 None 项)。如果未指定,则默认为 ()(标量)。
  • initializer: 用于填充初始变量值的初始化器对象,或内置初始化器的字符串名称(例如 "random_normal")。如果未指定,浮点变量默认为 "glorot_uniform",所有其他类型(例如 int、bool)默认为 "zeros"
  • dtype: 要创建的变量的 dtype(数据类型),例如 "float32"。如果未指定,则默认为层的变量 dtype(如果未指定,其本身默认为 "float32")。
  • trainable: 布尔值,表示变量是否应该通过反向传播进行训练,还是手动管理其更新。默认为 True
  • autocast: 布尔值,表示访问层变量时是否应自动转换类型。默认为 True
  • regularizer: 用于对权重应用惩罚的正则化器对象。这些惩罚在优化过程中累加到损失函数中。默认为 None
  • constraint: 在任何优化器更新后应用于变量的约束对象,或内置约束的字符串名称。默认为 None
  • aggregation: 可选字符串,可以是 None, "none", "mean", "sum""only_first_replica" 之一。在编写自定义数据并行训练循环时,使用此参数标注该变量应采用的多副本聚合类型。默认为 "none"
  • overwrite_with_gradient: 布尔值,表示是否用计算出的梯度覆盖变量。这对于 float8 训练很有用。默认为 False
  • name: 字符串,变量的名称。对于调试很有用。

trainable 属性

keras.layers.Layer.trainable

可设置的布尔值,表示此层是否应该可训练。


[源码]

get_weights 方法

Layer.get_weights()

layer.weights 的值作为 NumPy 数组列表返回。


[源码]

set_weights 方法

Layer.set_weights(weights)

从 NumPy 数组列表设置 layer.weights 的值。


[源码]

get_config 方法

Model.get_config()

返回对象的配置。

对象配置是一个 Python 字典(可序列化),包含重新实例化对象所需的信息。


[源码]

add_loss 方法

Layer.add_loss(loss)

可以在 call() 方法内部调用以添加标量损失。

示例

class MyLayer(Layer):
    ...
    def call(self, x):
        self.add_loss(ops.sum(x))
        return x

losses 属性

keras.layers.Layer.losses

来自 add_loss、正则化器和子层的标量损失列表。