应用hyperopt给keras项目自动调参

1、hyperopt干什么

这个python库可以在给定的参数空间中随机取点,每一组参数训练一个模型,最后记录和比较所有模型的表现,给出表现最好的一组参数。

它兼容大部分的机器学习任务,不需要对你的模型做什么太大的修改(只需要改一下超参数的写法,把超参数写到字典里面,例如lr改成params['lr'])。

2、hyperopt的使用

a) 安装并导入需要的程序

pip install hyperopt

from hyperopt import hp, STATUS_OK, Trials, fmin

b) 定义参数空间

space = {
    'lr':hp.loguniform('lr',-9,-5),
    'lambda_l2':hp.loguniform('lambda_l2',-5,0),
    'batch_size'hp.choice('batch_size',[8,16])
}

严格地说这里的参数指的是机器学习任务中的超参数,即训练过程中不进行梯度下降的部分。

参数空间是一个字典,在参数空间中,我定义了学习率lr,L2正则化系数lambda_l2,以及minibatch的大小batch_size。

其中,学习率和正则化系数的取值范围是一个均匀对数的范围,例如hp.loguniform('lr',-9,-5)就意味着取值范围是exp(-9)到exp(-5),指数在 [-9, -5] 之间均匀分布。注意这里确实是自然指数,不是10为底的指数。

minibatch大小的取值范围则是离散的,从给定的8和16中二选一。(你可可以把这个列表改成你需要的那些值)

除了loguniform和choice,hp中的参数空间还有:uniform(线性空间中均匀随机取值)、quniform(线性离散取值)、qloguniform等

c) 把调参的任务描述为一个以参数为输入的函数

例如,在我的参数空间中有lr, lambda_l2, batch_size这三个参数,我希望最后得到一个最小化测试集的f1指数的模型,可以写成如下的方式(我的代码其实就是训练模型并输出测试集上的f1指数,你把中间的部分改成你的训练代码就行,注意要把参数换成params['batch_size']这种形式):

def trainAmodel(params): #params={'lr':??, 'lambda_l2':??, 'batch_size':??}
    global X_train,X_test,Y_test,Y_train
    print('Params testing: ', params)
    # 创建模型 & 训练模型
    model_v1 = V1_utils.modelV1(X_train.shape[1:],params)
    opt = tensorflow.keras.optimizers.Adam(lr=params['lr'])
    model_v1.compile(loss="binary_crossentropy", metrics=['accuracy'], optimizer=opt)
    steps_per_epoch = (np.shape(X_train)[0] + params['batch_size'] - 1) // params['batch_size']
    history = model_v1.fit_generator(generator=data_generator(X_train, Y_train, params['batch_size']),
                                     steps_per_epoch=steps_per_epoch,
                                     epochs=30,
                                     verbose=0,
                                     validation_data=(X_test[::20], Y_test[::20]),
                                     )
    # 评估模型
    testres = model_v1.predict_generator(pre_generator(X_test, 4), verbose=0)
    testf1s, cache = V1_utils.fmeasure(Y_test, cvres)
    p, r = cache
    print("f1 = {}, precision = {}, recall = {}".format(testf1s, p, r))
    # 返回关心的指标(越小越好),状态
    return {
        'loss':-testf1s,
        'status':STATUS_OK
    }

注意,fmin默认是把指标越小认为表现越好,所以如果指标是f1指数、正确率这种越大越好的,可以加上负号,就变成越小越好。

另外,如果你希望在中途保存表现最好的模型,可以保存最好的表现,实时对比,如果更好就保存新的模型(我就不写了)。

d) 最后调用fmin开始跑不同参数下的模型,并保存。

trials = Trials()
best = fmin(trainAmodel, space, algo=tpe.suggest, max_evals=50, trials=trials)

import numpy as np
filename= 'model/v1/log_v1_4.npz'
np.savez(filename,trails=trials,best=best)

fmin的参数:

max_evals:要跑多少个模型,这个视你的需要,跑的越多肯多越有可能找到表现更好的模型,但是也意味着耗时增加。

algo:我还不清楚,应该是选择参数的算法?我直接用的suggest,也许选择一些算法能提高搜索效率。

3、结果

trials中会保留每一次训练的超参数、模型表现,我们可以根据这些画出模型在参数空间中的表现,帮助我们选择最后的超参数。例如我的这个结果:

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值