本文主要是介绍Keras深度学习框架基础第四讲:层接口(layers API)“层权重约束”,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1、层权重约束概述
1.1 层权重约束的定义
Keras层权重约束的定义主要涉及到在训练神经网络模型时,对层的权重参数施加一定的限制或约束,以提高模型的泛化能力和稳定性。以下是关于Keras层权重约束的详细定义:
-
约束的目的:
-
防止过拟合:通过限制权重的大小或范围,可以减少模型对训练数据的过度依赖,从而提高模型在未见数据上的性能。
-
提高模型稳定性:约束可以确保权重参数在合理的范围内变化,避免模型因权重过大或过小而导致的不稳定行为。
-
约束的类型:
-
Keras的
keras.constraints
模块提供了多种类型的约束,包括但不限于:MaxNorm
:强制权重向量的范数(通常是L2范数)小于或等于某个指定的最大值。例如,keras.constraints.MaxNorm(max_value=2.0)
将确保权重向量的L2范数不超过2.0。NonNeg
:强制权重为非负数。这在某些应用场景中可能是必要的,例如当权重表示某种概率或比例时。UnitNorm
:强制权重向量的范数等于1.0。这可以确保权重向量在相同的尺度上进行比较。MinMaxNorm
:强制权重在一个指定的最小值和最大值之间。这可以进一步细化对权重范围的控制。
1.2 约束的使用
来自keras.constraints
模块的类允许在训练期间对模型参数设置约束(例如非负性)。这些约束是应用于目标变量的每变量投影函数,在每次梯度更新后(使用fit()
方法时)执行。
具体的API将取决于层,但Dense
、Conv1D
、Conv2D
和Conv3D
层具有统一的API。
这些层提供了两个关键字参数:
kernel_constraint
:用于主要权重矩阵的约束bias_constraint
:用于偏置的约束
from keras.constraints import max_norm
model.add(Dense(64, kernel_constraint=max_norm(2.)))
2、层权重约束的用法
2.1 Constraint类
keras.constraints.Constraint()
权重约束的基类
一个Constraint实例就像一个无状态的函数。用户如果继承这个类,应该重写__call__()方法。这个方法接收一个单一的权重参数,并返回这个参数的一个投影版本(例如,标准化或裁剪后的版本)。约束可以通过kernel_constraint或bias_constraint参数与各种Keras层一起使用。
>>> class NonNegative(keras.constraints.Constraint):
...
... def __call__(self, w):
... return w * ops.cast(ops.greater_equal(w, 0.), dtype=w.dtype)
>>> weight = ops.convert_to_tensor((-1.0, 1.0))
>>> NonNegative()(weight)
[0., 1.]
在层里面使用的方法
>>> keras.layers.Dense(4, kernel_constraint=NonNegative())
2.2 MaxNorm类
keras.constraints.MaxNorm(max_value=2, axis=0)
MaxNorm权重约束
该约束将每个隐藏单元连接的权重范数限制为小于或等于一个指定的值。
也可以通过快捷函数keras.constraints.max_norm
来使用。
参数
max_value
: 传入权重的最大范数值。axis
: 整数,计算权重范数的轴。例如,在一个Dense层中,权重矩阵的形状是(input_dim, output_dim),设置axis
为0可以约束每个长度为(input_dim,)的权重向量。在一个Conv2D
层中,如果data_format="channels_last"
,权重张量的形状是(rows, cols, input_depth, output_depth),设置axis
为[0, 1, 2]可以约束每个大小为(rows, cols, input_depth)的滤波器张量的权重。
MaxNorm约束是一种常用的权重约束方法,用于防止神经网络中的权重过大。过大的权重可能导致模型对训练数据的过拟合,而适当的权重约束可以提高模型的泛化能力。在Keras中,你可以通过MaxNorm
约束类或keras.constraints.max_norm
快捷函数来应用这种约束。通过设置max_value
参数,你可以指定权重的最大范数值,而axis
参数则决定了在哪个维度上计算权重范数。
2.3 NonNeg类
keras.constraints.NonNeg()
约束权重为非负
2.4 UnitNorm类
keras.constraints.UnitNorm(axis=0)
UnitNorm权重约束
将每个隐藏单元连接的权重约束为单位范数。
参数
axis
: 整数,沿着该轴计算权重范数。例如,在一个Dense层中,权重矩阵的形状是(input_dim, output_dim),设置axis
为0可以约束每个长度为(input_dim,)的权重向量。在一个Conv2D
层中,如果data_format="channels_last"
,权重张量的形状是(rows, cols, input_depth, output_depth),设置axis
为[0, 1, 2]可以约束每个大小为(rows, cols, input_depth)的滤波器张量的权重。
2.5 创建自定义权重约束
权重约束可以是任何可调用对象,它接收一个张量并返回一个具有相同形状和数据类型的张量。通常,您会作为keras.constraints.Constraint的子类来实现自己的约束。
from keras import opsclass CenterAround(keras.constraints.Constraint):"""Constrains weight tensors to be centered around `ref_value`."""def __init__(self, ref_value):self.ref_value = ref_valuedef __call__(self, w):mean = ops.mean(w)return w - mean + self.ref_valuedef get_config(self):return {'ref_value': self.ref_value}
可选地,程序员还可以实现get_config
方法和类方法from_config
,以便支持序列化——就像任何Keras对象一样。请注意,在上面的例子中,我们不需要实现from_config
,因为类的构造函数参数与get_config
返回的配置字典中的键是相同的。在这种情况下,默认的from_config
方法工作得很好。
在创建自定义Keras层、约束、优化器等对象时,为了使这些对象可以被保存(例如,保存到HDF5文件)并在之后重新加载,您需要支持序列化。序列化通常涉及两个主要步骤:
-
get_config:这是一个实例方法,用于获取对象的配置字典。这个字典应该包含足够的信息来重建对象的相同实例。在自定义对象上调用
get_config
时,它应该返回一个字典,该字典映射了对象的属性到它们的值。 -
from_config:这是一个类方法,用于从配置字典中重建对象。它应该接受一个配置字典,并返回该类的一个新实例,该实例的配置与原始对象相同。
不过,在上面的CenteredConstraint
示例中,由于构造函数参数(在本例中为center_value
)与get_config
返回的字典中的键相同,因此默认的from_config
实现(由Keras基类提供)已经足够。这是因为默认的from_config
方法会简单地使用配置字典中的键作为关键字参数来调用构造函数。所以,在这种情况下,我们不需要自己实现from_config
。
如果自定义对象有更复杂的构造函数参数或需要额外的逻辑来从配置中恢复状态,那么将需要覆盖from_config
方法以提供正确的实现。
3、源代码
from keras.src import backend
from keras.src import ops
from keras.src.api_export import keras_export@keras_export("keras.constraints.Constraint")
class Constraint:"""Base class for weight constraints.A `Constraint` instance works like a stateless function.Users who subclass thisclass should override the `__call__()` method, which takes a singleweight parameter and return a projected version of that parameter(e.g. normalized or clipped). Constraints can be used with various Keraslayers via the `kernel_constraint` or `bias_constraint` arguments.Here's a simple example of a non-negative weight constraint:>>> class NonNegative(keras.constraints.Constraint):...... def __call__(self, w):... return w * ops.cast(ops.greater_equal(w, 0.), dtype=w.dtype)>>> weight = ops.convert_to_tensor((-1.0, 1.0))>>> NonNegative()(weight)[0., 1.]Usage in a layer:>>> keras.layers.Dense(4, kernel_constraint=NonNegative())"""def __call__(self, w):"""Applies the constraint to the input weight variable.By default, the inputs weight variable is not modified.Users should override this method to implement their own projectionfunction.Args:w: Input weight variable.Returns:Projected variable (by default, returns unmodified inputs)."""return wdef get_config(self):"""Returns a Python dict of the object config.A constraint config is a Python dictionary (JSON-serializable) that canbe used to reinstantiate the same object.Returns:Python dict containing the configuration of the constraint object."""return {}@classmethoddef from_config(cls, config):"""Instantiates a weight constraint from a configuration dictionary.Example:```pythonconstraint = UnitNorm()config = constraint.get_config()constraint = UnitNorm.from_config(config)```Args:config: A Python dictionary, the output of `get_config()`.Returns:A `keras.constraints.Constraint` instance."""return cls(**config)@keras_export(["keras.constraints.MaxNorm", "keras.constraints.max_norm"])
class MaxNorm(Constraint):"""MaxNorm weight constraint.Constrains the weights incident to each hidden unitto have a norm less than or equal to a desired value.Also available via the shortcut function `keras.constraints.max_norm`.Args:max_value: the maximum norm value for the incoming weights.axis: integer, axis along which to calculate weight norms.For instance, in a `Dense` layer the weight matrixhas shape `(input_dim, output_dim)`,set `axis` to `0` to constrain each weight vectorof length `(input_dim,)`.In a `Conv2D` layer with `data_format="channels_last"`,the weight tensor has shape`(rows, cols, input_depth, output_depth)`,set `axis` to `[0, 1, 2]`to constrain the weights of each filter tensor of size`(rows, cols, input_depth)`."""def __init__(self, max_value=2, axis=0):self.max_value = max_valueself.axis = axisdef __call__(self, w):w = backend.convert_to_tensor(w)norms = ops.sqrt(ops.sum(ops.square(w), axis=self.axis, keepdims=True))desired = ops.clip(norms, 0, self.max_value)return w * (desired / (backend.epsilon() + norms))def get_config(self):return {"max_value": self.max_value, "axis": self.axis}@keras_export(["keras.constraints.NonNeg", "keras.constraints.non_neg"])
class NonNeg(Constraint):"""Constrains the weights to be non-negative."""def __call__(self, w):w = backend.convert_to_tensor(w)return w * ops.cast(ops.greater_equal(w, 0.0), dtype=w.dtype)@keras_export(["keras.constraints.UnitNorm", "keras.constraints.unit_norm"])
class UnitNorm(Constraint):"""Constrains the weights incident to each hidden unit to have unit norm.Args:axis: integer, axis along which to calculate weight norms.For instance, in a `Dense` layer the weight matrixhas shape `(input_dim, output_dim)`,set `axis` to `0` to constrain each weight vectorof length `(input_dim,)`.In a `Conv2D` layer with `data_format="channels_last"`,the weight tensor has shape`(rows, cols, input_depth, output_depth)`,set `axis` to `[0, 1, 2]`to constrain the weights of each filter tensor of size`(rows, cols, input_depth)`."""def __init__(self, axis=0):self.axis = axisdef __call__(self, w):w = backend.convert_to_tensor(w)return w / (backend.epsilon()+ ops.sqrt(ops.sum(ops.square(w), axis=self.axis, keepdims=True)))def get_config(self):return {"axis": self.axis}@keras_export(["keras.constraints.MinMaxNorm", "keras.constraints.min_max_norm"]
)
class MinMaxNorm(Constraint):"""MinMaxNorm weight constraint.Constrains the weights incident to each hidden unitto have the norm between a lower bound and an upper bound.Args:min_value: the minimum norm for the incoming weights.max_value: the maximum norm for the incoming weights.rate: rate for enforcing the constraint: weights will berescaled to yield`(1 - rate) * norm + rate * norm.clip(min_value, max_value)`.Effectively, this means that rate=1.0 stands for strictenforcement of the constraint, while rate<1.0 means thatweights will be rescaled at each step to slowly movetowards a value inside the desired interval.axis: integer, axis along which to calculate weight norms.For instance, in a `Dense` layer the weight matrixhas shape `(input_dim, output_dim)`,set `axis` to `0` to constrain each weight vectorof length `(input_dim,)`.In a `Conv2D` layer with `data_format="channels_last"`,the weight tensor has shape`(rows, cols, input_depth, output_depth)`,set `axis` to `[0, 1, 2]`to constrain the weights of each filter tensor of size`(rows, cols, input_depth)`."""def __init__(self, min_value=0.0, max_value=1.0, rate=1.0, axis=0):self.min_value = min_valueself.max_value = max_valueself.rate = rateself.axis = axisdef __call__(self, w):w = backend.convert_to_tensor(w)norms = ops.sqrt(ops.sum(ops.square(w), axis=self.axis, keepdims=True))desired = (self.rate * ops.clip(norms, self.min_value, self.max_value)+ (1 - self.rate) * norms)return w * (desired / (backend.epsilon() + norms))def get_config(self):return {"min_value": self.min_value,"max_value": self.max_value,"rate": self.rate,"axis": self.axis,}
4、总结
今天讨论的层权重约束在Keras框架中扮演着重要的角色,它们用于限制和优化神经网络层中的权重值,从而帮助改善模型的训练效果。
权重约束的概念
权重约束是一种机制,用于在训练神经网络时限制层中的权重值。这些约束可以确保权重保持在一个合理的范围内,避免权重过大或过小,从而有助于模型的稳定性和泛化能力。
内置权重约束
Keras提供了几种内置的权重约束,如MaxNorm
、NonNeg
、UnitNorm
等。这些约束可以方便地应用于神经网络的各个层,通过限制权重的最大值、确保权重非负或强制权重具有单位范数等方式来影响模型的训练过程。
自定义权重约束
除了内置的约束外,用户还可以根据需要创建自定义的权重约束。自定义约束需要继承keras.constraints.Constraint
类,并实现__call__
和get_config
方法。__call__
方法用于定义约束的逻辑,即如何根据输入的权重张量计算约束后的权重。get_config
方法用于返回约束的配置字典,以便支持序列化和重新加载。
应用权重约束
在Keras中,可以将权重约束应用于神经网络的各个层。这通常通过在层的构造函数中设置kernel_constraint
或bias_constraint
参数来完成。这些参数接受一个约束对象作为输入,并将该约束应用于层的权重或偏置项。
层权重约束的作用
权重约束在神经网络训练中起着重要的作用。它们可以帮助防止过拟合,通过限制权重的范围来防止模型过于复杂。此外,权重约束还可以提高模型的稳定性和泛化能力,使模型在未见过的数据上表现更好。
今天讨论了Keras中的层权重约束,包括内置约束和自定义约束。权重约束在神经网络训练中扮演着重要的角色,它们可以限制权重的范围,帮助改善模型的稳定性和泛化能力。通过合理地应用权重约束,我们可以构建更有效、更健壮的神经网络模型。
这篇关于Keras深度学习框架基础第四讲:层接口(layers API)“层权重约束”的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!