在Keras中使用权重约束减少深度神经网络中的过度拟合权重约束提供了一种方法来减少深度学习神经网络模型对训练数据的过度拟合并提高模型在新数据上的性能(例如在测试集上的性能)。有各种类型的权重约束,例如最大和单位向量范数,有些需要必须配置的超参数。在本教程中,您将了解用于向深度学习神经网络模型添加权重约束以减少过度拟合的KerasAPI。完成本教程后,您将了解:如何使用KerasAPI创建向量范数约束。如何使用KerasAPI向MLP、CNN和RNN层添加权重约束。如何通过向现有模型添加权重约束来减少过度拟合。教程概述本教程分为三个部分,它们是:Keras权重约束层上的权重约束权重约束案例研究Keras权重约束KerasAPI支持权重约束。约束是按层指定的,但在层内的每个节点上应用和强制执行。使用约束通常涉及在层上为输入权重设置kernel_constraint参数,为偏置权重设置bias_constraint。通常,权重约束不用于偏置权重。一组不同的向量规范可以用作约束,在keras.constraints模块中作为类提供。它们是:最大范数(max_norm),用于强制权重等于或低于给定限制。非负范数(non_neg),强制权重为正数。单位范数(unit_norm),强制权重为1.0。最小-最大范数(min_max_norm),用于在一个范围内强制执行权重。例如,可以像这样导入和实例化一个简单的约束:#importnormfromkeras.constraintsimportmax_norm#instantiatenormnorm=max_norm(3.0)#importnormfromkeras.constraintsimportmax_norm#instantiatenormnorm=max_norm(3.0)层上的权重约束权重范数可用于大多数Keras层。在本节中,我们将查看一些常见示例。MLP权重约束以下示例在密集全连接层上设置最大范数权重约束。#exampleofmaxnormonadenselayerfromkeras.layersimportDensefromkeras.constraintsimportmax_norm...model.add(密集(32,kernel_constraint=max_norm(3),bias_constraint==max_norm(3)))...#exampleofmaxnormonadenselayerfromkeras.layersimportDensefromkeras.constraintsimportmax_norm.model(密集...模型(32,kernel_constraint=max_norm(3),bias_constraint==max_norm(3)))...CNN权重约束以下示例在卷积层上设置最大范数权重约束。#exampleofmaxnormonacnnlayerfromkeras.layersimportConv2Dfromkeras.constraintsimportmax_norm...model.add(Conv2D(32,(3,3),kernel_constraint=max_norm(3),bias_constraint==max_norm(3)))...RNN权重约束和其他层类型不同,循环神经网络允许您设置输入权重和偏差的权重约束,以及循环输入权重。循环权重的约束是通过层的recurrent_constraint参数设置的。以下示例在LSTM层上设置最大范数权重约束。#exampleofmaxnormonanlstmlayerfromkeras.layersimportLSTMfromkeras.constraintsimportmax_norm...model.add(LSTM(32,kernel_constraint=max_norm(3),recurrent_constraint=max_norm(3),bias_constraint==max_norm.LS(3)))...#exampleofmaxnormonanlstmlayerconstraintfromkerasTM.layersimport。.model.add(LSTM(32,kernel_constraint=max_norm(3),recurrent_constraint=max_norm(3),bias_constraint==max_norm(3)))...现在我们知道如何使用权重约束API,让我们看看的有效例子。加权约束案例研究在本节中,我们将演示如何使用权重约束来减少MLP在简单二元分类问题上的过度拟合。此示例提供了一个模板,用于将权重约束应用于您自己的神经网络以解决分类和回归问题。二元分类问题我们将使用一个标准的二元分类问题来定义两个半圆数据集,一个半圆代表每个类。每个观测值都有两个具有相同尺度和类输出值0或1的输入变量。这个数据集被称为“月亮”数据集,因为绘制时每个类的观测值的形状。我们可以使用make_moons()函数从这个问题中生成观察结果。我们将向数据添加噪声并为随机数生成器播种,以便每次运行代码时生成相同的样本。#generate2dclassificationdatasetX,y=make_moons(n_samples=100,noise=0.2,random_state=1)我们可以在图上绘制数据集,其中两个变量作为x和y坐标,类值作为观察的颜色。下面列出了生成数据集并绘制它的完整示例。#generatetwomoonsdatasetfromsklearn.datasetsimportmake_moonsfrommatplotlibimportpyplotfrompandasimportDataFrame#generate2dclassificationdatasetX,y=make_moons(n_samples=100,noise=0.2,random_state=1)#scatterplot,dotscoloredbyclassvalued]1[字典,(x]标签=y))颜色={0:'红色',1:'blue'}fig,ax=pyplot.subplots()grouped=df.groupby('label')forkey,grouped:group.plot(axax=ax,kind='scatter',x='x',y='y',label=key,color=colors[key])pyplot.show()#generatetwomoonsdatasetfromsklearn.datasetsimportmake_moonsfrommatplotlibimportpyplotfrompandasimportDataFrame#generate2dclassificationdatasetX,y=make_moons(n_samples=10noise=0.2,random_state=1)#scatterplot,dotscoloredbyclassvaluedf=DataFrame(字典(x=X[:,0],y=X[:,1],label=y))colors={0:'red',1:'blue'}fig,ax=pyplot.subplots()grouped=df.groupby('label')forkey,groupgrouped:group.plot(axax=ax,kind='scatter',x='x',y='y',label=key,color=colors[key])pyplot.show()运行该示例会创建一个散点图,显示在每个类中观察到的半圆或月亮形状。我们可以看到点散布中的噪声使卫星不那么明显。这是一个很好的测试问题,因为类不能用一行分隔,例如不是线性可分的,需要神经网络等非线性方法来求解。我们只生成了100个样本,这对于神经网络来说很小,提供了过度拟合训练数据集并在测试数据集上产生更高错误的机会:使用正则化的一个很好的例子。此外,样本有噪声,使模型有机会学习不一致样本的各个方面。在多层感知器上我们可以开发一个MLP模型来解决这个二元分类问题。该模型将有一个隐藏层,其节点数多于解决问题所需的数量,从而为过度拟合提供了机会。我们还训练模型比必要的时间更长,以确保模型过度杀伤。在定义模型之前,我们将数据集分为训练集和测试集,使用30个示例来训练模型,使用70个示例来评估拟合模型的性能。X,y=make_moons(n_samples=100,noise=0.2,random_state=1)#splitintotrainandtestn_train=30trainX,testX=X[:n_train,:],X[n_train:,:]trainy,testy=y[:n_train],y[n_train:]接下来,我们可以定义模型。隐藏层使用隐藏层中的500个节点和一个修正线性激活函数。输出层使用sigmoid激活函数来预测类别值为0或1。该模型使用二元交叉熵损失函数进行优化,这是Adam的一个有效版本,用于二元分类问题和梯度下降。#definemodelmodel=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'])然后,将定义的模型拟合到4,000个训练数据,默认批量大小为32。我们还将使用测试数据集作为验证数据集。#fitmodelhistory=model.fit(trainX,trainy,validation_data=(testX,testy),epochs=4000,verbose=0)我们可以评估模型在测试数据集上的性能并报告结果。#evaluatethemodel_,train_acc=model.evaluate(trainX,trainy,verbose=0)_,test_acc=model.evaluate(testX,testy,verbose=0)print('火车:%.3f,测试:%.3f'%(train_acc,test_acc))最后,我们将绘制模型在每个时期的训练集和测试集上的性能。如果模型确实过度拟合了训练数据集,我们预计训练集上的准确率线图会继续增加,并且随着模型学习训练数据集中的统计噪声,测试设置会上升然后再次下降。#plothistorypyplot.plot(history.history['acc'],label='train')pyplot.plot(history.history['val_acc'],label='test')pyplot.legend()pyplot.show()我们可以将所有这些部分组合起来;下面列出了一个完整的例子。#mlpoverfitonthemoonsdatasetfromsklearn.datasetsimportmake_moonsfromkeras.layersimportDensefromkeras.modelsimportSequentialfrommatplotlibimportpyplot#generate2dclassificationdatasetX,y=make_moons(n_samples=100,noise=0.2,random_state=1)#splitintotrainandtestn_train=30trainX,testX=X[:n_train_train::,]X[,testy=y[:n_train],y[n_train:]#definemodelmodel=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'])#fitmodelhistory=model.fit(trainX,trainy,validation_data=(testX,testy),epochs=4000,verbose=0)#evaluatethemodel_,train_acc=model.evaluate(trainX,trainy,verbose=0)_,test_acc=model.evaluate(testX,testy,verbose=0)print('火车:%.3f,测试:%.3f'%(train_acc,test_acc))#plothistorypyplot.plot(history.history['acc'],label='train')pyplot.plot(history.history['val_acc'],label='test')pyplot.legend()pyplot.show()运行该显示示例报告车辆和测试数据集上的模型性能我们可以看到模型在训练数据集上的性能优于测试数据集,这可能是过度拟合的迹象。由于神经网络和训练算法的随机性,您的确切结果可能会有所不同。由于模型过度拟合,我们通常不期望在同一数据集上重复运行模型会出现准确性差异(如果有的话)。Train:1.000,Test:0.914创建一个图表,显示训练集和测试集上的模型精度图。我们可以看到过拟合模型的预期形状,其中测试准确度增加到一个点,然后又开始下降。具有权重约束的过度拟合MLP我们可以更新示例以使用权重约束。有几个不同的加权限制可供选择。这个模型的一个很好的简单约束是简单地归一化权重,使范数等于1.0。此约束具有强制所有传入权重较小的效果。我们可以通过在Keras中使用unit_norm来做到这一点。这个约束可以添加到第一个隐藏层,如下所示:model.add(Dense(500,input_dim=2,activation='relu',kernel_constraint=unit_norm()))maximum设置为1.0以达到相同的结果,例如:model.add(Dense(500,input_dim=2,activation='relu',kernel_constraint=min_max_norm(min_value=1.0,max_value=1.0)))我们不能通过maxnorm数值约束实现相同的结果,因为它允许范数等于或低于指定的限制;forexample:model.add(Dense(500,input_dim=2,activation='relu',kernel_constraint=max_norm(1.0)))listedbelow了具有单位规范约束的完整更新示例:#mlpoverfitonthemoonsdatasetwithaunitnormconstraintfromsklearn.datasetsimportmake_moonsfromkeras.layersimportDensefromkeras.modelsimportSequentialfromkeras.约束importunit_normfrommatplotlibimportpyplot#generate2dclassificationdatasetX,y=make_moons(n_samples=100,noise=0.2,random_state=1)#splitintotrainandtestn_train=30trainX,testX=X[:n_train,:],X[n_train:,:]trainy,testy=y[:n_train],y[n_train:]#definemodelmodel=Sequential()model.add(Dense(500,input_dim=2,activation='relu',kernel_constraint=unit_norm()))model.add(Dense(1,activation='sigmoid'))model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])#fitmodelhistory=model.fit(trainX,trainy,validation_data=(testX,testy),epochs=4000,verbose=0)#evaluatethemodel_,train_acc=model.evaluate(trainX,trainy,verbose=0)_,test_acc=model.evaluate(testX,testy,verbose=0)print('火车:%.3f,测试:%.3f'%(train_acc,test_acc))#plothistorypyplot.plot(history.history['acc'],label='train')pyplot.plot(history.history['val_acc'],label='test')pyplot.legend()pyplot.show()运行示例来报告模型在训练和测试数据集上的性能我们可以看到,对权重大小的严格限制确实提高了模型在测试集上的性能,而不影响模型的训练性能放。Train:1.000,Test:0.943回头看训练集曲线和测试准确率,可以看出模型对训练数据集过拟合了。训练集和测试集上的模型准确性继续提高到一个稳定水平。扩展本节列出了一些您可能希望探索的扩展教程的想法。报告加权标准。该示例已更新以计算网络权重的大小并证明约束确实使大小变小。约束输出层。更新示例以向模型的输出层添加约束并比较结果。约束偏差。更新示例以向偏差权重添加约束并比较结果。反复评价。更新示例以多次拟合和评估模型,并报告模型性能的均值和标准差。
