用Keras进行深度学习模式的正则化方法:Dropout

2021-09-10 10:47:50 浏览数 (1)

Dropout是神经网络和深度学习模型的简单而有效的正则化技术。

在这篇文章中,你将发现Dropout正则化技术,以及如何使用Keras将其应用于Python中的模型。

看完这篇文章后,你会知道:

  • Dropout正则化的原理。
  • 如何在输入层上使用Dropout。
  • 如何在隐藏的层上使用Dropout。
  • 如何根据问题调整Dropout。

让我们开始吧。

照片版权:Trekking Rinjani

神经网络的Dropout正则化

Dropout是由Srivastava等人在2014年的一篇论文中提出的一种针对神经网络模型的正则化方法“Dropout: A Simple Way to Prevent Neural Networks from Overfitting”(下载PDF)。

Dropout是在训练期间随机选择的一些神经元忽略的技术。他们随机“Dropout”。这意味着它们对下游神经元的激活的贡献暂时消除,并且在反向过程没有实施任何权重的更新。

随着神经网络学习,神经元的权重会与网络上下文适应。神经元的权重为特定的特性提供一些专门化的调整。相邻的神经元变得依赖于这种专业化,如果过度使用,会导致这种过度专业化的模型脆弱不堪,无法训练数据。神经元在训练过程中的这种依赖上下文的现象被称为复杂的协同适应(complex co-adaptations)。

你可以想象,如果神经元在训练期间被随机地从网络中舍弃,那么其他的神经元将不得不介入并处理对缺失的神经元做出预测所需要的表征。这被认为可以让网络学习到多个独立的内部表征。

它的效果是让网络对神经元的特定权重变得不那么敏感。让网络能够更好地泛化,并且很少过拟合训练数据。

Keras中的Dropout正则化

每轮权重更新,以给定的概率(例如20%)从随机选择的节点中舍弃,这个过程很容易实现。这就是在Keras中实现Dropout。Dropout仅在训练模型时使用,在评估模型的技能时不使用。

接下来我们将探讨在Keras中使用Dropout的几种不同方法。

这些例子将使用Sonar数据集。这是二分类问题,其目标是用声纳的回声正确识别岩石和矿。它是神经网络的一个很好的测试数据集,因为所有的输入值都是数字型,并且具有相同的量纲。

数据集可以从UCI Machine Learning库下载。你可以将声纳数据集放在当前的工作目录中,文件名为sonar.csv。

我们将使用scikit-learning的10次折交叉验证来评估开发的模型,以便更好地梳理结果的差异。

有60个输入值和一个输出值,输入值在网络使用前被归一化。基准神经网络模型有两个隐藏层,第一个为60个节点,第二个为30个。使用随机梯度下降以较低的学习率和动量对模型进行训练。

完整的基准模型如下所示。

代码语言:javascript复制
# Baseline Model on the Sonar Dataset
import numpy
from pandas import read_csv
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.wrappers.scikit_learn import KerasClassifier
from keras.constraints import maxnorm
from keras.optimizers import SGD
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)
# load dataset
dataframe = read_csv("sonar.csv", header=None)
dataset = dataframe.values
# split into input (X) and output (Y) variables
X = dataset[:,0:60].astype(float)
Y = dataset[:,60]
# encode class values as integers
encoder = LabelEncoder()
encoder.fit(Y)
encoded_Y = encoder.transform(Y)

# baseline
def create_baseline():
	# create model
	model = Sequential()
	model.add(Dense(60, input_dim=60, kernel_initializer='normal', activation='relu'))
	model.add(Dense(30, kernel_initializer='normal', activation='relu'))
	model.add(Dense(1, kernel_initializer='normal', activation='sigmoid'))
	# Compile model
	sgd = SGD(lr=0.01, momentum=0.8, decay=0.0, nesterov=False)
	model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
	return model

