热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【调参02】如何使用L1和L2正则化降低过拟合风险

本文介绍了为什么要使用正则化以及如何在Keras中使用正则化来降低模型过拟合风险。文章目录1.权重过大导致的问题2.正则化3.正则化使用技巧3.1在所有模型上使用3.2标准化输入数

本文介绍了为什么要使用正则化以及如何在Keras中使用正则化来降低模型过拟合风险。



文章目录

  • 1. 权重过大导致的问题
  • 2. 正则化
  • 3. 正则化使用技巧
    • 3.1 在所有模型上使用
    • 3.2 标准化输入数据 🐳
    • 3.3 训练深层网络时使用
    • 3.4 结合使用 L1和L2正则化
    • 3.5 在训练好的网络上使用正则化 🐬
    • 3.6 其它正则化方法 🐋
  • 4. Keras 实现
    • 4.1 Keras API
    • 4.2 L1 正则化
    • 4.3 L2 正则化
    • 4.3 L1L2 正则化
    • 4.4 自定义正则化函数 🐟
  • 5. 网格搜索寻找最佳的正则化参数



代码环境:

python -3.7.6
tensorflow -2.1.0


神经网络学习一组权重,以最佳地将输入映射到输出。具有较大网络权重的网络可能表示网络不稳定,在该网络中,输入的较小变化可能导致输出的较大变化。这可能表明网络过度适合训练数据集,并且在对新数据进行预测时可能表现不佳。

该问题的解决方案是更新学习算法,使网络保持较小的权重,即权重正则化(weight regularization),该方法可以减少训练数据集的过拟合风险并提高模型泛化能力。



1. 权重过大导致的问题

训练神经网络一般使用随机梯度下降(SGD)算法,“训练”即学习权重向量和偏置的过程。

训练周期越长,模型越容易过度适应训练集的特征分布,从而导致过拟合。为了从训练集中提取特征,权重会增大,较大的权重会导致网络不稳定,即使输入数据发生较小的波动或引入随机噪声,也会导致输出有很大差异。也就就是说,模型在训练集上表现很好,但是在新数据集上表现很差,即泛化能力很差。

通常认为这样的模型具有较大的方差和较小的偏差。即模型对训练数据集中的某些样本敏感,比如收集数据过程中引入的噪声。

权重较大的模型比权重较小的模型更为复杂,虽然拟合能力很强,但很容易导致过拟合。根据奥卡剃刀定律:“如无必要,勿增实体”,在应用过程中,一般从较简单的模型开始建模。

另一个可能的问题是,可能有许多输入变量,每一个都与输出变量有不同程度的相关性。有时可以使用方法来帮助选择输入变量,但通常变量之间的相互关系并不明显。

对于不太相关或不相关的模型输入,使用较小的权重甚至零权重可以使得模型专注于学习。这也可以减少模型容量,提高泛化能力,避免陷入局部最优。



2. 正则化

正则化又称为惩罚,即通过选择解决学习问题的最小向量来抑制权重向量的任何不相关分量。常用的正则化有L1正则化,又称为稀疏正则化;L2正则化,又称为权重衰减正则化。L1和L2分别表示L1范数和L2范数。其计算公式如下:

l1l_1l1 范数表示向量的各个元素的绝对值之和。其公式为:
在这里插入图片描述
l2l_2l2 范数表示向量的各个元素的平方和再开平方。
在这里插入图片描述
其中,vvv 表示一个 NNN 维向量。范数(Norm) 是一个表示向量“长度”的函数,为向量空间内的所有向量赋予非零的正长度或大小。

加入正则化后,最优化目标函数变为:
在这里插入图片描述
其中 L(⋅)L(·)L() 为损失函数,NNN 为训练样本的数量,f(⋅)f(·)f() 为待学习的神经网络,θθθ 为其参数,lpl_plp 表示范数,通常为 l1l_1l1 范数和 l2l_2l2 范数,λ表示正则化系数。


L1 正则化鼓励模型将权重设置为0或1,从而使模型稀疏。L2 正则化又称为 岭回归(ridge regression) 或 Tikhonov 正则化。L2 是更常用的正则化方法。

通过之前的机器学习基石课程中知道,L2正则化中包含一个拉格朗日乘子系数 α\alphaα,称为惩罚项或正则化项,控制对模型权重惩罚的力度,其值介于0和1之间。如果 α\alphaα 选择的大小合适,权重衰减会抑制静态噪声对目标的某些影响。越大的惩罚项表示对模型的拟合能力限制越大。

权重的向量范数通常是逐层计算的,而不是整个网络中的。尽管默认情况下通常在每个层上使用相同的 α\alphaα 值,但这在选择所使用的正则化类型(例如,输入层使用L1,其它层使用L2)的类型方面提供了更大的灵活性,并且在 α\alphaα 值方面具有灵活性。

