Layer 类tf_keras.layers.Layer(trainable=True, name=None, dtype=None, dynamic=False, **kwargs)
这是所有层继承自的类。
层是一个可调用对象,它接受一个或多个张量作为输入,并输出一个或多个张量。它涉及计算,在call()方法中定义,以及状态(权重变量)。状态可以在各种地方创建,方便子类实现者
__init__()中;build()方法中,该方法在首次调用层时被调用,并提供输入的形状,这些形状可能在初始化时未知;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()中方便创建的状态;有关详细信息,请参阅其文档字符串。您可以在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且synchronization被设置为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的正确配置。默认配置将为init参数返回配置字典,如果它们是基本类型。当需要自定义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>]
返回
张量列表。