numpy.random.seed(seed)
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasClassifier(build_fn=create_baseline, epochs=300, batch_size=16, verbose=0)))
pipeline = Pipeline(estimators)
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
results = cross_val_score(pipeline, X, encoded_Y, cv=kfold)
print("Baseline: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))

运行示例,生成的估计分类准确度是86%。

代码语言:javascript复制
Baseline: 86.04% (4.58%)

在可见层上使用Dropout

Dropout应用于输入的神经元称为可见层。

在下面的示例中,我们在输入(或者说可见层)和第一个隐藏层之间添加一个新层Dropout。舍弃率设置为20%,这意味着从每个更新周期中随机排除5个输入中的一个。

另外,按照关于Dropout的原始文章中的建议,对每个隐藏层的权重加了限制,确保权重的最大值不超过3。这可以通过在构造层时设置Dense class中的kernel_constraint参数实现。

学习率提升一个数量级,momentum上升到0.9。这些增加的学习率的方法也是在原来的Dropout论文中推荐的。

继续从上面的基准示例,下面的代码练习与相同的输入Dropout网络。

代码语言:javascript复制
# dropout in the input layer with weight constraint
def create_model():
	# create model
	model = Sequential()
	model.add(Dropout(0.2, input_shape=(60,)))
	model.add(Dense(60, kernel_initializer='normal', activation='relu', kernel_constraint=maxnorm(3)))
	model.add(Dense(30, kernel_initializer='normal', activation='relu', kernel_constraint=maxnorm(3)))
	model.add(Dense(1, kernel_initializer='normal', activation='sigmoid'))
	# Compile model
	sgd = SGD(lr=0.1, momentum=0.9, decay=0.0, nesterov=False)
	model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
	return model

numpy.random.seed(seed)
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasClassifier(build_fn=create_model, epochs=300, batch_size=16, verbose=0)))
pipeline = Pipeline(estimators)
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
results = cross_val_score(pipeline, X, encoded_Y, cv=kfold)
print("Visible: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))

运行示例,生成的估计分类准确度下降到83.5%。

代码语言:javascript复制
Visible: 83.52% (7.68%)

在隐藏层中使用Dropout

Dropout也可用于模型内的隐藏层节点

在下面的示例中,Dropout应用于两个隐藏层之间以及最后一个隐藏层和输出层之间。再次使用20%的辍学率,就像这些层的权重约束一样。??????

代码语言:javascript复制
# dropout in hidden layers with weight constraint
def create_model():
	# create model
	model = Sequential()
	model.add(Dense(60, input_dim=60, kernel_initializer='normal', activation='relu', kernel_constraint=maxnorm(3)))
	model.add(Dropout(0.2))
	model.add(Dense(30, kernel_initializer='normal', activation='relu', kernel_constraint=maxnorm(3)))
	model.add(Dropout(0.2))
	model.add(Dense(1, kernel_initializer='normal', activation='sigmoid'))
	# Compile model
	sgd = SGD(lr=0.1, momentum=0.9, decay=0.0, nesterov=False)
	model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
	return model

numpy.random.seed(seed)
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasClassifier(build_fn=create_model, epochs=300, batch_size=16, verbose=0)))
pipeline = Pipeline(estimators)
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
results = cross_val_score(pipeline, X, encoded_Y, cv=kfold)
print("Hidden: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))

我们可以看到,对于这个问题,以及使用隐藏层中的Dropout网络配置并没有提升性能。事实上,表现比基线差。

可能需要额外的训练次数,或者需要进一步调整学习率。

代码语言:javascript复制
Hidden: 83.59% (7.31%)

使用Dropout的提示??

关于Dropout的原始论文提供了一套标准机器学习问题的实验结果。因此,他们在实践中提供了一些有用的启发式来考虑使用辍学。

  • 通常,使用20%-50%的舍弃率比较好。一个概率太低,没什么效果,概率太高会导致网络的学习不充分。
  • Dropout被使用在大型网络中可能会有更好的表现,有更多机会学习独立表征。
  • 在输入层和隐藏层都使用Dropout已经证明效果不错。
  • 使用大的学习率与冲量,学习率扩大10~100倍,冲量值调到0.9~0.99。
  • 限制网络权重的大小。大的学习率可能导致过大的网络权重。对网络权重的大小施加约束,可以改善结果。

总结

在这篇文章中,你发现了深度学习模型的Dropout正则化技术。你学了:

  • Dropout的含义和原理。
  • 如何在自己的深度学习模式使用Dropout。
  • 使用Dropout达到最好效果的技巧。

原文:http://machinelearningmastery.com/dropout-regularization-deep-learning-models-keras/

0 人点赞