Я использую пакет hyperopt для поиска гиперпараметров моей глубокой нейронной сети.Ниже мой код.Мой набор данных здесь слишком большой.Я использую набор данных iris, чтобы показать проблему.
from sklearn import datasets
from sklearn.preprocessing import OneHotEncoder
iris = datasets.load_iris()
X = iris.data
y = iris.target.reshape(-1,1)
enc = OneHotEncoder(sparse=False)
y = enc.fit_transform(y)
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.33, random_state=1)
# search space
space = {'choice': hp.choice('num_layers',
[
{'layers':'two',},
{'layers':'three',
'units3': hp.choice('units3', [64, 128, 256, 512]),
'dropout3': hp.choice('dropout3', [0.25,0.5,0.75]) }
]),
'units1': hp.choice('units1', [64, 128, 256, 512]),
'units2': hp.choice('units2', [64, 128, 256, 512]),
'dropout1': hp.choice('dropout1', [0.25,0.5,0.75]),
'dropout2': hp.choice('dropout2', [0.25,0.5,0.75]),
'batch_size' : hp.choice('batch_size', [28,64,128]),
'epochs' : 50,
'optimizer': 'adadelta',
'activation': 'relu' }
#Objective function that hyperopt will minimize
def objective(params):
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.optimizers import Adadelta
from keras.layers.normalization import BatchNormalization
from keras.callbacks import Callback,EarlyStopping, ModelCheckpoint
print ('Params testing: ', params)
print ('\n ')
model = Sequential()
model.add(Dense(units=params['units1'], input_dim = X_train.shape[1], kernel_initializer = "glorot_uniform"))
model.add(Activation(params['activation']))
model.add(Dropout(params['dropout1']))
model.add(BatchNormalization())
model.add(Dense(units=params['units2'], kernel_initializer = "glorot_uniform"))
model.add(Activation(params['activation']))
model.add(Dropout(params['dropout2']))
model.add(BatchNormalization())
if params['choice']['layers']== 'three':
model.add(Dense(units=params['choice']['units3'], kernel_initializer = "glorot_uniform"))
model.add(Activation(params['activation']))
model.add(Dropout(params['choice']['dropout3']))
model.add(BatchNormalization())
patience=8
else:
patience=4
model.add(Dense(3, kernel_initializer= "glorot_uniform", activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer=params['optimizer'], metrics=['accuracy'])
# To use val_loss as early stopping
call_back = [EarlyStopping(monitor='val_loss', patience=patience ),
ModelCheckpoint(filepath='best_model.h5', monitor='val_loss', save_best_only=True)]
#includes the call back object
model.fit(X_train, y_train, validation_data=(X_val, y_val),
nb_epoch=params['epochs'], batch_size=params['batch_size'], verbose = 2,
callbacks=call_back) #******
#predict the validation set
pred_val = model.predict_classes(X_val)
y_val_original = one_hot_to_indices(y_val)
score = f1_score(y_val_original, pred_val, average='weighted')
eval_score = 1-score
print("f1 score {:.3f} params {}".format(score, params))
return (eval_score)
trials = Trials()
best_hParams = fmin(fn=objective, space=space, algo=tpe.suggest, trials=trials, max_evals=2)
print (best_hParams)
Лучшие гиперпараметры из результата fmin
показаны ниже.
{'units2': 1, 'dropout1': 1, 'batch_size': 2, 'num_layers': 0, 'units1': 2, 'dropout2': 1}
Кажется, что значения являются индексом моего пространства поиска.
Кто-нибудь знает, как я могу преобразовать этот индекс в истинные параметры?Я чувствую, что что-то упустил из этого пакета.Там должен быть какой-то простой способ сделать это.Большое спасибо заранее!