深度学习的正则化方法

深度学习的正则化方法: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个。使用随机梯度下降以较低的学习率和动量对模型进行训练。

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

# 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%。

Baseline: 86.04% (4.58%)

在可见层上使用Dropout

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

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

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

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

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

# 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%。

Visible: 83.52% (7.68%)

来源: https://www.atyun.com/3905.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值