Jus*_*lms 18 machine-learning scikit-learn cross-validation keras grid-search
我希望通过Keras和sklean实现早期停止GridSearchCV.
下面的工作代码示例是使用Keras在Python中如何使用网格搜索超参数进行深度学习模型修改的.可以从这里下载数据集.
修改添加了Keras EarlyStopping回调类以防止过度拟合.为了使其有效,它需要monitor='val_acc'用于监控验证准确性的论据.要val_acc使其可用,KerasClassifier需要validation_split=0.1生成验证准确性,否则EarlyStopping提高RuntimeWarning: Early stopping requires val_acc available!.注意FIXME:代码注释!
请注意,我们可以更换val_acc的val_loss!
问题:如何使用GridSearchCVk-fold算法生成的交叉验证数据集,而不是浪费10%的训练数据用于早期停止验证集?
# Use scikit-learn to grid search the learning rate and momentum
import numpy
from sklearn.model_selection import GridSearchCV
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
from keras.optimizers import SGD
# Function to create model, required for KerasClassifier
def create_model(learn_rate=0.01, momentum=0):
# create model
model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# Compile model
optimizer = SGD(lr=learn_rate, momentum=momentum)
model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])
return model
# Early stopping
from keras.callbacks import EarlyStopping
stopper = EarlyStopping(monitor='val_acc', patience=3, verbose=1)
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)
# load dataset
dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:8]
Y = dataset[:,8]
# create model
model = KerasClassifier(
build_fn=create_model,
epochs=100, batch_size=10,
validation_split=0.1, # FIXME: Instead use GridSearchCV k-fold validation data.
verbose=2)
# define the grid search parameters
learn_rate = [0.01, 0.1]
momentum = [0.2, 0.4]
param_grid = dict(learn_rate=learn_rate, momentum=momentum)
grid = GridSearchCV(estimator=model, param_grid=param_grid, verbose=2, n_jobs=1)
# Fitting parameters
fit_params = dict(callbacks=[stopper])
# Grid search.
grid_result = grid.fit(X, Y, **fit_params)
# summarize results
print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
print("%f (%f) with: %r" % (mean, stdev, param))
Run Code Online (Sandbox Code Playgroud)
des*_*aut 24
[问题编辑后澄清并澄清:]
在急于实施问题之前,花一些时间思考方法和任务本身总是一个好习惯; 可以说,早期停止与交叉验证程序混合并不是一个好主意.
让我们举一个例子来突出这个论点.
假设您确实使用100个时期的早期停止,以及超参数选择的5倍交叉验证(CV).假设您最终得到了一个超参数集X,它可以提供最佳性能,比如89.3%的二进制分类精度.
现在假设您的第二个最佳超参数集Y,准确率为89.2%.仔细检查个人简历褶皱,您会看到,你最好的情况下X,3开出5 CV的折叠用尽最大100时代,而在其他2月初停止踢了,在89个93分别纪元说.
现在想象一下,检查你的第二个最好的集合Y,你会看到5个CV折叠中的4个用尽了100个时代,而第5个时期早在约80个时期停止了.
这样的实验会得出什么结论?
可以说,你会发现自己处于一个不确定的境地; 进一步的实验可能会揭示哪个实际上是最好的超参数集,当然,您可以考虑首先考虑结果的这些细节.不用说,如果所有这些都是通过回调自动完成的,那么你可能已经错过了最好的模型,尽管你实际上已经尝试过了.
整个简历的想法隐含地基于"所有其他是平等的"论点(当然,这在实践中从来都不是真的,只能以最好的方式进行近似).如果您觉得时代的数量应该是一个超参数,那么只需将它明确地包含在您的简历中,而不是通过早期停止的后门插入,这可能会影响整个过程(更不用说早期停止本身了)超参数,patience).
不混合这两种技术并不意味着你不能顺序使用它们:一旦你通过简历获得了最好的超参数,你可以在整个训练集中拟合模型时提前停止(当然你提供有一个单独的验证集).
深度神经网络领域仍然(非常)年轻,它确实尚未建立其"最佳实践"指南; 事实上,由于一个令人惊叹的社区,开源实现中提供了各种各样的工具,你可以很容易地发现自己陷入了混乱的困境(因为它们碰巧可用).我并不一定说这就是你在这里尝试做的事情 - 我只是在提出一些可能没有设计的想法时更加谨慎......
| 归档时间: |
|
| 查看次数: |
4577 次 |
| 最近记录: |