Keras 2 API 文件 / 層 API / 核心層 / Lambda 層

Lambda 層

[原始碼]

Lambda 類別

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

將任意表達式包裝為 Layer 物件。

Lambda 層的存在是為了在建構序列式和函數式 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 用於模型中,它將不會被訓練。

一個更好的模式是編寫一個子類化的層

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 層對於簡單的無狀態計算很方便,但任何更複雜的事情都應該改用子類化層。

參數

  • 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 引數指定。

輸出形狀由 output_shape 引數指定