在神经网络的情况下,有时需要为网络的每一层使用系数不同的惩罚项。因为搜索多个合适的超参数很耗费计算资源,所以在所有层上使用相同的权重衰减只是为了减小搜索空间的大小,但仍然是合理的。



3. 正则化使用技巧

3.1 在所有模型上使用

权重正则化是一种通用方法。它可以与大多数的神经网络模型一起使用,尤其是多层感知器,卷积神经网络和长短期记忆递归神经网络等最常见的网络类型。对于LSTM,可能需要对输入层和LSTM层使用不同的惩罚项。



3.2 标准化输入数据 🐳

当输入变量具有不同的比例时,网络权重的比例将相应地变化。这在使用权重正则化时引入了一个问题,必须添加权重的绝对值或平方值以用于惩罚。可以通过标准化或标准化输入变量来解决此问题。

常用的做法是将原始数据减去均值,再除以标准差。



3.3 训练深层网络时使用

对于较大的网络(更多的层或更多的节点),更容易导致过拟合。因此使用正则化来降低过拟合风险。



3.4 结合使用 L1和L2正则化

因为这两个正则化方法各有其特点,所以结合使用不失为一种提高模型性能的方法。



3.5 在训练好的网络上使用正则化 🐬

例如,可以先不使用正则化训练模型,然后再使用正则化更新模型,以减小已经表现良好的模型的权重大小。



3.6 其它正则化方法 🐋

权重惩罚的另一种可能类型是:
e∣x∣–1e^{|x|}–1ex1
它虽然不像L1那样强烈,却鼓励零权重,同时也像L2一样强力惩罚较大的权重(但更强)。
在这里插入图片描述



4. Keras 实现

4.1 Keras API

tensorflow.keras 提供了三个正则化关键字参数,分别是:

  • kernel_regularizer:正则化器在层的内核上添加惩罚项;
  • bias_regularizer:正则化器对层的偏差添加惩罚项;
  • activity_regularizer:正则化器对层的输出添加惩罚项。

简单示例:

from tensorflow.keras import layers
from tensorflow.keras import regularizerslayer = layers.Dense(units=64,kernel_regularizer=regularizers.l1_l2(l1=1e-5, l2=1e-4),bias_regularizer=regularizers.l2(1e-4),activity_regularizer=regularizers.l2(1e-5)
)



4.2 L1 正则化

tf.keras.regularizers.l1(l=0.01)

The L1 regularization penalty is computed as: loss = l * reduce_sum(abs(x))

参数说明:

  • l: Float; L1 regularization factor.



4.3 L2 正则化

tf.keras.regularizers.l2(l=0.01)

The L2 regularization penalty is computed as: loss = l * reduce_sum(square(x))

参数说明:

  • l: Float; L2 regularization factor.



4.3 L1L2 正则化

tf.keras.regularizers.l1_l2(l1=0.01, l2=0.01)



4.4 自定义正则化函数 🐟

1.简单方法

def my_regularizer(x):return 1e-3 * tf.reduce_sum(tf.square(x))


2.Regularizer 子类
如果需要通过各种参数(例如l1和中的l2参数l1_l2)配置正则化,则应实现为tf.keras.regularizers.Regularizer 的子类。

class MyRegularizer(regularizers.Regularizer):def __init__(self, strength):self.strength = strengthdef __call__(self, x):return self.strength * tf.reduce_sum(tf.square(x))



5. 网格搜索寻找最佳的正则化参数

掉头发调参的时候,如果确定正则化可以提高模型性能,那么就需要通过网格搜索来确定最佳的正则化参数。

一般的做法的是,首先在0.0到0.1之间的各个数量级上进行网格搜索,然后在找到某个级别后,再对该级别进行网格搜索。

from sklearn.datasets import make_moons
from tensorflow.keras.layers import Dense
from tensorflow.keras.models import Sequential
from tensorflow.keras.regularizers import l2
import matplotlib.pyplot as plt
plt.rcParams['figure.dpi'] = 150# 生成虚拟分类样本
X, y = make_moons(n_samples=100, noise=0.2, random_state=1)# 划分训练集和测试集
n_train = 30
trainX, testX = X[:n_train, :], X[n_train:, :]
trainy, testy = y[:n_train], y[n_train:]# 网格搜索参数配置
values = [1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6]all_train, all_test = list(), list()for param in values:# 定义模型model = Sequential()model.add(Dense(500, input_dim=2, activation='relu', kernel_regularizer=l2(param)))model.add(Dense(1, activation='sigmoid'))model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])# 训练模型model.fit(trainX, trainy, epochs=4000, verbose=0)# 评估模型_, train_acc = model.evaluate(trainX, trainy, verbose=0)_, test_acc = model.evaluate(testX, testy, verbose=0)print('Param: %f, Train: %.3f, Test: %.3f' % (param, train_acc, test_acc))all_train.append(train_acc)all_test.append(test_acc)plt.semilogx(values, all_train, label='train', marker='o') # 转换为10的幂显示
plt.semilogx(values, all_test, label='test', marker='o')
plt.legend()
plt.show()

