1、绪论
在Keras中,层权重正则化器是用于防止模型过拟合的一种技术,它通过向模型的损失函数中添加一个与权重相关的惩罚项来实现。
1.1 Keras正则化器概述
-
正则化器的概念:
- 正则化器允许在优化过程中对层的参数或层的激活情况进行惩罚。
- 网络优化的损失函数也包括这些惩罚项,从而引导模型在训练过程中找到更加泛化的权重参数。
-
正则化器的使用:
- Keras提供了多种内置的正则化器,如L1正则化、L2正则化和L1-L2正则化。
- 这些正则化器可以通过为层的
kernel_regularizer
、bias_regularizer
和activity_regularizer
参数指定相应的正则化实例来使用。
-
可用的正则化:
keras.regularizers.l1(l1)
:L1正则化,对权重参数的绝对值进行惩罚,使得权重参数趋近于0。其中l1
是L1正则化的系数。keras.regularizers.l2(l2)
:L2正则化,对权重参数的平方进行惩罚,使得权重参数尽可能小。其中l2
是L2正则化的系数。keras.regularizers.l1_l2(l1=l1, l2=l2)
:L1-L2正则化,同时使用L1和L2正则化。其中l1
和l2
分别是L1和L2正则化的系数。
-
定义新的正则化器:
- 如果需要定义自定义的正则化器,可以创建一个继承自
keras.regularizers.Regularizer
的类,并实现__call__
方法。这个方法应该接收一个权重矩阵作为输入,并返回一个与正则化惩罚相关的标量张量。
- 如果需要定义自定义的正则化器,可以创建一个继承自
-
API细节:
- 对于Dense、Conv1D、Conv2D和Conv3D等层,正则化器的使用方式是统一的。这意味着你可以在创建这些层时,通过指定
kernel_regularizer
、bias_regularizer
和activity_regularizer
参数来应用正则化。
- 对于Dense、Conv1D、Conv2D和Conv3D等层,正则化器的使用方式是统一的。这意味着你可以在创建这些层时,通过指定
-
示例:
from tensorflow.keras.layers import Dense from tensorflow.keras.regularizers import l2# 创建一个具有L2正则化的Dense层 dense_layer = Dense(64, kernel_regularizer=l2(0.01))
在这个示例中,我们创建了一个具有64个神经元的Dense层,并为该层的权重应用了L2正则化,其中L2正则化的系数为0.01。
-
正则化系数的选择:
- 正则化系数的选择通常需要根据具体的任务和数据集进行调整。较大的正则化系数会导致更强烈的惩罚,而较小的正则化系数则惩罚较弱。
Keras层权重正则化器是一种强大的工具,可以帮助你构建更加泛化的神经网络模型。通过选择适当的正则化器和调整正则化系数,你可以有效地防止模型过拟合,并提高模型在未见过的数据上的性能。
1.2 正则化器的主要参数
正则化器(Regularizers)允许程序员在优化过程中对层参数或层活动应用惩罚项。这些惩罚项会被加入到网络优化的损失函数中。
正则化惩罚是基于每一层来应用的。具体的API将取决于该层,但许多层(例如Dense、Conv1D、Conv2D和Conv3D)都有统一的API。
这些层暴露了以下三个关键字参数:
kernel_regularizer:在层的核(权重)上应用惩罚项的正则化器
bias_regularizer:在层的偏置上应用惩罚项的正则化器
activity_regularizer:在层的输出上应用惩罚项的正则化器
from keras import layers
from keras import regularizerslayer = layers.Dense(units=64,kernel_regularizer=regularizers.L1L2(l1=1e-5, l2=1e-4),bias_regularizer=regularizers.L2(1e-4),activity_regularizer=regularizers.L2(1e-5)
)
当在神经网络的层上使用activity_regularizer
时,该对象返回的值会被除以输入批次的大小(batch size)。这样做的目的是为了确保权重正则化(weight regularizers)和活动正则化(activity regularizers)之间的相对权重不会因为批次大小的变化而发生变化。
在将输入传递给层之后,您可以通过调用layer.losses
来访问该层的正则化惩罚项。这是Keras框架提供的一个特性,它允许您轻松地获取与层相关的所有正则化损失。
activity_regularizer
对象返回的值会被除以输入批次的大小,以确保权重正则化和活动正则化之间的相对权重不会随着批次大小的变化而变化。
程序员可以在将输入传递给层之后,通过调用layer.losses
来访问该层的正则化惩罚项。
from keras import opslayer = layers.Dense(units=5,kernel_initializer='ones',kernel_regularizer=regularizers.L1(0.01),activity_regularizer=regularizers.L2(0.01))
tensor = ops.ones(shape=(5, 5)) * 2.0
out = layer(tensor)
# The kernel regularization term is 0.25
# The activity regularization term (after dividing by the batch size) is 5
print(ops.sum(layer.losses)) # 5.25 (= 5 + 0.25)
2、层权重正则化器详解
2.1 Regularizer类
keras.regularizers.Regularizer()
正则化器基类。
正则化器允许您在优化过程中对层参数或层活动应用惩罚项。这些惩罚项会被加入到网络优化的损失函数中。
正则化惩罚是基于每一层来应用的。具体的API将取决于该层,但许多层(例如Dense、Conv1D、Conv2D和Conv3D)具有统一的API。
这些层暴露了三个关键字参数:
kernel_regularizer:在层的核(权重)上应用惩罚项的正则化器
bias_regularizer:在层的偏置上应用惩罚项的正则化器
activity_regularizer:在层的输出上应用惩罚项的正则化器
所有层(包括自定义层)都公开了activity_regularizer
作为可设置的属性,无论它是否位于构造函数的参数中。
activity_regularizer
返回的值会被除以输入批次的大小,以确保权重正则化和活动正则化之间的相对权重不会随着批次大小的变化而变化。
程序员可以在将输入传递给层之后,通过调用layer.losses
来访问该层的正则化惩罚项。
>>> layer = Dense(
... 5, input_dim=5,
... kernel_initializer='ones',
... kernel_regularizer=L1(0.01),
... activity_regularizer=L2(0.01))
>>> tensor = ops.ones(shape=(5, 5)) * 2.0
>>> out = layer(tensor)
>>> # The kernel regularization term is 0.25
>>> # The activity regularization term (after dividing by the batch size)
>>> # is 5
>>> ops.sum(layer.losses)
5.25
使用罚函数
L1(0.3) # L1 Regularization Penalty
L2(0.1) # L2 Regularization Penalty
L1L2(l1=0.01, l2=0.01) # L1 + L2 penalties
直接调用一个正则化器
通过将正则化器直接作为一个单参数函数来调用,可以在一个张量上计算正则化损失。
>>> regularizer = L2(2.)
>>> tensor = ops.ones(shape=(5, 5))
>>> regularizer(tensor)
50.0
开发新的正则化器
任何接受权重矩阵作为输入并返回一个标量张量的函数都可以用作正则化器。
>>> def l1_reg(weight_matrix):
... return 0.01 * ops.sum(ops.absolute(weight_matrix))
...
>>> layer = Dense(5, input_dim=5,
... kernel_initializer='ones', kernel_regularizer=l1_reg)
>>> tensor = ops.ones(shape=(5, 5))
>>> out = layer(tensor)
>>> layer.losses
0.25
另外,程序员也可以通过扩展这个正则化器基类来以面向对象的方式编写自定义的正则化器。
>>> class L2Regularizer(Regularizer):
... def __init__(self, l2=0.):
... self.l2 = l2
...
... def __call__(self, x):
... return self.l2 * ops.sum(ops.square(x))
...
... def get_config(self):
... return {'l2': float(self.l2)}
...
>>> layer = Dense(
... 5, input_dim=5, kernel_initializer='ones',
... kernel_regularizer=L2Regularizer(l2=0.5))
>>> tensor = ops.ones(shape=(5, 5))
>>> out = layer(tensor)
>>> layer.losses
12.5
序列化和反序列化的注意事项
如果你只是进行模型的训练和执行、导出和导入SavedModels,或者保存和加载权重检查点,将正则化器注册为可序列化的选项是可选的。
但是,如果你需要将模型保存到HDF5格式、进行Keras模型克隆、使用某些可视化工具,或者将模型导出到JSON或从JSON导入,那么注册是必需的。如果你使用这些功能,你必须确保运行你模型的任何Python进程也已经定义并注册了你的自定义正则化器。
2.2 L1类
keras.regularizers.L1(l1=0.01)
应用L1正则化惩罚的正则化器。
L1正则化惩罚的计算公式是:loss = l1 * reduce_sum(abs(x))
L1可以作为字符串标识符传递给一个层:
>>> dense = Dense(3, kernel_regularizer='l1')
在这种情况下,默认值是l1=0.01。
参数
l1:浮点数,L1正则化因子。
2.3 L2类
keras.regularizers.L2(l2=0.01)
应用L2正则化惩罚的正则化器。
L2正则化惩罚的计算公式是:loss = l2 * reduce_sum(square(x))
L2可以作为字符串标识符传递给一个层:
>>> dense = Dense(3, kernel_regularizer='l2')
在这种情况下,默认值是l2=0.01。
参数:
l2:浮点数,L2正则化因子。
2.4 L1L2类
keras.regularizers.L1L2(l1=0.0, l2=0.0)
正则化器同时应用L1和L2正则化惩罚。
L1正则化惩罚的计算公式是:loss = l1 * reduce_sum(abs(x))
L2正则化惩罚的计算公式是:loss = l2 * reduce_sum(square(x))
L1L2可以作为字符串标识符传递给一个层:
>>> dense = Dense(3, kernel_regularizer='l1_l2')
在这种情况下,默认值是l1=0.01和l2=0.01。
参数
l1:浮点数,L1正则化因子。
l2:浮点数,L2正则化因子。
2.5 OrthogonalRegularizer类
keras.regularizers.OrthogonalRegularizer(factor=0.01, mode="rows")
正则化器鼓励输入向量相互正交。
它可以应用于矩阵的行(mode=“rows”)或列(mode=“columns”)。当应用于形状为(input_dim, units)的Dense层的核时,行模式(rows mode)将寻求使特征向量(即输出空间的基)相互正交。
参数
factor:浮点数。正则化因子。正则化惩罚将与factor成正比,乘以输入中L2归一化行(如果mode=“rows”)或列(如果mode=“columns”)之间的点积的平均值,但不包括每行/列与其自身的点积。默认为0.01。
mode:字符串,必须是{“rows”, “columns”}中的一个。默认为"rows"。在行模式下,正则化效果寻求使输入的各行相互正交。在列模式下,它寻求使输入的各列相互正交。
>>> regularizer = OrthogonalRegularizer(factor=0.01)
>>> layer = Dense(units=4, kernel_regularizer=regularizer)
2.6 创建自定义正则化器
2.6.1 简单的可调用对象
权重正则化器可以是任何可调用对象,它接受一个权重张量(例如Conv2D层的核)作为输入,并返回一个标量损失。例如:
def my_regularizer(x):return 1e-3 * ops.sum(ops.square(x))
2.6.2 正则化器子类
如果你需要通过各种参数来配置你的正则化器(例如l1_l2中的l1和l2参数),你应该将其实现为keras.regularizers.Regularizer的子类。
下面是一个简单的例子:
class MyRegularizer(regularizers.Regularizer):def __init__(self, strength):self.strength = strengthdef __call__(self, x):return self.strength * ops.sum(ops.square(x))
程序员还可以实现get_config
方法和类方法from_config
,以便支持序列化——就像任何其他Keras对象一样。示例如下:
class MyRegularizer(regularizers.Regularizer):def __init__(self, strength):self.strength = strengthdef __call__(self, x):return self.strength * ops.sum(ops.square(x))def get_config(self):return {'strength': self.strength}
3、总结
今天我们对Keras中的正则化器进行了讨论,涉及了预定义的正则化器(如L1、L2和L1L2)以及如何创建自定义正则化器。
3.1. 预定义的正则化器:
- L1 正则化:鼓励模型权重稀疏化,通过计算权重的绝对值之和来实现。
- L2 正则化:也被称为权重衰减或Ridge回归,它通过计算权重的平方和来实现,有助于防止过拟合。
- L1L2 正则化:同时应用L1和L2正则化,结合了两种正则化的优点。
3.2. 自定义正则化器:
- 简单的可调用对象:任何接受权重张量作为输入并返回标量损失的函数都可以作为正则化器。
- 正则化器子类:如果正则化器需要多个参数配置,你可以通过继承
keras.regularizers.Regularizer
类来实现。这允许你定义自己的__call__
方法(计算正则化损失),并可以(但不是必需的)实现get_config
和from_config
方法来支持序列化。
3.3. 序列化与反序列化:
- 当你需要将模型保存到文件(如HDF5或JSON格式)或从文件中加载时,你需要确保任何自定义的正则化器都被正确注册并可以被序列化和反序列化。这通常通过实现
get_config
和from_config
方法来完成。
3.4. 注意事项:
- 当在Keras中使用自定义正则化器时,确保所有使用该正则化器的Python进程都已定义并注册了该正则化器。
- 考虑正则化器的效果对模型训练和性能的影响,并适当调整正则化因子。
3.5. 示例:
- 我们提供了一个简单的自定义正则化器示例,它鼓励输入向量的行或列相互正交。这个正则化器可以作为
keras.regularizers.Regularizer
的子类来实现。
Keras提供了灵活的方式来定义和使用正则化器,无论是使用预定义的选项还是创建自定义的解决方案。正确地选择和应用正则化器对于防止过拟合和改善模型的泛化能力至关重要。