网格搜索具有多个输入的Keras

时间:2019-06-30 12:48:54

标签: python keras deep-learning grid-search hyperparameters

我正在尝试对我的超参数进行网格搜索,以调整深度学习架构。我对该模型有多个输入选项,并且正在尝试使用sklearn的网格搜索API。问题是,网格搜索api仅将单个数组作为输入,并且在检查数据大小维度时代码失败。(我的输入维度是5 *数据点数,而根据sklearn api,它应该是数据点数*功能尺寸)。我的代码如下所示:

from keras.layers import Concatenate, Reshape, Input, Embedding, Dense, Dropout
from keras.models import Model
from keras.wrappers.scikit_learn import KerasClassifier

def model(hyparameters):
    a = Input(shape=(1,))
    b = Input(shape=(1,))
    c = Input(shape=(1,))
    d = Input(shape=(1,))
    e = Input(shape=(1,))

    //Some operations and I get a single output -->out
    model = Model([a, b, c, d, e], out)
    model.compile(optimizer='rmsprop',
                               loss='categorical_crossentropy',
                               metrics=['accuracy'])
    return model

k_model = KerasClassifier(build_fn=model, epochs=150, batch_size=512, verbose=2)
# define the grid search parameters
param_grid = hyperparameter options dict
grid = GridSearchCV(estimator=k_model, param_grid=param_grid, n_jobs=-1)
grid_result = grid.fit([a_input, b_input, c_input, d_input, e_input], encoded_outputs)

1 个答案:

答案 0 :(得分:1)

这是将GridSearch和Keras模型用于多个输入的解决方法。诀窍在于将所有输入合并到一个数组中。我创建了一个虚拟模型,该模型接收一个输入,然后使用Lambda层将其拆分为所需的部分。该过程可以根据您自己的数据结构轻松修改

def createMod(optimizer='Adam'):
    
    combi_input = Input((3,)) # (None, 3)
    a_input = Lambda(lambda x: tf.expand_dims(x[:,0],-1))(combi_input) # (None, 1) 
    b_input = Lambda(lambda x: tf.expand_dims(x[:,1],-1))(combi_input) # (None, 1)
    c_input = Lambda(lambda x: tf.expand_dims(x[:,2],-1))(combi_input) # (None, 1)
    
    ## do something
    c = Concatenate()([a_input, b_input, c_input])
    x = Dense(32)(c)

    out = Dense(1,activation='sigmoid')(x)
    model = Model(combi_input, out)

    model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics='accuracy')

    return model


## recreate multiple inputs
n_sample = 1000
a_input, b_input, c_input = [np.random.uniform(0,1, n_sample) for _ in range(3)]
y = np.random.randint(0,2, n_sample)

## merge inputs
combi_input = np.stack([a_input, b_input, c_input], axis=-1)


model = tf.keras.wrappers.scikit_learn.KerasClassifier(build_fn=createMod, verbose=0)
batch_size = [10, 20]
epochs = [10, 5]
optimizer = ['adam','SGD']
param_grid = dict(batch_size=batch_size, epochs=epochs)
grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1, cv=3)
grid_result = grid.fit(combi_input, y)

另一种简单而有价值的solution