如何使用 KerasClassifier 验证拆分和使用 scikit 学习 GridSearchCV

Posted

技术标签:

【中文标题】如何使用 KerasClassifier 验证拆分和使用 scikit 学习 GridSearchCV【英文标题】:How to use KerasClassifier validation split and using scitkit learn GridSearchCV 【发布时间】:2020-04-01 03:59:41 【问题描述】:

我想尝试测试一些超参数,那就是我想使用 GridSearchCV,因为这似乎就是这样做的方式。

但我也想使用验证拆分。使用像 EarlyStopping 或/和 ReduceLROnPlateau 这样的回调。所以我的问题是: 我如何正确实现 GridSearchCV + validation_split 验证拆分中的所有数据都没有用于训练并且整个训练集都用于训练我的模型? Afaik GridSearchCV 再次拆分我剩余的火车数据(即 1-validation_split)并再次拆分?我的准确率有点高,我认为我没有正确拆分数据

model = KerasClassifier(build_fn=create_model,verbose=2, validation_split=0.1)
optimizers = ['rmsprop', 'adam']
init = ['glorot_uniform',
        #'normal',
        'uniform',
        'he_normal',
        #'lecun_normal',
        #'he_uniform'
       ]
epochs = [3] #5,8,10,30
batches = [64] #32,64
param_grid = dict(optimizer=optimizers, epochs=epochs, batch_size=batches, init=init)
grid = GridSearchCV(estimator=model, param_grid=param_grid)
grid_result = grid.fit(X_train, Y_train)

【问题讨论】:

【参考方案1】:

您可以通过将一个额外的参数传递给grid.fit() 函数validation_data=(X_test, Y_test) 来使用您自定义的验证数据。 documentation 声明 grid.fit() 函数接受所有可以传递给默认 Keras model 的实际 model.fit() 函数的有效参数。因此,您可以通过grid.fit() 函数传递验证数据。你也可以在那里传递回调函数。

我在下面添加一个工作代码(应用于 MNIST 数字数据集)。请注意我是如何在grid.fit() 上添加验证数据并删除“validation_split”的:

import tensorflow as tf
import numpy as np
from tensorflow.keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import GridSearchCV
from tensorflow.keras.datasets import mnist 
from tensorflow.keras.utils import to_categorical

(X_train, Y_train), (X_test, Y_test) = mnist.load_data()
Y_train = to_categorical(Y_train, 10)
Y_test = to_categorical(Y_test, 10)
X_train = np.expand_dims(X_train, 3)
X_test = np.expand_dims(X_test, 3)

def create_model(optimizer, init):
    model = tf.keras.Sequential([
         tf.keras.layers.Convolution2D(32, 3, input_shape=(28, 28, 1), 
                                       activation='relu', kernel_initializer=init),
         tf.keras.layers.Convolution2D(32, 3, activation='relu',
                                       kernel_initializer=init),
         tf.keras.layers.Flatten(),
         tf.keras.layers.Dense(12, activation='relu', 
                               kernel_initializer=init),
         tf.keras.layers.Dense(10, activation='softmax', 
                               kernel_initializer=init),
    ])
    model.compile(loss='categorical_crossentropy', 
                  optimizer=optimizer, metrics=['accuracy'])
    return model

model = KerasClassifier(build_fn=create_model, verbose=2,)
optimizers = ['rmsprop', 'adam']
init = ['glorot_uniform',
        #'normal',
        'uniform',
        'he_normal',
        #'lecun_normal',
        #'he_uniform'
       ]
epochs = [4,] 
batches = [32, 64] 
param_grid = dict(optimizer=optimizers, nb_epoch=epochs, 
                  batch_size=batches, init=init)

grid = GridSearchCV(estimator=model, param_grid=param_grid)
grid_result = grid.fit(X_train, Y_train, validation_data=(X_test, Y_test))

希望这会有所帮助。谢谢。

【讨论】:

以上是关于如何使用 KerasClassifier 验证拆分和使用 scikit 学习 GridSearchCV的主要内容,如果未能解决你的问题,请参考以下文章

使用手动 KFold-Cross 验证与 KerasClassifier-KFold 交叉验证时的不同结果

具有多输入 KerasClassifier 的 Sklearn cross_val_score

尽管一切正常,但 KerasClassifier 无法拟合模型

KerasClassifier 对象没有属性模型

使用类权重的网格搜索和 KerasClassifier

如何在不使用和拆分测试集的情况下将我的数据集拆分为训练和验证?