Как использовать HyperOpt для оптимизации гиперпараметров сети глубокого обучения Keras?

Я хочу построить модель нелинейной регрессии с использованием keras для прогнозирования непрерывной переменной + ve. Как выбрать следующие гиперпараметры для модели ниже?

  1. Количество скрытых слоев и нейронов
  2. Коэффициент отсева
  3. Использовать BatchNormalization или нет
  4. Функция активации вне линейной, relu, tanh, сигмовидной
  5. Лучший оптимизатор для использования среди adam, rmsprog, sgd

Код

def dnn_reg():
    model = Sequential()
    #layer 1
    model.add(Dense(40, input_dim=13, kernel_initializer='normal'))
    model.add(Activation('tanh'))
    model.add(Dropout(0.2))
    #layer 2
    model.add(Dense(30, kernel_initializer='normal'))
    model.add(BatchNormalization())
    model.add(Activation('relu'))
    model.add(Dropout(0.4))
    #layer 3
    model.add(Dense(5, kernel_initializer='normal'))
    model.add(BatchNormalization())
    model.add(Activation('relu'))
    model.add(Dropout(0.4))

    model.add(Dense(1, kernel_initializer='normal'))
    model.add(Activation('relu'))
    # Compile model
    model.compile(loss='mean_squared_error', optimizer='adam')
    return model

Я рассмотрел случайный поиск по сетке, но вместо этого хочу использовать гиперопт, который, как мне кажется, будет быстрее. Первоначально я реализовал настройку с помощью https://github.com/maxpumperla/hyperas. Hyperas не работает с последней версией keras. Я подозреваю, что keras быстро развивается, и сопровождающему сложно сделать его совместимым. Поэтому я думаю, что использование Hyperopt напрямую будет лучшим вариантом.

PS: Я новичок в байесовской оптимизации для настройки гиперпараметров и гипероптики.


person GeorgeOfTheRF    schedule 21.04.2017    source источник
comment
Вы нашли решение своей проблемы? Если да, не могли бы вы обновить свой вопрос, чтобы он помог всем с подобным вопросом? Спасибо.   -  person Tae-Sung Shin    schedule 07.05.2020


Ответы (2)


У меня был большой успех с Hyperas. Вот что я узнал, чтобы заставить его работать.

1) Запустите его как скрипт python из терминала (не из записной книжки Ipython) 2) Убедитесь, что у вас нет комментариев в вашем коде (Hyperas не любит комментарии!) 3) Инкапсулируйте ваши данные и модель в работают, как описано в файле readme по гиперам.

Ниже приведен пример сценария Hyperas, который работал у меня (следуя приведенным выше инструкциям).

from __future__ import print_function

from hyperopt import Trials, STATUS_OK, tpe
from keras.datasets import mnist
from keras.layers.core import Dense, Dropout, Activation
from keras.models import Sequential
from keras.utils import np_utils
import numpy as np
from hyperas import optim
from keras.models import model_from_json
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.optimizers import SGD , Adam
import tensorflow as tf
from hyperas.distributions import choice, uniform, conditional
__author__ = 'JOnathan Hilgart'



def data():
    """
    Data providing function:

    This function is separated from model() so that hyperopt
    won't reload data for each evaluation run.
    """
    import numpy as np
    x = np.load('training_x.npy')
    y = np.load('training_y.npy')
    x_train = x[:15000,:]
    y_train = y[:15000,:]
    x_test = x[15000:,:]
    y_test = y[15000:,:]
    return x_train, y_train, x_test, y_test


def model(x_train, y_train, x_test, y_test):
    """
    Model providing function:

    Create Keras model with double curly brackets dropped-in as needed.
    Return value has to be a valid python dictionary with two customary keys:
        - loss: Specify a numeric evaluation metric to be minimized
        - status: Just use STATUS_OK and see hyperopt documentation if not feasible
    The last one is optional, though recommended, namely:
        - model: specify the model just created so that we can later use it again.
    """
    model_mlp = Sequential()
    model_mlp.add(Dense({{choice([32, 64,126, 256, 512, 1024])}},
                        activation='relu', input_shape= (2,)))
    model_mlp.add(Dropout({{uniform(0, .5)}}))
    model_mlp.add(Dense({{choice([32, 64, 126, 256, 512, 1024])}}))
    model_mlp.add(Activation({{choice(['relu', 'sigmoid'])}}))
    model_mlp.add(Dropout({{uniform(0, .5)}}))
    model_mlp.add(Dense({{choice([32, 64, 126, 256, 512, 1024])}}))
    model_mlp.add(Activation({{choice(['relu', 'sigmoid'])}}))
    model_mlp.add(Dropout({{uniform(0, .5)}}))
    model_mlp.add(Dense({{choice([32, 64, 126, 256, 512, 1024])}}))
    model_mlp.add(Activation({{choice(['relu', 'sigmoid'])}}))
    model_mlp.add(Dropout({{uniform(0, .5)}}))
    model_mlp.add(Dense(9))
    model_mlp.add(Activation({{choice(['softmax','linear'])}}))
    model_mlp.compile(loss={{choice(['categorical_crossentropy','mse'])}}, metrics=['accuracy'],
                  optimizer={{choice(['rmsprop', 'adam', 'sgd'])}})



    model_mlp.fit(x_train, y_train,
              batch_size={{choice([16, 32, 64, 128])}},
              epochs=50,
              verbose=2,
              validation_data=(x_test, y_test))
    score, acc = model_mlp.evaluate(x_test, y_test, verbose=0)
    print('Test accuracy:', acc)
    return {'loss': -acc, 'status': STATUS_OK, 'model': model_mlp}

    enter code here

