Keras 2 API 文档 / 层 API / 核心层 / Lambda 层

Lambda 层

[源代码]

Lambda

tf_keras.layers.Lambda(
    function, output_shape=None, mask=None, arguments=None, **kwargs
)

将任意表达式包装为 Layer 对象。

Lambda 层的存在是为了在构建 Sequential 和 Functional API 模型时,可以将任意表达式用作 LayerLambda 层最适合简单的操作或快速实验。对于更高级的用例,请遵循 本指南,了解如何子类化 tf.keras.layers.Layer

警告:tf.keras.layers.Lambda 层具有(反)序列化限制!

子类化 tf.keras.layers.Layer 而不是使用 Lambda 层的主要原因是保存和检查模型。Lambda 层通过序列化 Python 字节码来保存,这从根本上来说是不可移植的。它们只能在保存它们的同一环境中加载。子类化的层可以通过覆盖它们的 get_config() 方法以更可移植的方式保存。依赖于子类化层的模型通常也更容易可视化和理解。

示例

# add a x -> x^2 layer
model.add(Lambda(lambda x: x ** 2))
# add a layer that returns the concatenation
# of the positive part of the input and
# the opposite of the negative part

def antirectifier(x):
    x -= K.mean(x, axis=1, keepdims=True)
    x = K.l2_normalize(x, axis=1)
    pos = K.relu(x)
    neg = K.relu(-x)
    return K.concatenate([pos, neg], axis=1)

model.add(Lambda(antirectifier))

关于变量的注意事项

虽然可以在 Lambda 层中使用变量,但不建议这样做,因为它很容易导致错误。例如,考虑以下层

scale = tf.Variable(1.)
scale_layer = tf.keras.layers.Lambda(lambda x: x * scale)

由于 scale_layer 不直接跟踪 scale 变量,它不会出现在 scale_layer.trainable_weights 中,因此如果 scale_layer 在模型中使用,它将不会被训练。

更好的模式是编写一个子类化的 Layer

class ScaleLayer(tf.keras.layers.Layer):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.scale = tf.Variable(1.)

    def call(self, inputs):
        return inputs * self.scale

总的来说,Lambda 层对于简单的无状态计算很方便,但任何更复杂的操作都应该使用子类化的 Layer。

参数

  • function:要评估的函数。将输入张量作为第一个参数。
  • output_shape:函数预期的输出形状。如果未显式提供,则可以推断此参数。可以是元组或函数。如果是元组,则仅指定第一个维度之后的内容;样本维度假定与输入相同:output_shape = (input_shape[0], ) + output_shape,或者输入为 None 且样本维度也为 Noneoutput_shape = (None, ) + output_shape。如果是函数,则将整个形状指定为输入形状的函数:output_shape = f(input_shape)
  • mask:None(表示不进行掩码)或具有与 compute_mask 层方法相同签名的可调用对象,或者一个张量,无论输入是什么,都将作为输出掩码返回。
  • arguments:要传递给函数的关键字参数的可选字典。

输入形状 任意。当将此层用作模型中的第一层时,请使用关键字参数 input_shape(整数元组,不包括样本轴)。

整数,不包括样本轴)。

输出形状 由 output_shape 参数指定