Поиск по сетке для Keras с несколькими входами

Я пытаюсь выполнить поиск по сетке по своим гиперпараметрам для настройки архитектуры глубокого обучения. У меня есть несколько вариантов ввода для модели, и я пытаюсь использовать API-интерфейс поиска сетки 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)

person Biswadip Mandal    schedule 30.06.2019    source источник


Ответы (1)


это обходной путь для использования модели GridSearch и Keras с несколькими входами. трюк состоит в том, чтобы объединить все входные данные в один массив. Я создаю фиктивную модель, которая получает ОДИН вход, а затем разделяю ее на нужные части с помощью лямбда-слоев. процедура может быть легко изменена в соответствии с вашей собственной структурой данных

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)

Еще одно простое и полезное решение

person Marco Cerliani    schedule 22.06.2020
comment
вот еще один пример: stackoverflow.com/questions/62510913/ - person Marco Cerliani; 25.06.2020