内容简介:权重正则化可以减轻深度神经网络模型的过拟合问题,可以提升对新数据的泛化能力。有多种正则方法可供选择,如:读完本篇文章,你将学习到:
介绍
权重正则化可以减轻深度神经网络模型的过拟合问题,可以提升对新数据的泛化能力。有多种正则方法可供选择,如: L1 , L2 正则化,每种方法在使用前需要超参数配置。在这篇文章中,你将学习在 keras 如何使用权重正则化的方法来减轻模型过拟合问题。
读完本篇文章,你将学习到:
- 如何在 keras 中使用权重正则化应用到 MLP , CNN ,或者 LSTM 神经网络任务中
- 一些常见论文在模型中使用权重正则化的方法和经验
- 通过一个案例学习如何使用权重正则化解决过拟合问题
## keras中权重正则化方法 ##
keras提供了权重正则化方法,可以在损失函数中通过添加惩罚系数来使用。 keras 提供了三种正则化方法:
- L1:绝对值权重之和
- L2:平方权重之和
- L1L2:两者累加之和
tf.keras.regularizers.l1(l=0.01) tf.keras.regularizers.l2(l=0.01) tf.keras.regularizers.l1_l2(l1=0.01,l2=0.01)
keras中,权重正则化可以应用到任意一层,不过,模型默认不使用任何权重正则化。
全连接层使用权重正则化
全连接层使用L2权重正则化:
import tensorflow as tf model=tf.keras.models.Sequential( # 权重正则化,bias正则化(应用较少) tf.keras.layers.Dense(512,activation=tf.nn.relu,kernel_regularizer=tf.keras.regularizers.l2(l=0.001),bias_regularizer=tf.keras.regularizers.l2(l=0.001)) )
卷积层使用权重正则化
同全连接层一样,卷积层也使用 kernel_regularizer 和 bias_regularizer 参数添加正则化。代码展示在卷积层中使用L2正则化。
import tensorflow as tf model=tf.keras.models.Sequential( tf.keras.layers.Conv2D(32,3,activation=tf.nn.relu,kernel_regularizer=tf.keras.regularizers.l2(l=0.001),bias_regularizer=tf.keras.regularizers.l2(l=0.001)) )
RNN网络中使用权重正则化
代码展示在LSTM网络中使用L2权重正则化
import tensorflow as tf model=tf.keras.models.Sequential( tf.keras.layers.LSTM(32,activation=tf.nn.tanh,recurrent_regularizer=tf.keras.regularizers.l2(l=0.001),kernel_regularizer=tf.keras.regularizers.l2(l=0.001),bias_regularizer=tf.keras.regularizers.l2(l=0.001)) )
权重正则化使用经验
- 最常见的权重正则化是L2正则化,数值通常是0-0.1之间,如:0.1,0.001,0.0001。
- 找到最优的系数并不容易,需要尝试不同的权重系数,找到模型表现最平稳优秀的系数
- L2正则化在CNN网络中,建议系数设置小一些,如:0.0005
- 少量的权重正则对模型很重要,可以减少模型训练误差
- LSTM网络中L2权重系数通常更小,如:10^-6
权重正则化案例学习
我们将使用标准二元分类问题来定义两个半圆观察:每个类一个半圆。每个观测值都有两个输入变量,它们具有相同的比例,类输出值为0或1.该数据集称为“月亮”数据集,因为绘制时每个类中的观测值的形状。
# 导入sklearn中的数据集 from sklearn.datasets import make_moons from matplotlib import pyplot from pandas import DataFrame # 生成2分类数据集 X, y = make_moons(n_samples=100, noise=0.2, random_state=1) print(X.shape) print(X[:6]) print(y.shape) print(y[:6]) df = DataFrame(dict(x=X[:,0], y=X[:,1], label=y)) colors = {0:'red', 1:'blue'} fig, ax = pyplot.subplots() grouped = df.groupby('label') for key, group in grouped: group.plot(ax=ax, kind='scatter', x='x', y='y', label=key, color=colors[key]) pyplot.show()
sklearn常用数据集:
数据集格式:
matplot结果显示:
如图所示,该问题是非线性问题,可以使用神经网络来解决。我们只生成了100个样本,对神经网络来说数据量很少,这很容易造成过拟合问题。我们使用正则化,添加噪声数据来处理问题。
虽然卷积神经网络(CNN)功能强大,并广泛应用于各种计算机视觉任务中,但由于参数过多而导致过度拟合[22]。神经网络的最初发展受到人脑机制的启发[18],它不像计算机那样精确。受到差异的启发,我们推断在训练过程中添加噪音可能会指示CNN学习更强大的特征表示以抵消噪音的影响,从而降低过度拟合的风险。许多正则化方法通过向训练数据添加噪声来防止过拟合。数据增强的输入图像,如随机裁剪,翻转和阻塞[9,21,30]已广泛用于提高CNNs的泛化能力。 Adversarial Training [1]被提出来通过在图像中添加基于梯度的扰动来调整网络。 DisturbLabel [26]随机地将样本的一小部分子集的标签改变为不正确的值,从而在损失层上规则化CNN。
过拟合模型
我们创建一个只有一层隐藏层的MLP模型,并让神经元数量大于样本数量,然后过长时间训练模型,以此来人为造成过拟合问题。训练模型之前,我们拆分下数据集,训练数据30%,验证数据70%,来训练模型表现。
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:]
模型隐藏层有500个神经元,激活函数使用relu,输出层使用sigmoid激活函数,输出一项类别。模型使用bind_crossentropy损失函数,adam优化器。
model = Sequential() model.add(Dense(500, input_dim=2, activation='relu')) model.add(Dense(1, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
模型迭代数据集400次,batch_size=32。
model.fit(trainX, trainy, epochs=4000, verbose=0)
在测试集上评估模型表现:
# model.evaluate返回:loss value;metrics value _, train_acc = model.evaluate(trainX, trainy, verbose=0) _, test_acc = model.evaluate(testX, testy, verbose=0) print('Train: %.3f, Test: %.3f' % (train_acc, test_acc))
模型输出结果:
我们看到训练表现远大于测试表现,这是过拟合问题的典型标志。我们将train和test训练精度过程图形化展示出来。
from sklearn.datasets import make_moons from keras.layers import Dense from keras.models import Sequential from matplotlib import pyplot 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:] # 创建模型 model = Sequential() model.add(Dense(500, input_dim=2, activation='relu')) model.add(Dense(1, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) # 返回训练,验证集的损失和准确率 history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0) pyplot.plot(history.history['acc'], label='train') pyplot.plot(history.history['val_acc'], label='test') pyplot.legend() pyplot.show()
如图所示,在某一点,train和test的准确率出现分叉口。
使用正则化的模型
我们将在隐藏层中使用权重正则化,并设置系数为0.001,以此来减轻过拟合问题。
model.add(Dense(500, input_dim=2, activation='relu', kernel_regularizer=l2(0.001)))
完整代码如下:
from sklearn.datasets import make_moons from keras.layers import Dense from keras.models import Sequential from keras.regularizers import l2 # 创建数据集 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:] # 创建模型 model = Sequential() # 设置权重正则化 model.add(Dense(500, input_dim=2, activation='relu', kernel_regularizer=l2(0.001))) 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('Train: %.3f, Test: %.3f' % (train_acc, test_acc))
乍一看,好像除了test准确率降低些,其它也没什么了。让我们画图看下train和test的训练过程。
from sklearn.datasets import make_moons from keras.layers import Dense from keras.models import Sequential from keras.regularizers import l2 from matplotlib import pyplot 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:] model = Sequential() model.add(Dense(500, input_dim=2, activation='relu', kernel_regularizer=l2(0.001))) model.add(Dense(1, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) history = model.fit(trainX, trainy, validation_data=(testX, testy), epochs=4000, verbose=0 pyplot.plot(history.history['acc'], label='train') pyplot.plot(history.history['val_acc'], label='test') pyplot.legend() pyplot.show()
如图所示,现在就很清楚了,test与train一致。
网格搜索正则化超参数
当确定权重正则化可以改善模型的时候,这时你可以尝试不同的权重系数值。首先对0.0到0.1之间的一些数量级进行网格搜索,然后再找到一个级别后进行网格搜索,这是一个很好的做法。
# 待测权重正则化值 values = [1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6] all_train, all_test = list(), list() for param in values: ... model.add(Dense(500, input_dim=2, activation='relu', kernel_regularizer=l2(param))) ... all_train.append(train_acc) all_test.append(test_acc)
我们依然可以图形化展示训练过程:
pyplot.semilogx(values, all_train, label='train', marker='o') pyplot.semilogx(values, all_test, label='test', marker='o')
完整代码如下:
from sklearn.datasets import make_moons from keras.layers import Dense from keras.models import Sequential from keras.regularizers import l2 from matplotlib import pyplot # 创建数据集 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) # plot train and test means pyplot.semilogx(values, all_train, label='train', marker='o') pyplot.semilogx(values, all_test, label='test', marker='o') pyplot.legend() pyplot.show()
总结
降低过拟合问题,我们一般需要从“数据”,“模型结构”,“模型参数”,“模型训练方法”等角度,采用的方法如下:
- 数据增强:图像的平移,旋转,裁剪等;利用GAN生成新数据;利用机器翻译生成新数据。
- 降低模型复杂度:减少网络层数,神经元个数;
- 添加正则化项,如:L1,L2
- 集成学习:神经网络,dropout
- 避免过长时间训练模型,设置提前终止。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 浅议过拟合现象(overfitting)以及正则化技术原理
- 探索过拟合和欠拟合
- 过拟合与欠拟合-股票投资中的机器学习
- matlab练习程序(曲面拟合)
- 用Keras中的权值约束缓解过拟合
- 过拟合详解:监督学习中不准确的「常识」
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Masterminds of Programming
Federico Biancuzzi、Chromatic / O'Reilly Media / 2009-03-27 / USD 39.99
Description Masterminds of Programming features exclusive interviews with the creators of several historic and highly influential programming languages. Think along with Adin D. Falkoff (APL), Jame......一起来看看 《Masterminds of Programming》 这本书的介绍吧!