输出:

Param: 0.100000, Train: 0.967, Test: 0.829
Param: 0.010000, Train: 1.000, Test: 0.943
Param: 0.001000, Train: 1.000, Test: 0.943
Param: 0.000100, Train: 1.000, Test: 0.929
Param: 0.000010, Train: 1.000, Test: 0.914
Param: 0.000001, Train: 1.000, Test: 0.914

在这里插入图片描述
可以看出,0.1的正则化参数模型表现比较差;0.01是比较好的正则化参数。



参考:
https://machinelearningmastery.com/weight-regularization-to-reduce-overfitting-of-deep-learning-models/
https://machinelearningmastery.com/how-to-reduce-overfitting-in-deep-learning-with-weight-regularization/
https://keras.io/getting_started/
https://keras.io/api/layers/regularizers/


推荐阅读
  • Keras 实战:自编码器入门指南
    本文介绍了使用 Keras 框架实现自编码器的基本方法。自编码器是一种用于无监督学习的神经网络模型,主要功能包括数据降维、特征提取等。通过实际案例,我们将展示如何使用全连接层和卷积层来构建自编码器,并讨论不同维度对重建效果的影响。 ... [详细]
  • 本文详细介绍了使用NumPy和TensorFlow实现的逻辑回归算法。通过具体代码示例,解释了数据加载、模型训练及分类预测的过程。 ... [详细]
  • 社交网络中的级联行为 ... [详细]
  • 本文介绍如何从字符串中移除大写、小写、特殊、数字和非数字字符,并提供了多种编程语言的实现示例。 ... [详细]
  • 使用Python爬虫技术从网页中提取图片链接的方法与示例
    本篇文章将详细介绍如何通过Python编程语言来实现从指定网页上抓取图片链接的功能,并提供了一个实用的代码示例。 ... [详细]
  • 本文介绍了如何利用Python进行批量图片尺寸调整,包括放大和等比例缩放。文中提供了详细的代码示例,并解释了每个步骤的具体实现方法。 ... [详细]
  • 本文探讨了为何相同的HTTP请求在两台不同操作系统(Windows与Ubuntu)的机器上会分别返回200 OK和429 Too Many Requests的状态码。我们将分析代码、环境差异及可能的影响因素。 ... [详细]
  • Python + Pytest 接口自动化测试中 Token 关联登录的实现方法
    本文将深入探讨 Python 和 Pytest 在接口自动化测试中如何实现 Token 关联登录,内容详尽、逻辑清晰,旨在帮助读者掌握这一关键技能。 ... [详细]
  • 本文将详细介绍Nose这一非标准库的Python测试框架,它虽然不是Python官方发行版的一部分,但与unittest框架紧密相关,旨在通过简化测试流程来提升开发效率。 ... [详细]
  • Celery在使用前必须实例化,称为application或app。app是线程安全的,具有不同配置、组件、task的多个Celery应用可以在同一个进 ... [详细]
  • 在Ubuntu 16.04中使用Anaconda安装TensorFlow
    本文详细介绍了如何在Ubuntu 16.04系统上通过Anaconda环境管理工具安装TensorFlow。首先,需要下载并安装Anaconda,然后配置环境变量以确保系统能够识别Anaconda命令。接着,创建一个特定的Python环境用于安装TensorFlow,并通过指定的镜像源加速安装过程。最后,通过一个简单的线性回归示例验证TensorFlow的安装是否成功。 ... [详细]
  • 本文详细介绍如何通过Anaconda 3.5.01快速安装TensorFlow,包括环境配置和具体步骤。 ... [详细]
  • 本文探讨了图像标签的多种分类场景及其在以图搜图技术中的应用,涵盖了从基础理论到实际项目实施的全面解析。 ... [详细]
  • 本文详细介绍了 TensorFlow 的入门实践,特别是使用 MNIST 数据集进行数字识别的项目。文章首先解析了项目文件结构,并解释了各部分的作用,随后逐步讲解了如何通过 TensorFlow 实现基本的神经网络模型。 ... [详细]
  • 本文介绍了一个使用Keras框架构建的卷积神经网络(CNN)实例,主要利用了Keras提供的MNIST数据集以及相关的层,如Dense、Dropout、Activation等,构建了一个具有两层卷积和两层全连接层的CNN模型。 ... [详细]
author-avatar
大小大空间_566
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有