Layer
類別tf_keras.layers.Layer(trainable=True, name=None, dtype=None, dynamic=False, **kwargs)
這是所有層繼承的類別。
層是一個可呼叫的物件,它接受一個或多個張量作為輸入,並輸出一個或多個張量。它涉及在 call()
方法中定義的計算,以及狀態(權重變數)。狀態可以在不同的地方建立,方便子類別實作。
__init__()
中;build()
方法中,該方法由層的第一次 __call__()
呼叫,並提供輸入的形狀,這些形狀可能在初始化時未知;call()
時,有一些如下討論的注意事項。層是遞迴可組合的:如果你將 Layer 實例指定為另一個 Layer 的屬性,則外部層將開始追蹤內部層建立的權重。巢狀層應該在 __init__()
方法中實例化。
使用者只需實例化層,然後將其視為可呼叫的物件。
參數
tf.keras.mixed_precision.Policy
,允許計算和權重 dtype 不同。預設值 None
表示使用 tf.keras.mixed_precision.global_policy()
,除非設定為其他值,否則預設為 float32 策略。True
。例如,這適用於 Tree-RNN 或遞迴網路,或者通常適用於任何使用 Python 控制流操作張量的層。如果為 False
,我們假設該層可以安全地用於產生靜態計算圖。屬性
dtype
的別名。tf.keras.mixed_precision.Policy
一起使用時,此值會與 variable_dtype
不同。tf.keras.mixed_precision.Policy
文件以了解詳細資訊。layer.trainable_weights
的一部分傳回。InputSpec
物件) 清單,指定層可接受的輸入約束。我們建議 Layer
的子類別實作下列方法
__init__()
:定義自訂層屬性,並使用 add_weight()
或其他狀態建立不依賴輸入形狀的層權重。build(self, input_shape)
:此方法可用於使用 add_weight()
或其他狀態建立依賴於輸入形狀的權重。__call__()
會自動呼叫 build()
來建立層(如果尚未建立)。call(self, inputs, *args, **kwargs)
:在確認已呼叫 build()
後在 __call__
中呼叫。call()
執行將層應用於 inputs
的邏輯。第一次呼叫也可能會建立無法方便地在 build()
中建立的狀態;請參閱其 docstring 以了解詳細資訊。您可以在 call()
中選擇性使用的兩個保留關鍵字參數是:- training
(布林值,表示呼叫是否處於推論模式或訓練模式)。請參閱層/模型子類別化指南中的更多詳細資訊 - mask
(布林張量,用於編碼輸入中被遮蔽的時間步,用於 RNN 層)。請參閱層/模型子類別化指南中的更多詳細資訊。此方法的典型簽名是 call(self, inputs)
,如果層需要,使用者可以選擇性地新增 training
和 mask
。*args
和 **kwargs
僅在未來計劃新增更多輸入參數時有用。get_config(self)
:傳回包含用於初始化此層的組態的字典。如果鍵與 __init__
中的引數不同,則也要覆寫 from_config(self)
。當儲存層或包含此層的模型時,會使用此方法。範例
這是一個基本範例:具有兩個變數 w
和 b
的層,傳回 y = w . x + b
。它顯示如何實作 build()
和 call()
。設定為層屬性的變數會被追蹤為層的權重 (在 layer.weights
中)。
class SimpleDense(Layer):
def __init__(self, units=32):
super(SimpleDense, self).__init__()
self.units = units
def build(self, input_shape): # Create the state of the layer (weights)
w_init = tf.random_normal_initializer()
self.w = tf.Variable(
initial_value=w_init(shape=(input_shape[-1], self.units),
dtype='float32'),
trainable=True)
b_init = tf.zeros_initializer()
self.b = tf.Variable(
initial_value=b_init(shape=(self.units,), dtype='float32'),
trainable=True)
def call(self, inputs): # Defines the computation from inputs to outputs
return tf.matmul(inputs, self.w) + self.b
# Instantiates the layer.
linear_layer = SimpleDense(4)
# This will also call `build(input_shape)` and create the weights.
y = linear_layer(tf.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
請注意,add_weight()
方法提供建立權重的捷徑。
class SimpleDense(Layer):
def __init__(self, units=32):
super(SimpleDense, self).__init__()
self.units = units
def build(self, input_shape):
self.w = self.add_weight(shape=(input_shape[-1], self.units),
initializer='random_normal',
trainable=True)
self.b = self.add_weight(shape=(self.units,),
initializer='random_normal',
trainable=True)
def call(self, inputs):
return tf.matmul(inputs, self.w) + self.b
除了在訓練期間透過反向傳播更新的可訓練權重外,層還可以具有不可訓練的權重。這些權重旨在在 call()
期間手動更新。以下是一個計算其輸入運行總和的範例層
class ComputeSum(Layer):
def __init__(self, input_dim):
super(ComputeSum, self).__init__()
# Create a non-trainable weight.
self.total = tf.Variable(initial_value=tf.zeros((input_dim,)),
trainable=False)
def call(self, inputs):
self.total.assign_add(tf.reduce_sum(inputs, axis=0))
return self.total
my_sum = ComputeSum(2)
x = tf.ones((2, 2))
y = my_sum(x)
print(y.numpy()) # [2. 2.]
y = my_sum(x)
print(y.numpy()) # [4. 4.]
assert my_sum.weights == [my_sum.total]
assert my_sum.non_trainable_weights == [my_sum.total]
assert my_sum.trainable_weights == []
有關建立層的更多資訊,請參閱指南透過子類別化建立新層和模型。
weights
屬性tf_keras.layers.Layer.weights
傳回所有層變數/權重的清單。
傳回
變數的清單。
trainable_weights
屬性tf_keras.layers.Layer.trainable_weights
此層追蹤的所有可訓練權重清單。
可訓練權重在訓練期間透過梯度下降更新。
傳回
可訓練變數的清單。
non_trainable_weights
屬性tf_keras.layers.Layer.non_trainable_weights
此層追蹤的所有不可訓練權重清單。
不可訓練權重在訓練期間不會更新。它們預期會在 call()
中手動更新。
傳回
不可訓練變數的清單。
add_weight
方法Layer.add_weight(
name=None,
shape=None,
dtype=None,
initializer=None,
regularizer=None,
trainable=None,
constraint=None,
use_resource=None,
synchronization=tf.VariableSynchronization.AUTO,
aggregation=tf.VariableSynchronization.NONE,
**kwargs
)
向層新增新的變數。
參數
self.dtype
。synchronization
設定為 ON_READ
,則 trainable
不能為 True
。ResourceVariable
。請參閱本指南以了解更多資訊。tf.VariableSynchronization
類別中定義的常數。預設情況下,同步設定為 AUTO
,目前的 DistributionStrategy
會選擇何時同步。如果 synchronization
設定為 ON_READ
,則 trainable
不得設定為 True
。tf.VariableAggregation
類別中定義的常數。getter
、collections
、autocast
、experimental_autocast
和 caching_device
。傳回
建立的變數。
引發
trainable
設定為 True 且同步設定為 ON_READ
時。trainable
屬性tf_keras.layers.Layer.trainable
get_weights
方法Layer.get_weights()
以 NumPy 陣列的形式傳回層的目前權重。
層的權重代表層的狀態。此函式會傳回與此層關聯的可訓練和不可訓練權重值,以 NumPy 陣列列表的形式,這些權重值可以反過來用於將狀態載入類似參數化的層。
例如,Dense
層會傳回兩個值的列表:核心矩陣和偏差向量。這些可用於設定另一個 Dense
層的權重。
>>> layer_a = tf.keras.layers.Dense(1,
... kernel_initializer=tf.constant_initializer(1.))
>>> a_out = layer_a(tf.convert_to_tensor([[1., 2., 3.]]))
>>> layer_a.get_weights()
[array([[1.],
[1.],
[1.]], dtype=float32), array([0.], dtype=float32)]
>>> layer_b = tf.keras.layers.Dense(1,
... kernel_initializer=tf.constant_initializer(2.))
>>> b_out = layer_b(tf.convert_to_tensor([[10., 20., 30.]]))
>>> layer_b.get_weights()
[array([[2.],
[2.],
[2.]], dtype=float32), array([0.], dtype=float32)]
>>> layer_b.set_weights(layer_a.get_weights())
>>> layer_b.get_weights()
[array([[1.],
[1.],
[1.]], dtype=float32), array([0.], dtype=float32)]
傳回
權重值,以 NumPy 陣列的列表表示。
set_weights
方法Layer.set_weights(weights)
從 NumPy 陣列設定層的權重。
層的權重代表層的狀態。此函式會從 numpy 陣列設定權重值。權重值應該按照它們由層建立的順序傳遞。請注意,在呼叫此函式之前,必須先透過呼叫層來實例化層的權重。
例如,Dense
層會傳回兩個值的列表:核心矩陣和偏差向量。這些可用於設定另一個 Dense
層的權重。
>>> layer_a = tf.keras.layers.Dense(1,
... kernel_initializer=tf.constant_initializer(1.))
>>> a_out = layer_a(tf.convert_to_tensor([[1., 2., 3.]]))
>>> layer_a.get_weights()
[array([[1.],
[1.],
[1.]], dtype=float32), array([0.], dtype=float32)]
>>> layer_b = tf.keras.layers.Dense(1,
... kernel_initializer=tf.constant_initializer(2.))
>>> b_out = layer_b(tf.convert_to_tensor([[10., 20., 30.]]))
>>> layer_b.get_weights()
[array([[2.],
[2.],
[2.]], dtype=float32), array([0.], dtype=float32)]
>>> layer_b.set_weights(layer_a.get_weights())
>>> layer_b.get_weights()
[array([[1.],
[1.],
[1.]], dtype=float32), array([0.], dtype=float32)]
參數
get_weights
的輸出匹配)。引發
get_config
方法Model.get_config()
傳回 Model
的組態。
組態是一個 Python 字典(可序列化),其中包含物件的配置,在此情況下為 Model
。這允許稍後從此配置重新實例化 Model
(無需其訓練權重)。
請注意,get_config()
不保證每次呼叫都會傳回字典的全新副本。呼叫者如果想要修改字典,應複製傳回的字典。
建議子類別化的 Model
開發人員覆寫此方法,並繼續從 super(MyModel, self).get_config()
更新字典,以提供此 Model
的正確配置。如果初始參數為基本類型,則預設組態將傳回初始參數的組態字典。在子類別化模型需要自訂 get_config()
實作的情況下,會引發 NotImplementedError
。
傳回
包含此 Model
配置的 Python 字典。
add_loss
方法Layer.add_loss(losses, **kwargs)
新增損失張量,可能依賴於層輸入。
某些損失(例如,活動正規化損失)可能依賴於呼叫層時傳入的輸入。因此,當在不同輸入 a
和 b
上重複使用同一層時,layer.losses
中的某些條目可能依賴於 a
,而某些則依賴於 b
。此方法會自動追蹤依賴關係。
此方法可用於子類別化的層或模型的 call
函式內,在此情況下,losses
應為張量或張量列表。
範例
class MyLayer(tf.keras.layers.Layer):
def call(self, inputs):
self.add_loss(tf.abs(tf.reduce_mean(inputs)))
return inputs
相同的程式碼適用於分散式訓練:add_loss()
的輸入被視為正規化損失,並由訓練迴圈(內建 Model.fit()
和相容的自訂訓練迴圈)在副本之間進行平均。
add_loss
方法也可以在建構期間直接在 Functional Model 上呼叫。在這種情況下,傳遞給此模型的任何損失張量都必須是符號式的,並且能夠追溯到模型的 Input
。這些損失會成為模型拓撲的一部分,並在 get_config
中追蹤。
範例
inputs = tf.keras.Input(shape=(10,))
x = tf.keras.layers.Dense(10)(inputs)
outputs = tf.keras.layers.Dense(1)(x)
model = tf.keras.Model(inputs, outputs)
# Activity regularization.
model.add_loss(tf.abs(tf.reduce_mean(x)))
如果您的損失不是這種情況(例如,您的損失引用模型其中一層的 Variable
),您可以將您的損失包裝在一個零引數 lambda 中。這些損失不會被追蹤為模型拓撲的一部分,因為它們無法序列化。
範例
inputs = tf.keras.Input(shape=(10,))
d = tf.keras.layers.Dense(10)
x = d(inputs)
outputs = tf.keras.layers.Dense(1)(x)
model = tf.keras.Model(inputs, outputs)
# Weight regularization.
model.add_loss(lambda: tf.reduce_mean(d.kernel))
參數
losses
屬性tf_keras.layers.Layer.losses
使用 add_loss()
API 新增的損失列表。
變數正規化張量在存取此屬性時建立,因此是 eager 安全的:在 tf.GradientTape
下存取 losses
將會將梯度傳播回對應的變數。
範例
>>> class MyLayer(tf.keras.layers.Layer):
... def call(self, inputs):
... self.add_loss(tf.abs(tf.reduce_mean(inputs)))
... return inputs
>>> l = MyLayer()
>>> l(np.ones((10, 1)))
>>> l.losses
[1.0]
>>> inputs = tf.keras.Input(shape=(10,))
>>> x = tf.keras.layers.Dense(10)(inputs)
>>> outputs = tf.keras.layers.Dense(1)(x)
>>> model = tf.keras.Model(inputs, outputs)
>>> # Activity regularization.
>>> len(model.losses)
0
>>> model.add_loss(tf.abs(tf.reduce_mean(x)))
>>> len(model.losses)
1
>>> inputs = tf.keras.Input(shape=(10,))
>>> d = tf.keras.layers.Dense(10, kernel_initializer='ones')
>>> x = d(inputs)
>>> outputs = tf.keras.layers.Dense(1)(x)
>>> model = tf.keras.Model(inputs, outputs)
>>> # Weight regularization.
>>> model.add_loss(lambda: tf.reduce_mean(d.kernel))
>>> model.losses
[<tf.Tensor: shape=(), dtype=float32, numpy=1.0>]
傳回
張量的列表。