I want to search hyper-parameters in a convolutional net built with Keras. For this I am using the KerasClassifier and GridSearchCV from SciKit-learn in line with a good intro that is given here MachineLearningMastery.
Typically SciKit-learn optimizes on 'accuracy', however my network runs image segmentation optimizing the Jaccard index. So I need to define my own scoring object for the grid search using make_scorer as explaned here make_scorer and here defining your scoring strategy. The code section below shows my implementation, but I am getting an error in model.compile(optimizer=optimizer, loss=eval_loss, metrics=(['eval_func']), where I do not know what to specify in metrics. Default is 'accuracy' but I would assume in my case this would be 'eval_func' (which works when not doing grid search) or 'score' but neither of these works in this case.
What is the right syntax?
def eval_func(y_true, y_pred):
'''Evaluation function dice or jaccard, set with global var JACCARD=True'''
if JACCARD:
return jaccard_index(y_true, y_pred)
else:
return dice_coef(y_true, y_pred)
def get_unet(batch_size=32, decay=0, dropout_rate=0.5, weight_constraint=0):
'''Create u-net model'''
dim = 32
inputs = Input((3, image_cols, image_rows)) # modified to take 3 color channel input
conv1 = Convolution2D(dim, 3, 3, activation='relu', border_mode='same', W_constraint=weight_constraint)(inputs)
conv1 = Convolution2D(dim, 3, 3, activation='relu', border_mode='same', W_constraint=weight_constraint)(conv1)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
pool1 = Dropout(dropout_rate)(pool1) # dropout added to all layers
... more layers ...
conv10 = Convolution2D(1, 1, 1, activation='sigmoid')(conv9)
model = Model(input=inputs, output=conv10)
optimizer = Adam(lr=LR, decay=decay)
model.compile(optimizer=optimizer, loss=eval_loss, metrics=(['eval_func'])
return model
def run_grid_search():
'''Optimize model parameters with grid search'''
... loading data ...
model = KerasClassifier(build_fn=get_unet, verbose=1, nb_epoch=NUM_EPOCH, shuffle=True)
# define grid search parameters
batch_size = [16, 32, 48]
decay = [0, 0.002, 0.004]
param_grid = dict(batch_size=batch_size, decay=decay)
# create scoring object
score = make_scorer(eval_func, greater_is_better=True)
grid = GridSearchCV(estimator=model, param_grid=param_grid, scoring=score, n_jobs=1, verbose=1)
grid_result = grid.fit(X_aug, Y_aug)
Here is the last part of the error I am getting both using 'eval_func' and 'score':
File "C:\Program Files\Anaconda2\lib\site-packages\keras\metrics.py", line 216 , in get return get_from_module(identifier, globals(), 'metric') File "C:\Program Files\Anaconda2\lib\site-packages\keras\utils\generic_utils.p y", line 16, in get_from_module str(identifier)) Exception: Invalid metric: eval_func