if __name__ == '__main__':
    import gc; gc.collect()

    with K.get_session(): ## TF session
        best_run, best_model = optim.minimize(model=model,
                                              data=data,
                                              algo=tpe.suggest,
                                              max_evals=2,
                                              trials=Trials())
        X_train, Y_train, X_test, Y_test = data()
        print("Evalutation of best performing model:")
        print(best_model.evaluate(X_test, Y_test))
        print("Best performing model chosen hyper-parameters:")
        print(best_run)

это вызвано другой последовательностью gc, если сначала сеанс сбора python, программа завершится успешно, если сначала python соберет память swig (tf_session), программа завершится с ошибкой.

вы можете заставить python удалить сеанс:

del session

или если вы используете keras, вы не можете получить экземпляр сеанса, вы можете запустить следующий код в конце вашего кода:

import gc; gc.collect()
person Jonathan Hilgart    schedule 05.05.2017
comment
Код, которым вы поделились, работает, но через несколько эпох я получаю следующую ошибку. AssertionError: исключение игнорируется в: ‹связанном методе BaseSession .__ del__ объекта‹ tensorflow.python.session.Session по адресу 0x000665667 ›› - person GeorgeOfTheRF; 22.05.2017
comment
Решение хорошее, но отсутствует использование kernel_initializer, которое использовалось OP. Это все еще вариант для гиперактивов? - person StatsSorceress; 24.05.2017
comment
Очень странно думать, что гиперактивы не допускают комментариев. Я не так уверен в этом. У вас есть ссылка? - person StatsSorceress; 24.05.2017
comment
@StatsSorceress Hyperas, по своей сути, является парсером строк. Похоже, что в вашем случае что-то пойдет не так из-за комментариев, по крайней мере, я так подозреваю: github.com / maxpumperla / hyperas / issues / 24 - person Jonathan Hilgart; 27.05.2017
comment
Что, если в конечном итоге у вас будет 1024 нейрона последнего скрытого слоя, но 32 на входе? - person mikkokotila; 18.05.2018

Это также может быть другой подход:

from hyperopt import fmin, tpe, hp, STATUS_OK, Trials
from sklearn.metrics import roc_auc_score
import sys

X = []
y = []
X_val = []
y_val = []

space = {'choice': hp.choice('num_layers',
                    [ {'layers':'two', },
                    {'layers':'three',
                    'units3': hp.uniform('units3', 64,1024), 
                    'dropout3': hp.uniform('dropout3', .25,.75)}
                    ]),

            'units1': hp.uniform('units1', 64,1024),
            'units2': hp.uniform('units2', 64,1024),

            'dropout1': hp.uniform('dropout1', .25,.75),
            'dropout2': hp.uniform('dropout2',  .25,.75),

            'batch_size' : hp.uniform('batch_size', 28,128),

            'nb_epochs' :  100,
            'optimizer': hp.choice('optimizer',['adadelta','adam','rmsprop']),
            'activation': 'relu'
        }

def f_nn(params):   
    from keras.models import Sequential
    from keras.layers.core import Dense, Dropout, Activation
    from keras.optimizers import Adadelta, Adam, rmsprop

    print ('Params testing: ', params)
    model = Sequential()
    model.add(Dense(output_dim=params['units1'], input_dim = X.shape[1])) 
    model.add(Activation(params['activation']))
    model.add(Dropout(params['dropout1']))

    model.add(Dense(output_dim=params['units2'], init = "glorot_uniform")) 
    model.add(Activation(params['activation']))
    model.add(Dropout(params['dropout2']))

    if params['choice']['layers']== 'three':
        model.add(Dense(output_dim=params['choice']['units3'], init = "glorot_uniform")) 
        model.add(Activation(params['activation']))
        model.add(Dropout(params['choice']['dropout3']))    

    model.add(Dense(1))
    model.add(Activation('sigmoid'))
    model.compile(loss='binary_crossentropy', optimizer=params['optimizer'])

    model.fit(X, y, nb_epoch=params['nb_epochs'], batch_size=params['batch_size'], verbose = 0)

    pred_auc =model.predict_proba(X_val, batch_size = 128, verbose = 0)
    acc = roc_auc_score(y_val, pred_auc)
    print('AUC:', acc)
    sys.stdout.flush() 
    return {'loss': -acc, 'status': STATUS_OK}


trials = Trials()
best = fmin(f_nn, space, algo=tpe.suggest, max_evals=50, trials=trials)
print('best: ', best)

Источник

person Jeril    schedule 01.03.2018