Scikit-learn网格搜索自定义得分对象语法

3
我希望能够使用KerasClassifier和SciKit-learn的GridSearchCV在卷积网中搜索超参数。参考MachineLearningMastery提供的优秀介绍。通常,SciKit-learn会基于“准确性”进行优化,但是我的网络运行图像分割并优化Jaccard指数。因此,我需要使用make_scorer定义自己的评分对象进行网格搜索,如make_scorerdefining your scoring strategy所述。下面的代码部分显示了我的实现,但是在model.compile(optimizer=optimizer, loss=eval_loss, metrics=(['eval_func'])处出现错误,我不知道metrics应该指定什么。默认值为“准确性”,但是在我的情况下,我认为应该是“eval_func”(如果不进行网格搜索,则有效),或者是“score”,但这两者都在此情况下无效。

请问正确的语法是什么?

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) 

这是我使用“eval_func”和“score”时遇到的错误的最后一部分:
在“C:\ Program Files \ Anaconda2 \ lib \ site-packages \ keras \ metrics.py”文件中,第216行代码出现错误。尝试从模块中获取指标时,会调用“get_from_module”函数。然而,在“C:\ Program Files \ Anaconda2 \ lib \ site-packages \ keras \ utils \ generic_utils.py”文件中,第16行代码再次出现了错误。它打印出一条异常信息:“无效度量:eval_func”。
2个回答

1
当传递给编译器时,您应该取消引用它。只有在指标属于Keras API的一部分时,Keras才会识别带引号的指标。请参见Keras.io/metrics
这是问题:
model.compile(optimizer=optimizer, loss=eval_loss, metrics=(['eval_func']) 

你应该将其修复为:

你应该将其修复为:

model.compile(optimizer=optimizer, loss=eval_loss, metrics=([eval_func])

希望它有所帮助!

这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - Mark Rotteveel
它确实有答案,因为他将回调函数用引号传递给编译方法,而没有使用引号应该可以解决这个问题。 - Snir Hordan
我认为你需要展示你的解决方案,具体说明需要做什么。目前它不是一个真正的答案,只是一条评论/提示。 - Mark Rotteveel

0

scikit-learn默认使用估计器中的得分函数(如果存在)。因此,您可以在KerasClassifier中覆盖得分函数

class MyEstimator(KerasClassifier):
    def __init__(self, **kwargs):
        super(MyEstimator, self).__init__(**kwargs)

    def score(self, X, y):
        y_pred = self.predict(X)
        return eval_func(y, y_pred)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接