Lambda
類別tf_keras.layers.Lambda(
function, output_shape=None, mask=None, arguments=None, **kwargs
)
將任意表達式包裝為 Layer
物件。
Lambda
層的存在是為了在建構序列式和函數式 API 模型時,可以使用任意表達式作為 Layer
。Lambda
層最適合簡單的操作或快速實驗。對於更進階的用例,請遵循此指南,透過子類化 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
層對於簡單的無狀態計算很方便,但任何更複雜的事情都應該改用子類化層。
參數
output_shape = (input_shape[0], ) + output_shape
,或者,輸入為 None
且樣本維度也為 None
:output_shape = (None, ) + output_shape
。如果是函式,則將整個形狀指定為輸入形狀的函式:output_shape = f(input_shape)
compute_mask
層方法相同簽名的可呼叫物件,或者是不管輸入是什麼都將作為輸出遮罩傳回的張量。輸入形狀:任意。當將此層作為模型中的第一層時,請使用關鍵字引數 input_shape(整數元組,不包括樣本軸)。
輸出形狀:由 output_shape
引數指定。
輸出形狀由 output_shape
引數指定