精华内容
下载资源
问答
  • 全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 优化的相关的知识内容可以参考 ...网格搜索GridSearchCV GridSearchCV用于系统地遍历多种参数组合,通过交叉验证确定最佳效果参数。 classskle...

    分享一个朋友的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!大家可以看看是否对自己有帮助:点击打开


    ad1.jpg

    全栈工程师开发手册 (作者:栾鹏)
    python数据挖掘系列教程

    优化的相关的知识内容可以参考
    https://blog.csdn.net/luanpeng825485697/article/details/78765923

    网格搜索GridSearchCV

    GridSearchCV用于系统地遍历多种参数组合,通过交叉验证确定最佳效果参数。

    classsklearn.model_selection.GridSearchCV(estimator,param_grid, scoring=None, fit_params=None, n_jobs=1, iid=True, refit=True,cv=None, verbose=0, pre_dispatch='2*n_jobs', error_score='raise',return_train_score=True)
    

    常用参数解读

    estimator:所使用的分类器,如estimator=RandomForestClassifier(min_samples_split=100,min_samples_leaf=20,max_depth=8,max_features='sqrt',random_state=10), 并且传入除需要确定最佳的参数之外的其他参数。每一个分类器都需要一个scoring参数,或者score方法。

    param_grid:值为字典或者列表,即需要最优化的参数的取值,param_grid =param_test1,param_test1 = {'n_estimators':range(10,71,10)}。

    scoring :准确度评价标准,默认None,这时需要使用score函数;或者如scoring=‘roc_auc’,根据所选模型不同,评价准则不同。字符串(函数名),或是可调用对象,需要其函数签名形如:scorer(estimator, X, y);如果是None,则使用estimator的误差估计函数。

    cv :交叉验证参数,默认None,使用三折交叉验证。指定fold数量,默认为3,也可以是yield训练/测试数据的生成器。

    refit :默认为True,程序将会以交叉验证训练集得到的最佳参数,重新对所有可用的训练集与开发集进行,作为最终用于性能评估的最佳模型参数。即在搜索参数结束后,用最佳参数结果再次fit一遍全部数据集。

    iid:默认True,为True时,默认为各个样本fold概率分布一致,误差估计为所有样本之和,而非各个fold的平均。

    verbose:日志冗长度,int:冗长度,0:不输出训练过程,1:偶尔输出,>1:对每个子模型都输出。

    n_jobs: 并行数,int:个数,-1:跟CPU核数一致, 1:默认值。

    pre_dispatch:指定总共分发的并行任务数。当n_jobs大于1时,数据将在每个运行点进行复制,这可能导致OOM,而设置pre_dispatch参数,则可以预先划分总共的job数量,使数据最多被复制pre_dispatch次

    随机参数优化RandomizedSearchCV

    尽管使用参数设置的网格法是目前最广泛使用的参数优化方法, 其他搜索方法也具有更有利的性能。 RandomizedSearchCV 实现了对参数的随机搜索, 其中每个设置都是从可能的参数值的分布中进行取样。 这对于穷举搜索有两个主要优势:

    • 可以选择独立于参数个数和可能值的预算
    • 添加不影响性能的参数不会降低效率

    指定如何取样的参数是使用字典完成的, 非常类似于为 GridSearchCV 指定参数。 此外, 通过 n_iter 参数指定计算预算, 即取样候选项数或取样迭代次数。 对于每个参数, 可以指定在可能值上的分布或离散选择的列表 (均匀取样):

    {'C': scipy.stats.expon(scale=100), 'gamma': scipy.stats.expon(scale=.1),
      'kernel': ['rbf'], 'class_weight':['balanced', None]}
    

    搜索的输出值

    cv_results_:给出不同参数情况下的评价结果的记录

    best_params_:描述了已取得最佳结果的参数的组合

    best_score_:成员提供优化过程期间观察到的最好的评分

    from sklearn.datasets import load_iris  # 自带的样本数据集
    from sklearn.neighbors import KNeighborsClassifier  # 要估计的是knn里面的参数,包括k的取值和样本权重分布方式
    import matplotlib.pyplot as plt  # 可视化绘图
    from sklearn.model_selection import GridSearchCV,RandomizedSearchCV  # 网格搜索和随机搜索
    
    iris = load_iris()
    
    X = iris.data  # 150个样本,4个属性
    y = iris.target # 150个类标号
    
    k_range = range(1, 31)  # 优化参数k的取值范围
    weight_options = ['uniform', 'distance']  # 代估参数权重的取值范围。uniform为统一取权值,distance表示距离倒数取权值
    # 下面是构建parameter grid,其结构是key为参数名称,value是待搜索的数值列表的一个字典结构
    param_grid = {'n_neighbors':k_range,'weights':weight_options}  # 定义优化参数字典,字典中的key值必须是分类算法的函数的参数名
    print(param_grid)
    
    knn = KNeighborsClassifier(n_neighbors=5)  # 定义分类算法。n_neighbors和weights的参数名称和param_grid字典中的key名对应
    
    
    # ================================网格搜索=======================================
    # 这里GridSearchCV的参数形式和cross_val_score的形式差不多,其中param_grid是parameter grid所对应的参数
    # GridSearchCV中的n_jobs设置为-1时,可以实现并行计算(如果你的电脑支持的情况下)
    grid = GridSearchCV(estimator = knn, param_grid = param_grid, cv=10, scoring='accuracy') #针对每个参数对进行了10次交叉验证。scoring='accuracy'使用准确率为结果的度量指标。可以添加多个度量指标
    grid.fit(X, y)
    
    print('网格搜索-度量记录:',grid.cv_results_)  # 包含每次训练的相关信息
    print('网格搜索-最佳度量值:',grid.best_score_)  # 获取最佳度量值
    print('网格搜索-最佳参数:',grid.best_params_)  # 获取最佳度量值时的代定参数的值。是一个字典
    print('网格搜索-最佳模型:',grid.best_estimator_)  # 获取最佳度量时的分类器模型
    
    
    # 使用获取的最佳参数生成模型,预测数据
    knn = KNeighborsClassifier(n_neighbors=grid.best_params_['n_neighbors'], weights=grid.best_params_['weights'])  # 取出最佳参数进行建模
    knn.fit(X, y)  # 训练模型
    print(knn.predict([[3, 5, 4, 2]]))  # 预测新对象
    
    
    
    # =====================================随机搜索===========================================
    rand = RandomizedSearchCV(knn, param_grid, cv=10, scoring='accuracy', n_iter=10, random_state=5)  #
    rand.fit(X, y)
    
    print('随机搜索-度量记录:',grid.cv_results_)  # 包含每次训练的相关信息
    print('随机搜索-最佳度量值:',grid.best_score_)  # 获取最佳度量值
    print('随机搜索-最佳参数:',grid.best_params_)  # 获取最佳度量值时的代定参数的值。是一个字典
    print('随机搜索-最佳模型:',grid.best_estimator_)  # 获取最佳度量时的分类器模型
    
    
    # 使用获取的最佳参数生成模型,预测数据
    knn = KNeighborsClassifier(n_neighbors=grid.best_params_['n_neighbors'], weights=grid.best_params_['weights'])  # 取出最佳参数进行建模
    knn.fit(X, y)  # 训练模型
    print(knn.predict([[3, 5, 4, 2]]))  # 预测新对象
    
    
    # =====================================自定义度量===========================================
    from sklearn import metrics
    # 自定义度量函数
    def scorerfun(estimator, X, y):
        y_pred = estimator.predict(X)
        return metrics.accuracy_score(y, y_pred)
    
    rand = RandomizedSearchCV(knn, param_grid, cv=10, scoring='accuracy', n_iter=10, random_state=5)  #
    rand.fit(X, y)
    
    print('随机搜索-最佳度量值:',grid.best_score_)  # 获取最佳度量值
    
    

    当你的调节参数是连续的,比如回归问题的正则化参数,有必要指定一个连续分布而不是可能值的列表,这样RandomizeSearchCV就可以执行更好的grid search。

    Scoring Function Comment
    Classification
    ‘accuracy’ metrics.accuracy_score
    ‘average_precision’ metrics.average_precision_score
    ‘f1’ metrics.f1_score for binary targets
    ‘f1_micro’ metrics.f1_score micro-averaged
    ‘f1_macro’ metrics.f1_score macro-averaged
    ‘f1_weighted’ metrics.f1_score weighted average
    ‘f1_samples’ metrics.f1_score by multilabel sample
    ‘neg_log_loss’ metrics.log_loss requires predict_proba support
    ‘precision’ etc. metrics.precision_score suffixes apply as with ‘f1’
    ‘recall’ etc. metrics.recall_score suffixes apply as with ‘f1’
    ‘roc_auc’ metrics.roc_auc_score
    Clustering
    ‘adjusted_rand_score’ metrics.adjusted_rand_score
    ‘adjusted_mutual_info_score’ metrics.adjusted_mutual_info_score
    ‘completeness_score’ metrics.completeness_score
    ‘fowlkes_mallows_score’ metrics.fowlkes_mallows_score
    ‘homogeneity_score’ metrics.homogeneity_score
    ‘mutual_info_score’ metrics.mutual_info_score
    ‘normalized_mutual_info_score’ metrics.normalized_mutual_info_score
    ‘v_measure_score’ metrics.v_measure_score
    Regression
    ‘explained_variance’ metrics.explained_variance_score
    ‘neg_mean_absolute_error’ metrics.mean_absolute_error
    ‘neg_mean_squared_error’ metrics.mean_squared_error
    ‘neg_mean_squared_log_error’ metrics.mean_squared_log_error
    ‘neg_median_absolute_error’ metrics.median_absolute_error
    ‘r2’ metrics.r2_score

    如果没有我们想要的度量字符串表达,我们可以自定义度量函数,将函数名设置为scoring参数的值。函数名必须为

    # 自定义度量函数
    def scorerfun(estimator, X, y):
    	。。。
        return 。。
    

    python调参神器hyperopt

    Hyperopt库为python中的模型选择和参数优化提供了算法和并行方案。

    给一段代码,一看就明白

    from sklearn.model_selection import cross_val_score
    import pickle
    from hyperopt import fmin, tpe, hp,space_eval,rand,Trials,partial,STATUS_OK
    from xgboost.sklearn import XGBClassifier
    import xgboost as xgb
    
    # 定义一个目标函数,接受一个变量,计算后返回一个函数的损失值,
    def GBM(argsDict):
        max_depth = argsDict["max_depth"] + 5
        n_estimators = argsDict['n_estimators'] * 5 + 50
        learning_rate = argsDict["learning_rate"] * 0.02 + 0.05
        subsample = argsDict["subsample"] * 0.1 + 0.7
        min_child_weight = argsDict["min_child_weight"]+1
        global attr_train,label_train
    
        gbm = xgb.XGBClassifier(nthread=4,    #进程数
                                max_depth=max_depth,  #最大深度
                                n_estimators=n_estimators,   #树的数量
                                learning_rate=learning_rate, #学习率
                                subsample=subsample,      #采样数
                                min_child_weight=min_child_weight,   #孩子数
                                max_delta_step = 10,  #10步不降则停止
                                objective="binary:logistic")
    
        metric = cross_val_score(gbm,attr_train,label_train,cv=5,scoring="roc_auc").mean()
        print(metric)
        return -metric
    
    # 定义参数的搜索空间
    
    space = {"max_depth":hp.randint("max_depth",15),
             "n_estimators":hp.randint("n_estimators",10),  #[0,1,2,3,4,5] -> [50,]
             "learning_rate":hp.randint("learning_rate",6),  #[0,1,2,3,4,5] -> 0.05,0.06
             "subsample":hp.randint("subsample",4),#[0,1,2,3] -> [0.7,0.8,0.9,1.0]
             "min_child_weight":hp.randint("min_child_weight",5), #
            }
    algo = partial(tpe.suggest,n_startup_jobs=1)  # 定义随机搜索算法。搜索算法本身也有内置的参数决定如何去优化目标函数
    best = fmin(GBM,space,algo=algo,max_evals=4)  # 对定义的参数范围,调用搜索算法,对模型进行搜索
    
    print(best)
    print(GBM(best))
    

    关于参数空间的设置,比如优化函数q,输入fmin(q,space=hp.uniform(‘a’,0,1))
    hp.uniform函数的第一个参数是标签,每个超参数在参数空间内必须具有独一无二的标签。

    • hp.choice返回一个选项,选项可以是list或者tuple.options可以是嵌套的表达式,用于组成条件参数。
    • hp.pchoice(label,p_options)以一定的概率返回一个p_options的一个选项。这个选项使得函数在搜索过程中对每个选项的可能性不均匀。
    • hp.uniform(label,low,high)参数在low和high之间均匀分布。
    • hp.quniform(label,low,high,q),参数的取值是round(uniform(low,high)/q)*q,适用于那些离散的取值。
    • hp.loguniform(label,low,high)绘制exp(uniform(low,high)),变量的取值范围是[exp(low),exp(high)]
    • hp.randint(label,upper) 返回一个在[0,upper)前闭后开的区间内的随机整数。
    展开全文
  • 参数优化是深度学习中的重要组成部分。...在这篇文章中,你会了解到如何使用scikit-learn python机器学习库中的网格搜索功能调整Keras深度学习模型中的超参数。 阅读本文后,你就会了解: 如何包装...

    转自:http://www.sohu.com/a/111078896_163588

    超参数优化是深度学习中的重要组成部分。其原因在于,神经网络是公认的难以配置,而又有很多参数需要设置。最重要的是,个别模型的训练非常缓慢。

    在这篇文章中,你会了解到如何使用scikit-learn python机器学习库中的网格搜索功能调整Keras深度学习模型中的超参数。

    阅读本文后,你就会了解:

    如何包装Keras模型以便在scikit-learn中使用,以及如何使用网格搜索。

    如何网格搜索常见的神经网络参数,如学习速率、 dropout 率、epochs 和神经元数量。

    如何设计自己的超参数优化实验。

    概述

    本文主要想为大家介绍如何使用scikit-learn网格搜索功能,并给出一套代码实例。你可以将代码复制粘贴到自己的项目中,作为项目起始。

    下文所涉及的议题列表:

    如何在scikit-learn模型中使用Keras。

    如何在scikit-learn模型中使用网格搜索。

    如何调优批尺寸和训练epochs。

    如何调优优化算法。

    如何调优学习率和动量因子。

    如何确定网络权值初始值。

    如何选择神经元激活函数。

    如何调优Dropout正则化。

    如何确定隐藏层中的神经元的数量。

    如何在scikit-learn模型中使用Keras

    通过用KerasClassifier或KerasRegressor类包装Keras模型,可将其用于scikit-learn。

    要使用这些包装,必须定义一个函数,以便按顺序模式创建并返回Keras,然后当构建KerasClassifier类时,把该函数传递给build_fn参数。

    例如:

    KerasClassifier类的构建器为可以采取默认参数,并将其被传递给model.fit()的调用函数,比如 epochs数目和批尺寸(batch size)。

    例如:

    KerasClassifier类的构造也可以使用新的参数,使之能够传递给自定义的create_model()函数。这些新的参数,也必须由使用默认参数的 create_model() 函数的签名定义。

    例如:

    您可以在Keras API文档中,了解到更多关于scikit-learn包装器的知识。

    如何在scikit-learn中使用网格搜索

    网格搜索(grid search)是一项模型超参数优化技术。

    在scikit-learn中,该技术由GridSearchCV类提供。

    当构造该类时,你必须提供超参数字典,以便用来评价param_grid参数。这是模型参数名称和大量列值的示意图。

    默认情况下,精确度是优化的核心,但其他核心可指定用于GridSearchCV构造函数的score参数。

    默认情况下,网格搜索只使用一个线程。在GridSearchCV构造函数中,通过将 n_jobs参数设置为-1,则进程将使用计算机上的所有内核。这取决于你的Keras后端,并可能干扰主神经网络的训练过程。

    当构造并评估一个模型中各个参数的组合时,GridSearchCV会起作用。使用交叉验证评估每个单个模型,且默认使用3层交叉验证,尽管通过将cv参数指定给 GridSearchCV构造函数时,有可能将其覆盖。

    下面是定义一个简单的网格搜索示例:

    一旦完成,你可以访问网格搜索的输出,该输出来自结果对象,由grid.fit()返回。best_score_成员提供优化过程期间观察到的最好的评分, best_params_描述了已取得最佳结果的参数的组合。

    您可以在scikit-learn API文档中了解更多关于GridSearchCV类的知识。

    问题描述

    现在我们知道了如何使用scikit-learn 的Keras模型,如何使用scikit-learn 的网格搜索。现在一起看看下面的例子。

    所有的例子都将在一个小型的标准机器学习数据集上来演示,该数据集被称为Pima Indians onset of diabetes 分类数据集。该小型数据集包括了所有容易工作的数值属性。

    下载数据集,并把它放置在你目前工作目录下,命名为:pima-indians-diabetes.csv。

    当我们按照本文中的例子进行,能够获得最佳参数。因为参数可相互影响,所以这不是网格搜索的最佳方法,但出于演示目的,它是很好的方法。

    注意并行化网格搜索

    所有示例的配置为了实现并行化(n_jobs=-1)。

    如果显示像下面这样的错误:

    结束进程,并修改代码,以便不并行地执行网格搜索,设置n_jobs=1。

    如何调优批尺寸和训练epochs

    在第一个简单的例子中,当调整网络时,我们着眼于调整批尺寸和训练epochs。

    迭代梯度下降的批尺寸大小是权重更新之前显示给网络的模式数量。它也是在网络训练的优选法,定义一次读取的模式数并保持在内存中。

    训练epochs是训练期间整个训练数据集显示给网络的次数。有些网络对批尺寸大小敏感,如LSTM复发性神经网络和卷积神经网络。

    在这里,我们将以20的步长,从10到100逐步评估不同的微型批尺寸。

    完整代码如下:

    运行之后输出如下:

    结果表明,ATOM优化算法结果最好,精确度约为70%。

    如何优化学习速率和动量因子?

    预先选择一个优化算法来训练你的网络和参数调整是十分常见的。目前,最常用的优化算法是普通的随机梯度下降法(Stochastic Gradient Descent,SGD),因为它十分易于理解。在本例中,我们将着眼于优化SGD的学习速率和动量因子(momentum)。

    学习速率控制每批(batch)结束时更新的权重,动量因子控制上次权重的更新对本次权重更新的影响程度。

    我们选取了一组较小的学习速率和动量因子的取值范围:从0.2到0.8,步长为0.2,以及0.9(实际中常用参数值)。

    一般来说,在优化算法中包含epoch的数目是一个好主意,因为每批(batch)学习量(学习速率)、每个 epoch更新的数目(批尺寸)和 epoch的数量之间都具有相关性。

    完整代码如下:

    运行之后输出如下:

    我们可以看到,当采用均匀权值初始化方案(uniform weight initialization )时取得最好的结果,可以实现约72%的性能。

    如何选择神经元激活函数

    激活函数控制着单个神经元的非线性以及何时激活。

    通常来说,整流器(rectifier)的激活功能是最受欢迎的,但应对不同的问题, sigmoid函数和tanh 函数可能是更好的选择。

    在本例中,我们将探讨、评估、比较Keras提供的不同类型的激活函数。我们仅在隐层中使用这些函数。考虑到二元分类问题,需要在输出层使用sigmoid激活函数。

    通常而言,为不同范围的传递函数准备数据是一个好主意,但在本例中我们不会这么做。

    完整代码如下:

    运行之后输出如下:

    令人惊讶的是(至少对我来说是),“线性(linear)”激活函数取得了最好的效果,准确率约为72%。

    如何调优Dropout正则化

    在本例中,我们将着眼于调整正则化中的dropout速率,以期限制过拟合(overfitting)和提高模型的泛化能力。为了得到较好的结果,dropout最好结合一个如最大范数约束之类的权值约束。

    了解更多dropout在深度学习框架Keras的使用请查看下面这篇文章:

    基于Keras/Python的深度学习模型Dropout正则项

    它涉及到拟合dropout率和权值约束。我们选定dropout percentages取值范围是:0.0-0.9(1.0无意义);最大范数权值约束( maxnorm weight constraint)的取值范围是0-5。

    完整代码如下:

    运行之后输出如下:

    Best: 0.723958 using {'dropout_rate': 0.2, 'weight_constraint': 4}

    0.696615 (0.031948) with: {'dropout_rate': 0.0, 'weight_constraint': 1}

    0.696615 (0.031948) with: {'dropout_rate': 0.0, 'weight_constraint': 2}

    0.691406 (0.026107) with: {'dropout_rate': 0.0, 'weight_constraint': 3}

    0.708333 (0.009744) with: {'dropout_rate': 0.0, 'weight_constraint': 4}

    0.708333 (0.009744) with: {'dropout_rate': 0.0, 'weight_constraint': 5}

    0.710937 (0.008438) with: {'dropout_rate': 0.1, 'weight_constraint': 1}

    0.709635 (0.007366) with: {'dropout_rate': 0.1, 'weight_constraint': 2}

    0.709635 (0.007366) with: {'dropout_rate': 0.1, 'weight_constraint': 3}

    0.695312 (0.012758) with: {'dropout_rate': 0.1, 'weight_constraint': 4}

    0.695312 (0.012758) with: {'dropout_rate': 0.1, 'weight_constraint': 5}

    0.701823 (0.017566) with: {'dropout_rate': 0.2, 'weight_constraint': 1}

    0.710938 (0.009568) with: {'dropout_rate': 0.2, 'weight_constraint': 2}

    0.710938 (0.009568) with: {'dropout_rate': 0.2, 'weight_constraint': 3}

    0.723958 (0.027126) with: {'dropout_rate': 0.2, 'weight_constraint': 4}

    0.718750 (0.030425) with: {'dropout_rate': 0.2, 'weight_constraint': 5}

    0.721354 (0.032734) with: {'dropout_rate': 0.3, 'weight_constraint': 1}

    0.707031 (0.036782) with: {'dropout_rate': 0.3, 'weight_constraint': 2}

    0.707031 (0.036782) with: {'dropout_rate': 0.3, 'weight_constraint': 3}

    0.694010 (0.019225) with: {'dropout_rate': 0.3, 'weight_constraint': 4}

    0.709635 (0.006639) with: {'dropout_rate': 0.3, 'weight_constraint': 5}

    0.704427 (0.008027) with: {'dropout_rate': 0.4, 'weight_constraint': 1}

    0.717448 (0.031304) with: {'dropout_rate': 0.4, 'weight_constraint': 2}

    0.718750 (0.030425) with: {'dropout_rate': 0.4, 'weight_constraint': 3}

    0.718750 (0.030425) with: {'dropout_rate': 0.4, 'weight_constraint': 4}

    0.722656 (0.029232) with: {'dropout_rate': 0.4, 'weight_constraint': 5}

    0.720052 (0.028940) with: {'dropout_rate': 0.5, 'weight_constraint': 1}

    0.703125 (0.009568) with: {'dropout_rate': 0.5, 'weight_constraint': 2}

    0.716146 (0.029635) with: {'dropout_rate': 0.5, 'weight_constraint': 3}

    0.709635 (0.008027) with: {'dropout_rate': 0.5, 'weight_constraint': 4}

    0.703125 (0.011500) with: {'dropout_rate': 0.5, 'weight_constraint': 5}

    0.707031 (0.017758) with: {'dropout_rate': 0.6, 'weight_constraint': 1}

    0.701823 (0.018688) with: {'dropout_rate': 0.6, 'weight_constraint': 2}

    0.701823 (0.018688) with: {'dropout_rate': 0.6, 'weight_constraint': 3}

    0.690104 (0.027498) with: {'dropout_rate': 0.6, 'weight_constraint': 4}

    0.695313 (0.022326) with: {'dropout_rate': 0.6, 'weight_constraint': 5}

    0.697917 (0.014382) with: {'dropout_rate': 0.7, 'weight_constraint': 1}

    0.697917 (0.014382) with: {'dropout_rate': 0.7, 'weight_constraint': 2}

    0.687500 (0.008438) with: {'dropout_rate': 0.7, 'weight_constraint': 3}

    0.704427 (0.011201) with: {'dropout_rate': 0.7, 'weight_constraint': 4}

    0.696615 (0.016367) with: {'dropout_rate': 0.7, 'weight_constraint': 5}

    0.680990 (0.025780) with: {'dropout_rate': 0.8, 'weight_constraint': 1}

    0.699219 (0.019401) with: {'dropout_rate': 0.8, 'weight_constraint': 2}

    0.701823 (0.015733) with: {'dropout_rate': 0.8, 'weight_constraint': 3}

    0.684896 (0.023510) with: {'dropout_rate': 0.8, 'weight_constraint': 4}

    0.696615 (0.017566) with: {'dropout_rate': 0.8, 'weight_constraint': 5}

    0.653646 (0.034104) with: {'dropout_rate': 0.9, 'weight_constraint': 1}

    0.677083 (0.012075) with: {'dropout_rate': 0.9, 'weight_constraint': 2}

    0.679688 (0.013902) with: {'dropout_rate': 0.9, 'weight_constraint': 3}

    0.669271 (0.017566) with: {'dropout_rate': 0.9, 'weight_constraint': 4}

    0.669271 (0.012075) with: {'dropout_rate': 0.9, 'weight_constraint': 5}

    我们可以看到,当 dropout率为0.2%、最大范数权值约束( maxnorm weight constraint)取值为4时,可以取得准确率约为72%的最好结果。

    如何确定隐藏层中的神经元的数量

    每一层中的神经元数目是一个非常重要的参数。通常情况下,一层之中的神经元数目控制着网络的代表性容量,至少是拓扑结构某一节点的容量。

    此外,一般来说,一个足够大的单层网络是接近于任何神经网络的,至少在理论上成立。

    在本例中,我们将着眼于调整单个隐藏层神经元的数量。取值范围是:1—30,步长为5。

    一个大型网络要求更多的训练,此外,至少批尺寸(batch size)和 epoch的数量应该与神经元的数量优化。

    完整代码如下:

    运行之后输出如下:

    我们可以看到,当网络中隐藏层内神经元的个数为5时,可以达到最佳结果,准确性约为71%。

    超参数优化的小技巧

    本节罗列了一些神经网络超参数调整时常用的小技巧。

    K层交叉检验(k-fold Cross Validation),你可以看到,本文中的不同示例的结果存在一些差异。使用了默认的3层交叉验证,但也许K=5或者K=10时会更加稳定。认真选择您的交叉验证配置,以确保您的结果是稳定的。

    审查整个网络。不要只注意最好的结果,审查整个网络的结果,并寻找支持配置决策的趋势。

    并行(Parallelize),如果可以,使用全部的CPU,神经网络训练十分缓慢,并且我们经常想尝试不同的参数。参考AWS实例。

    使用数据集的样本。由于神经网路的训练十分缓慢,尝试训练在您训练数据集中较小样本,得到总方向的一般参数即可,并非追求最佳的配置。

    从粗网格入手。从粗粒度网格入手,并且一旦缩小范围,就细化为细粒度网格。

    不要传递结果。结果通常是特定问题。尽量避免在每一个新问题上都采用您最喜欢的配置。你不可能将一个问题的最佳结果转移到另一个问题之上。相反地,你应该归纳更广泛的趋势,例如层的数目或者是参数之间的关系。

    再现性(Reproducibility)是一个问题。在NumPy中,尽管我们为随机数发生器设置了种子,但结果并非百分百重现。网格搜索wrapped Keras模型将比本文中所示Keras模型展现更多可重复性(reproducibility)。

    总结

    在这篇文章中,你可以了解到如何使用Keras和scikit-learn/Python调优神经网络中的超参数。

    尤其是可以学到:

    如何包装Keras模型以便在scikit-learn使用以及如何使用网格搜索。

    如何网格搜索Keras 模型中不同标准的神经网络参数。

    如何设计自己的超参数优化实验。

    展开全文
  • 参考链接: Python中的网格搜索优化算法 分享一个朋友的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!大家可以看看是否对自己有帮助:点击打开 全栈工程师开发手册 (作者:栾鹏) python数据挖掘...

    参考链接: Python中的网格搜索优化算法

    分享一个朋友的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!大家可以看看是否对自己有帮助:点击打开 

       

     

     全栈工程师开发手册 (作者:栾鹏)  python数据挖掘系列教程 

     

    优化的相关的知识内容可以参考 https://blog.csdn.net/luanpeng825485697/article/details/78765923 

    网格搜索GridSearchCV 

    GridSearchCV用于系统地遍历多种参数组合,通过交叉验证确定最佳效果参数。 

    classsklearn.model_selection.GridSearchCV

    展开全文
  • 在这篇文章中,你会了解到如何使用scikit-learn python机器学习库中的网格搜索功能调整Keras深度学习模型中的超参数。阅读本文后,你就会了解:如何包装Keras模型以便在scikit-learn中使用,以及如何使用网格搜索。 ...

    超参数优化是深度学习中的重要组成部分。其原因在于,神经网络是公认的难以配置,而又有很多参数需要设置。最重要的是,个别模型的训练非常缓慢。

    在这篇文章中,你会了解到如何使用scikit-learn python机器学习库中的网格搜索功能调整Keras深度学习模型中的超参数。

    阅读本文后,你就会了解:

    如何包装Keras模型以便在scikit-learn中使用,以及如何使用网格搜索。
    如何网格搜索常见的神经网络参数,如学习速率、 dropout 率、epochs 和神经元数量。
    如何设计自己的超参数优化实验。

    概述

    本文主要想为大家介绍如何使用scikit-learn网格搜索功能,并给出一套代码实例。你可以将代码复制粘贴到自己的项目中,作为项目起始。

    下文所涉及的议题列表:

    1. 如何在scikit-learn模型中使用Keras。
    2. 如何在scikit-learn模型中使用网格搜索。
    3. 如何调优批尺寸和训练epochs。
    4. 如何调优优化算法。
    5. 如何调优学习率和动量因子。
    6. 如何确定网络权值初始值。
    7. 如何选择神经元激活函数。
    8. 如何调优Dropout正则化。
    9. 如何确定隐藏层中的神经元的数量。

    如何在scikit-learn模型中使用Keras

    通过用KerasClassifier或KerasRegressor类包装Keras模型,可将其用于scikit-learn。

    要使用这些包装,必须定义一个函数,以便按顺序模式创建并返回Keras,然后当构建KerasClassifier类时,把该函数传递给build_fn参数。

    例如:

    def create_model():
        ...
        return model
    

    model = KerasClassifier(build_fn=create_model)
    KerasClassifier类的构建器为可以采取默认参数,并将其被传递给model.fit()的调用函数,比如 epochs数目和批尺寸(batch size)。

    例如:

    def create_model():
        ...
        return model

    model = KerasClassifier(build_fn=create_model, nb_epoch=10)
    KerasClassifier类的构造也可以使用新的参数,使之能够传递给自定义的create_model()函数。这些新的参数,也必须由使用默认参数的 create_model() 函数的签名定义。

    例如:

    def create_model(dropout_rate=0.0):
        ...
        return model

    model = KerasClassifier(build_fn=create_model, dropout_rate=0.2)
    您可以在Keras API文档中,了解到更多关于scikit-learn包装器的知识。

    如何在scikit-learn模型中使用网格搜索

    网格搜索(grid search)是一项模型超参数优化技术。

    在scikit-learn中,该技术由GridSearchCV类提供。

    当构造该类时,你必须提供超参数字典,以便用来评价param_grid参数。这是模型参数名称和大量列值的示意图。

    默认情况下,精确度是优化的核心,但其他核心可指定用于GridSearchCV构造函数的score参数。

    默认情况下,网格搜索只使用一个线程。在GridSearchCV构造函数中,通过将 n_jobs参数设置为-1,则进程将使用计算机上的所有内核。这取决于你的Keras后端,并可能干扰主神经网络的训练过程。

    当构造并评估一个模型中各个参数的组合时,GridSearchCV会起作用。使用交叉验证评估每个单个模型,且默认使用3层交叉验证,尽管通过将cv参数指定给 GridSearchCV构造函数时,有可能将其覆盖。

    下面是定义一个简单的网格搜索示例:

    param_grid = dict(nb_epochs=[10,20,30])
    grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1)
    grid_result = grid.fit(X, Y)

    一旦完成,你可以访问网格搜索的输出,该输出来自结果对象,由grid.fit()返回。best_score_成员提供优化过程期间观察到的最好的评分, best_params_描述了已取得最佳结果的参数的组合。

    您可以在scikit-learn API文档中了解更多关于GridSearchCV类的知识。

    问题描述
    现在我们知道了如何使用scikit-learn 的Keras模型,如何使用scikit-learn 的网格搜索。现在一起看看下面的例子。

    所有的例子都将在一个小型的标准机器学习数据集上来演示,该数据集被称为Pima Indians onset of diabetes 分类数据集。该小型数据集包括了所有容易工作的数值属性。

    下载数据集,并把它放置在你目前工作目录下,命名为:pima-indians-diabetes.csv。

    当我们按照本文中的例子进行,能够获得最佳参数。因为参数可相互影响,所以这不是网格搜索的最佳方法,但出于演示目的,它是很好的方法。

    注意并行化网格搜索
    所有示例的配置为了实现并行化(n_jobs=-1)。

    如果显示像下面这样的错误:

    INFO (theano.gof.compilelock): Waiting for existing lock by process ‘55614’ (I am process ‘55613’)
    INFO (theano.gof.compilelock): To manually release the lock, delete …
    结束进程,并修改代码,以便不并行地执行网格搜索,设置n_jobs=1。

    如何调优批尺寸和训练epochs

    在第一个简单的例子中,当调整网络时,我们着眼于调整批尺寸和训练epochs。

    迭代梯度下降的批尺寸大小是权重更新之前显示给网络的模式数量。它也是在网络训练的优选法,定义一次读取的模式数并保持在内存中。

    训练epochs是训练期间整个训练数据集显示给网络的次数。有些网络对批尺寸大小敏感,如LSTM复发性神经网络和卷积神经网络。

    在这里,我们将以20的步长,从10到100逐步评估不同的微型批尺寸。

    完整代码如下:

    #Use scikit-learn to grid search the batch size and epochs
    import numpy
    from sklearn.grid_search import GridSearchCV
    from keras.models import Sequential
    from keras.layers import Dense
    from keras.wrappers.scikit_learn import KerasClassifier
    # Function to create model, required for KerasClassifier
    def create_model():
        # create model
        model = Sequential()
        model.add(Dense(12, input_dim=8, activation='relu'))
        model.add(Dense(1, activation='sigmoid'))
        # Compile model
        model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
        return model
    # fix random seed for reproducibility
    seed = 7
    numpy.random.seed(seed)
    # load dataset
    dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
    # split into input (X) and output (Y) variables
    X = dataset[:,0:8]
    Y = dataset[:,8]
    # create model
    model = KerasClassifier(build_fn=create_model, verbose=0)
    # define the grid search parameters
    batch_size = [10, 20, 40, 60, 80, 100]
    epochs = [10, 50, 100]
    param_grid = dict(batch_size=batch_size, nb_epoch=epochs)
    grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1)
    grid_result = grid.fit(X, Y)
    # summarize results
    print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
    for params, mean_score, scores in grid_result.grid_scores_:
        print("%f (%f) with: %r" % (scores.mean(), scores.std(), params))

    运行之后输出如下:

    Best: 0.686198 using {'nb_epoch': 100, 'batch_size': 20}
    0.348958 (0.024774) with: {'nb_epoch': 10, 'batch_size': 10}
    0.348958 (0.024774) with: {'nb_epoch': 50, 'batch_size': 10}
    0.466146 (0.149269) with: {'nb_epoch': 100, 'batch_size': 10}
    0.647135 (0.021236) with: {'nb_epoch': 10, 'batch_size': 20}
    0.660156 (0.014616) with: {'nb_epoch': 50, 'batch_size': 20}
    0.686198 (0.024774) with: {'nb_epoch': 100, 'batch_size': 20}
    0.489583 (0.075566) with: {'nb_epoch': 10, 'batch_size': 40}
    0.652344 (0.019918) with: {'nb_epoch': 50, 'batch_size': 40}
    0.654948 (0.027866) with: {'nb_epoch': 100, 'batch_size': 40}
    0.518229 (0.032264) with: {'nb_epoch': 10, 'batch_size': 60}
    0.605469 (0.052213) with: {'nb_epoch': 50, 'batch_size': 60}
    0.665365 (0.004872) with: {'nb_epoch': 100, 'batch_size': 60}
    0.537760 (0.143537) with: {'nb_epoch': 10, 'batch_size': 80}
    0.591146 (0.094954) with: {'nb_epoch': 50, 'batch_size': 80}
    0.658854 (0.054904) with: {'nb_epoch': 100, 'batch_size': 80}
    0.402344 (0.107735) with: {'nb_epoch': 10, 'batch_size': 100}
    0.652344 (0.033299) with: {'nb_epoch': 50, 'batch_size': 100}
    0.542969 (0.157934) with: {'nb_epoch': 100, 'batch_size': 100}

    我们可以看到,批尺寸为20、100 epochs能够获得最好的结果,精确度约68%。

    #

    如何调优训练优化算法


    Keras提供了一套最先进的不同的优化算法。

    在这个例子中,我们调整用来训练网络的优化算法,每个都用默认参数。

    这个例子有点奇怪,因为往往你会先选择一种方法,而不是将重点放在调整问题参数上(参见下一个示例)。

    在这里,我们将评估Keras API支持的整套优化算法。

    完整代码如下:

    # Use scikit-learn to grid search the batch size and epochs
    import numpy
    from sklearn.grid_search import GridSearchCV
    from keras.models import Sequential
    from keras.layers import Dense
    from keras.wrappers.scikit_learn import KerasClassifier
    # Function to create model, required for KerasClassifier
    def create_model(optimizer='adam'):
        # create model
        model = Sequential()
        model.add(Dense(12, input_dim=8, activation='relu'))
        model.add(Dense(1, activation='sigmoid'))
        # Compile model
        model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])
        return model
    # fix random seed for reproducibility
    seed = 7
    numpy.random.seed(seed)
    # load dataset
    dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
    # split into input (X) and output (Y) variables
    X = dataset[:,0:8]
    Y = dataset[:,8]
    # create model
    model = KerasClassifier(build_fn=create_model, nb_epoch=100, batch_size=10, verbose=0)
    # define the grid search parameters
    optimizer = ['SGD', 'RMSprop', 'Adagrad', 'Adadelta', 'Adam', 'Adamax', 'Nadam']
    param_grid = dict(optimizer=optimizer)
    grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1)
    grid_result = grid.fit(X, Y)
    # summarize results
    print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
    for params, mean_score, scores in grid_result.grid_scores_:
        print("%f (%f) with: %r" % (scores.mean(), scores.std(), params))

    运行之后输出如下:

    Best: 0.704427 using {'optimizer': 'Adam'}
    0.348958 (0.024774) with: {'optimizer': 'SGD'}
    0.348958 (0.024774) with: {'optimizer': 'RMSprop'}
    0.471354 (0.156586) with: {'optimizer': 'Adagrad'}
    0.669271 (0.029635) with: {'optimizer': 'Adadelta'}
    0.704427 (0.031466) with: {'optimizer': 'Adam'}
    0.682292 (0.016367) with: {'optimizer': 'Adamax'}
    0.703125 (0.003189) with: {'optimizer': 'Nadam'}

    结果表明,ATOM优化算法结果最好,精确度约为70%。

    如何优化学习速率和动量因子?

    预先选择一个优化算法来训练你的网络和参数调整是十分常见的。目前,最常用的优化算法是普通的随机梯度下降法(Stochastic Gradient Descent,SGD),因为它十分易于理解。在本例中,我们将着眼于优化SGD的学习速率和动量因子(momentum)。

    学习速率控制每批(batch)结束时更新的权重,动量因子控制上次权重的更新对本次权重更新的影响程度。

    我们选取了一组较小的学习速率和动量因子的取值范围:从0.2到0.8,步长为0.2,以及0.9(实际中常用参数值)。

    一般来说,在优化算法中包含epoch的数目是一个好主意,因为每批(batch)学习量(学习速率)、每个 epoch更新的数目(批尺寸)和 epoch的数量之间都具有相关性。

    完整代码如下:

    # Use scikit-learn to grid search the learning rate and momentum
    import numpy
    from sklearn.grid_search import GridSearchCV
    from keras.models import Sequential
    from keras.layers import Dense
    from keras.wrappers.scikit_learn import KerasClassifier
    from keras.optimizers import SGD
    # Function to create model, required for KerasClassifier
    def create_model(learn_rate=0.01, momentum=0):
        # create model
        model = Sequential()
        model.add(Dense(12, input_dim=8, activation='relu'))
        model.add(Dense(1, activation='sigmoid'))
        # Compile model
        optimizer = SGD(lr=learn_rate, momentum=momentum)
        model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])
        return model
    # fix random seed for reproducibility
    seed = 7
    numpy.random.seed(seed)
    # load dataset
    dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
    # split into input (X) and output (Y) variables
    X = dataset[:,0:8]
    Y = dataset[:,8]
    # create model
    model = KerasClassifier(build_fn=create_model, nb_epoch=100, batch_size=10, verbose=0)
    # define the grid search parameters
    learn_rate = [0.001, 0.01, 0.1, 0.2, 0.3]
    momentum = [0.0, 0.2, 0.4, 0.6, 0.8, 0.9]
    param_grid = dict(learn_rate=learn_rate, momentum=momentum)
    grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1)
    grid_result = grid.fit(X, Y)
    # summarize results
    print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
    for params, mean_score, scores in grid_result.grid_scores_:
        print("%f (%f) with: %r" % (scores.mean(), scores.std(), params))

    运行之后输出如下:

    Best: 0.680990 using {'learn_rate': 0.01, 'momentum': 0.0}
    0.348958 (0.024774) with: {'learn_rate': 0.001, 'momentum': 0.0}
    0.348958 (0.024774) with: {'learn_rate': 0.001, 'momentum': 0.2}
    0.467448 (0.151098) with: {'learn_rate': 0.001, 'momentum': 0.4}
    0.662760 (0.012075) with: {'learn_rate': 0.001, 'momentum': 0.6}
    0.669271 (0.030647) with: {'learn_rate': 0.001, 'momentum': 0.8}
    0.666667 (0.035564) with: {'learn_rate': 0.001, 'momentum': 0.9}
    0.680990 (0.024360) with: {'learn_rate': 0.01, 'momentum': 0.0}
    0.677083 (0.026557) with: {'learn_rate': 0.01, 'momentum': 0.2}
    0.427083 (0.134575) with: {'learn_rate': 0.01, 'momentum': 0.4}
    0.427083 (0.134575) with: {'learn_rate': 0.01, 'momentum': 0.6}
    0.544271 (0.146518) with: {'learn_rate': 0.01, 'momentum': 0.8}
    0.651042 (0.024774) with: {'learn_rate': 0.01, 'momentum': 0.9}
    0.651042 (0.024774) with: {'learn_rate': 0.1, 'momentum': 0.0}
    0.651042 (0.024774) with: {'learn_rate': 0.1, 'momentum': 0.2}
    0.572917 (0.134575) with: {'learn_rate': 0.1, 'momentum': 0.4}
    0.572917 (0.134575) with: {'learn_rate': 0.1, 'momentum': 0.6}
    0.651042 (0.024774) with: {'learn_rate': 0.1, 'momentum': 0.8}
    0.651042 (0.024774) with: {'learn_rate': 0.1, 'momentum': 0.9}
    0.533854 (0.149269) with: {'learn_rate': 0.2, 'momentum': 0.0}
    0.427083 (0.134575) with: {'learn_rate': 0.2, 'momentum': 0.2}
    0.427083 (0.134575) with: {'learn_rate': 0.2, 'momentum': 0.4}
    0.651042 (0.024774) with: {'learn_rate': 0.2, 'momentum': 0.6}
    0.651042 (0.024774) with: {'learn_rate': 0.2, 'momentum': 0.8}
    0.651042 (0.024774) with: {'learn_rate': 0.2, 'momentum': 0.9}
    0.455729 (0.146518) with: {'learn_rate': 0.3, 'momentum': 0.0}
    0.455729 (0.146518) with: {'learn_rate': 0.3, 'momentum': 0.2}
    0.455729 (0.146518) with: {'learn_rate': 0.3, 'momentum': 0.4}
    0.348958 (0.024774) with: {'learn_rate': 0.3, 'momentum': 0.6}
    0.348958 (0.024774) with: {'learn_rate': 0.3, 'momentum': 0.8}
    0.348958 (0.024774) with: {'learn_rate': 0.3, 'momentum': 0.9}

    可以看到,SGD在该问题上相对表现不是很好,但当学习速率为0.01、动量因子为0.0时可取得最好的结果,正确率约为68%。

    如何调优网络权值初始化

    神经网络权值初始化一度十分简单:采用小的随机数即可。

    现在,有许多不同的技术可供选择。点击此处查看Keras 提供的清单。

    在本例中,我们将着眼于通过评估所有可用的技术,来调优网络权值初始化的选择。

    我们将在每一层采用相同的权值初始化方法。理想情况下,根据每层使用的激活函数选用不同的权值初始化方法效果可能更好。在下面的例子中,我们在隐藏层使用了整流器(rectifier)。因为预测是二进制,因此在输出层使用了sigmoid函数。

    完整代码如下:

    # Use scikit-learn to grid search the weight initialization
    import numpy
    from sklearn.grid_search import GridSearchCV
    from keras.models import Sequential
    from keras.layers import Dense
    from keras.wrappers.scikit_learn import KerasClassifier
    # Function to create model, required for KerasClassifier
    def create_model(init_mode='uniform'):
        # create model
        model = Sequential()
        model.add(Dense(12, input_dim=8, init=init_mode, activation='relu'))
        model.add(Dense(1, init=init_mode, activation='sigmoid'))
        # Compile model
        model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
        return model
    # fix random seed for reproducibility
    seed = 7
    numpy.random.seed(seed)
    # load dataset
    dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
    # split into input (X) and output (Y) variables
    X = dataset[:,0:8]
    Y = dataset[:,8]
    # create model
    model = KerasClassifier(build_fn=create_model, nb_epoch=100, batch_size=10, verbose=0)
    # define the grid search parameters
    init_mode = ['uniform', 'lecun_uniform', 'normal', 'zero', 'glorot_normal', 'glorot_uniform', 'he_normal', 'he_uniform']
    param_grid = dict(init_mode=init_mode)
    grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1)
    grid_result = grid.fit(X, Y)
    # summarize results
    print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
    for params, mean_score, scores in grid_result.grid_scores_:
        print("%f (%f) with: %r" % (scores.mean(), scores.std(), params))

    运行之后输出如下:

    Best: 0.720052 using {'init_mode': 'uniform'}
    0.720052 (0.024360) with: {'init_mode': 'uniform'}
    0.348958 (0.024774) with: {'init_mode': 'lecun_uniform'}
    0.712240 (0.012075) with: {'init_mode': 'normal'}
    0.651042 (0.024774) with: {'init_mode': 'zero'}
    0.700521 (0.010253) with: {'init_mode': 'glorot_normal'}
    0.674479 (0.011201) with: {'init_mode': 'glorot_uniform'}
    0.661458 (0.028940) with: {'init_mode': 'he_normal'}
    0.678385 (0.004872) with: {'init_mode': 'he_uniform'}

    我们可以看到,当采用均匀权值初始化方案(uniform weight initialization )时取得最好的结果,可以实现约72%的性能。

    如何选择神经元激活函数

    激活函数控制着单个神经元的非线性以及何时激活。

    通常来说,整流器(rectifier)的激活功能是最受欢迎的,但应对不同的问题, sigmoid函数和tanh 函数可能是更好的选择。

    在本例中,我们将探讨、评估、比较Keras提供的不同类型的激活函数。我们仅在隐层中使用这些函数。考虑到二元分类问题,需要在输出层使用sigmoid激活函数。

    通常而言,为不同范围的传递函数准备数据是一个好主意,但在本例中我们不会这么做。

    完整代码如下:

    # Use scikit-learn to grid search the activation function
    import numpy
    from sklearn.grid_search import GridSearchCV
    from keras.models import Sequential
    from keras.layers import Dense
    from keras.wrappers.scikit_learn import KerasClassifier
    # Function to create model, required for KerasClassifier
    def create_model(activation='relu'):
        # create model
        model = Sequential()
        model.add(Dense(12, input_dim=8, init='uniform', activation=activation))
        model.add(Dense(1, init='uniform', activation='sigmoid'))
        # Compile model
        model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
        return model
    # fix random seed for reproducibility
    seed = 7
    numpy.random.seed(seed)
    # load dataset
    dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
    # split into input (X) and output (Y) variables
    X = dataset[:,0:8]
    Y = dataset[:,8]
    # create model
    model = KerasClassifier(build_fn=create_model, nb_epoch=100, batch_size=10, verbose=0)
    # define the grid search parameters
    activation = ['softmax', 'softplus', 'softsign', 'relu', 'tanh', 'sigmoid', 'hard_sigmoid', 'linear']
    param_grid = dict(activation=activation)
    grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1)
    grid_result = grid.fit(X, Y)
    # summarize results
    print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
    for params, mean_score, scores in grid_result.grid_scores_:
        print("%f (%f) with: %r" % (scores.mean(), scores.std(), params))

    运行之后输出如下:

    Best: 0.722656 using {'activation': 'linear'}
    0.649740 (0.009744) with: {'activation': 'softmax'}
    0.720052 (0.032106) with: {'activation': 'softplus'}
    0.688802 (0.019225) with: {'activation': 'softsign'}
    0.720052 (0.018136) with: {'activation': 'relu'}
    0.691406 (0.019401) with: {'activation': 'tanh'}
    0.680990 (0.009207) with: {'activation': 'sigmoid'}
    0.691406 (0.014616) with: {'activation': 'hard_sigmoid'}
    0.722656 (0.003189) with: {'activation': 'linear'}

    令人惊讶的是(至少对我来说是),“线性(linear)”激活函数取得了最好的效果,准确率约为72%。

    如何调优Dropout正则化

    在本例中,我们将着眼于调整正则化中的dropout速率,以期限制过拟合(overfitting)和提高模型的泛化能力。为了得到较好的结果,dropout最好结合一个如最大范数约束之类的权值约束。

    了解更多dropout在深度学习框架Keras的使用请查看下面这篇文章:

    基于Keras/Python的深度学习模型Dropout正则项
    它涉及到拟合dropout率和权值约束。我们选定dropout percentages取值范围是:0.0-0.9(1.0无意义);最大范数权值约束( maxnorm weight constraint)的取值范围是0-5。

    完整代码如下:

    # Use scikit-learn to grid search the dropout rate
    import numpy
    from sklearn.grid_search import GridSearchCV
    from keras.models import Sequential
    from keras.layers import Dense
    from keras.layers import Dropout
    from keras.wrappers.scikit_learn import KerasClassifier
    from keras.constraints import maxnorm
    # Function to create model, required for KerasClassifier
    def create_model(dropout_rate=0.0, weight_constraint=0):
        # create model
        model = Sequential()
        model.add(Dense(12, input_dim=8, init='uniform', activation='linear', W_constraint=maxnorm(weight_constraint)))
        model.add(Dropout(dropout_rate))
        model.add(Dense(1, init='uniform', activation='sigmoid'))
        # Compile model
        model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
        return model
    # fix random seed for reproducibility
    seed = 7
    numpy.random.seed(seed)
    # load dataset
    dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
    # split into input (X) and output (Y) variables
    X = dataset[:,0:8]
    Y = dataset[:,8]
    # create model
    model = KerasClassifier(build_fn=create_model, nb_epoch=100, batch_size=10, verbose=0)
    # define the grid search parameters
    weight_constraint = [1, 2, 3, 4, 5]
    dropout_rate = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
    param_grid = dict(dropout_rate=dropout_rate, weight_constraint=weight_constraint)
    grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1)
    grid_result = grid.fit(X, Y)
    # summarize results
    print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
    for params, mean_score, scores in grid_result.grid_scores_:
        print("%f (%f) with: %r" % (scores.mean(), scores.std(), params))

    运行之后输出如下:

    Best: 0.723958 using {'dropout_rate': 0.2, 'weight_constraint': 4}
    0.696615 (0.031948) with: {'dropout_rate': 0.0, 'weight_constraint': 1}
    0.696615 (0.031948) with: {'dropout_rate': 0.0, 'weight_constraint': 2}
    0.691406 (0.026107) with: {'dropout_rate': 0.0, 'weight_constraint': 3}
    0.708333 (0.009744) with: {'dropout_rate': 0.0, 'weight_constraint': 4}
    0.708333 (0.009744) with: {'dropout_rate': 0.0, 'weight_constraint': 5}
    0.710937 (0.008438) with: {'dropout_rate': 0.1, 'weight_constraint': 1}
    0.709635 (0.007366) with: {'dropout_rate': 0.1, 'weight_constraint': 2}
    0.709635 (0.007366) with: {'dropout_rate': 0.1, 'weight_constraint': 3}
    0.695312 (0.012758) with: {'dropout_rate': 0.1, 'weight_constraint': 4}
    0.695312 (0.012758) with: {'dropout_rate': 0.1, 'weight_constraint': 5}
    0.701823 (0.017566) with: {'dropout_rate': 0.2, 'weight_constraint': 1}
    0.710938 (0.009568) with: {'dropout_rate': 0.2, 'weight_constraint': 2}
    0.710938 (0.009568) with: {'dropout_rate': 0.2, 'weight_constraint': 3}
    0.723958 (0.027126) with: {'dropout_rate': 0.2, 'weight_constraint': 4}
    0.718750 (0.030425) with: {'dropout_rate': 0.2, 'weight_constraint': 5}
    0.721354 (0.032734) with: {'dropout_rate': 0.3, 'weight_constraint': 1}
    0.707031 (0.036782) with: {'dropout_rate': 0.3, 'weight_constraint': 2}
    0.707031 (0.036782) with: {'dropout_rate': 0.3, 'weight_constraint': 3}
    0.694010 (0.019225) with: {'dropout_rate': 0.3, 'weight_constraint': 4}
    0.709635 (0.006639) with: {'dropout_rate': 0.3, 'weight_constraint': 5}
    0.704427 (0.008027) with: {'dropout_rate': 0.4, 'weight_constraint': 1}
    0.717448 (0.031304) with: {'dropout_rate': 0.4, 'weight_constraint': 2}
    0.718750 (0.030425) with: {'dropout_rate': 0.4, 'weight_constraint': 3}
    0.718750 (0.030425) with: {'dropout_rate': 0.4, 'weight_constraint': 4}
    0.722656 (0.029232) with: {'dropout_rate': 0.4, 'weight_constraint': 5}
    0.720052 (0.028940) with: {'dropout_rate': 0.5, 'weight_constraint': 1}
    0.703125 (0.009568) with: {'dropout_rate': 0.5, 'weight_constraint': 2}
    0.716146 (0.029635) with: {'dropout_rate': 0.5, 'weight_constraint': 3}
    0.709635 (0.008027) with: {'dropout_rate': 0.5, 'weight_constraint': 4}
    0.703125 (0.011500) with: {'dropout_rate': 0.5, 'weight_constraint': 5}
    0.707031 (0.017758) with: {'dropout_rate': 0.6, 'weight_constraint': 1}
    0.701823 (0.018688) with: {'dropout_rate': 0.6, 'weight_constraint': 2}
    0.701823 (0.018688) with: {'dropout_rate': 0.6, 'weight_constraint': 3}
    0.690104 (0.027498) with: {'dropout_rate': 0.6, 'weight_constraint': 4}
    0.695313 (0.022326) with: {'dropout_rate': 0.6, 'weight_constraint': 5}
    0.697917 (0.014382) with: {'dropout_rate': 0.7, 'weight_constraint': 1}
    0.697917 (0.014382) with: {'dropout_rate': 0.7, 'weight_constraint': 2}
    0.687500 (0.008438) with: {'dropout_rate': 0.7, 'weight_constraint': 3}
    0.704427 (0.011201) with: {'dropout_rate': 0.7, 'weight_constraint': 4}
    0.696615 (0.016367) with: {'dropout_rate': 0.7, 'weight_constraint': 5}
    0.680990 (0.025780) with: {'dropout_rate': 0.8, 'weight_constraint': 1}
    0.699219 (0.019401) with: {'dropout_rate': 0.8, 'weight_constraint': 2}
    0.701823 (0.015733) with: {'dropout_rate': 0.8, 'weight_constraint': 3}
    0.684896 (0.023510) with: {'dropout_rate': 0.8, 'weight_constraint': 4}
    0.696615 (0.017566) with: {'dropout_rate': 0.8, 'weight_constraint': 5}
    0.653646 (0.034104) with: {'dropout_rate': 0.9, 'weight_constraint': 1}
    0.677083 (0.012075) with: {'dropout_rate': 0.9, 'weight_constraint': 2}
    0.679688 (0.013902) with: {'dropout_rate': 0.9, 'weight_constraint': 3}
    0.669271 (0.017566) with: {'dropout_rate': 0.9, 'weight_constraint': 4}
    0.669271 (0.012075) with: {'dropout_rate': 0.9, 'weight_constraint': 5}

    我们可以看到,当 dropout率为0.2%、最大范数权值约束( maxnorm weight constraint)取值为4时,可以取得准确率约为72%的最好结果。

    如何确定隐藏层中的神经元的数量

    每一层中的神经元数目是一个非常重要的参数。通常情况下,一层之中的神经元数目控制着网络的代表性容量,至少是拓扑结构某一节点的容量。

    此外,一般来说,一个足够大的单层网络是接近于任何神经网络的,至少在理论上成立。

    在本例中,我们将着眼于调整单个隐藏层神经元的数量。取值范围是:1—30,步长为5。

    一个大型网络要求更多的训练,此外,至少批尺寸(batch size)和 epoch的数量应该与神经元的数量优化。

    完整代码如下:

    # Use scikit-learn to grid search the number of neurons
    import numpy
    from sklearn.grid_search import GridSearchCV
    from keras.models import Sequential
    from keras.layers import Dense
    from keras.layers import Dropout
    from keras.wrappers.scikit_learn import KerasClassifier
    from keras.constraints import maxnorm
    # Function to create model, required for KerasClassifier
    def create_model(neurons=1):
        # create model
        model = Sequential()
        model.add(Dense(neurons, input_dim=8, init='uniform', activation='linear', W_constraint=maxnorm(4)))
        model.add(Dropout(0.2))
        model.add(Dense(1, init='uniform', activation='sigmoid'))
        # Compile model
        model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
        return model
    # fix random seed for reproducibility
    seed = 7
    numpy.random.seed(seed)
    # load dataset
    dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
    # split into input (X) and output (Y) variables
    X = dataset[:,0:8]
    Y = dataset[:,8]
    # create model
    model = KerasClassifier(build_fn=create_model, nb_epoch=100, batch_size=10, verbose=0)
    # define the grid search parameters
    neurons = [1, 5, 10, 15, 20, 25, 30]
    param_grid = dict(neurons=neurons)
    grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1)
    grid_result = grid.fit(X, Y)
    # summarize results
    print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
    for params, mean_score, scores in grid_result.grid_scores_:
        print("%f (%f) with: %r" % (scores.mean(), scores.std(), params))

    运行之后输出如下:

    Best: 0.714844 using {'neurons': 5}
    0.700521 (0.011201) with: {'neurons': 1}
    0.714844 (0.011049) with: {'neurons': 5}
    0.712240 (0.017566) with: {'neurons': 10}
    0.705729 (0.003683) with: {'neurons': 15}
    0.696615 (0.020752) with: {'neurons': 20}
    0.713542 (0.025976) with: {'neurons': 25}
    0.705729 (0.008027) with: {'neurons': 30}

    我们可以看到,当网络中隐藏层内神经元的个数为5时,可以达到最佳结果,准确性约为71%。

    超参数优化的小技巧
    本节罗列了一些神经网络超参数调整时常用的小技巧。

    K层交叉检验(k-fold Cross Validation),你可以看到,本文中的不同示例的结果存在一些差异。使用了默认的3层交叉验证,但也许K=5或者K=10时会更加稳定。认真选择您的交叉验证配置,以确保您的结果是稳定的。
    审查整个网络。不要只注意最好的结果,审查整个网络的结果,并寻找支持配置决策的趋势。
    并行(Parallelize),如果可以,使用全部的CPU,神经网络训练十分缓慢,并且我们经常想尝试不同的参数。参考AWS实例。
    使用数据集的样本。由于神经网路的训练十分缓慢,尝试训练在您训练数据集中较小样本,得到总方向的一般参数即可,并非追求最佳的配置。
    从粗网格入手。从粗粒度网格入手,并且一旦缩小范围,就细化为细粒度网格。
    不要传递结果。结果通常是特定问题。尽量避免在每一个新问题上都采用您最喜欢的配置。你不可能将一个问题的最佳结果转移到另一个问题之上。相反地,你应该归纳更广泛的趋势,例如层的数目或者是参数之间的关系。
    再现性(Reproducibility)是一个问题。在NumPy中,尽管我们为随机数发生器设置了种子,但结果并非百分百重现。网格搜索wrapped Keras模型将比本文中所示Keras模型展现更多可重复性(reproducibility)。
    总结
    在这篇文章中,你可以了解到如何使用Keras和scikit-learn/Python调优神经网络中的超参数。

    尤其是可以学到:

    如何包装Keras模型以便在scikit-learn使用以及如何使用网格搜索。
    如何网格搜索Keras 模型中不同标准的神经网络参数。
    如何设计自己的超参数优化实验。

    原文来自http://geek.csdn.net/news/detail/95494?ref=myread

    展开全文
  • 在本教程中,我们将讨论一种非常强大的优化(或自动化)算法,即网格搜索算法。它最常用于机器学习模型中的超参数调整。我们将学习如何使用Python来实现它,以及如何将其应用到实际应用程序中,以了解它如何帮助我们...
  • 参数优化网格搜索

    千次阅读 2020-06-07 21:20:15
    使用Python完成网格搜索法在机器学习和深度学习的小案例!
  • 原文:How to Grid Search ...超参数优化是深度学习的重要组成部分。 原因是神奇网络的配置非常困难,并且需要设置很多参数。最重要的是,单个模型的训练速度可能非常慢。 在这篇文章中,您将了解如何使用scikit...
  • 在这篇文章中,你会了解到如何使用scikit-learn python机器学习库中的网格搜索功能调整Keras深度学习模型中的超参数。 阅读本文后,你就会了解: 如何包装Keras模型以便在scikit-learn中使用,以及如何使用网格搜索...
  • Sklearn-GridSearchCV网格搜索 scikit-learn一般实例之四:使用管道(pipeline)和GridSearchCV选择降维GridSearchCV,它存在的意义就是自动调参,只要把参数输进去,就能给出最优化的结果和参数。但是这个方法适合...
  • GridSearchCV的作用能够自动调参(Parameter tuning),...网格搜索,搜索的是参数,即在指定的参数范围内,按步长依次调整参数,利用调整的参数训练学习器,从所有的参数中找到在验证集上精度最高的参数,这其实是...
  • 交叉验证:训练数据划分为训练集和验证...1. 网格搜索GridSearchCV(常用) 2. 随机搜索RandomizedSearchCV(随机) 3. hyperopt(方便) 具体参考博客:https://blog.csdn.net/luanpeng825485697/article/detail...
  • https://machinelearningmastery.com/grid-search-hyperparameters-deep-learning-models-python-keras/ Overview In this post I want to show you both how you can use the scikit-learn grid search capabilit...
  • 本文介绍了如何使用网格搜索寻找网络的最佳超参数配置。 文章目录1. 准备数据集2. 问题建模2.1 训练集测试集拆分2.2...常用的方法是穷尽网格搜索(Exhaustive Grid Search)和随机参数优化(Randomized Parameter Opti
  • 我们知道,大部分的模型依赖于参数的调节达到模型更好的得分结果,但是频繁的调参是一个艰巨的任务,而且有可能费力不讨好,那么网格搜索将会大大减轻我们的负担,所谓网格搜索,就是将参数按照网格的形式排列,再...
  • sklearn包中自动调参方法-网格搜索GridSearchCV 一、GridSearchCV主要作用及函数参数 GridSearchCV:作用是在指定的范围内可以自动调参,只需将参数输入即可得到最优化的结果和参数。相对于人工调参更省时省力,相...
  • 网格搜索算法是一种通过遍历给定的参数组合来优化模型表现的方法。 以决策树为例,当我们确定了要使用决策树算法的时候,为了能够更好地拟合和预测,我们需要调整它的参数。在决策树算法中,我们通常选择的参数是...
  • 机器学习调参与贝叶斯优化及其典型python实现hyperopt...手动调参十分耗时,网格搜索和随机搜索不需要人力,但需要很长的运行时间。因此,诞生了许多自动调整超参数的方法,例如遗传算法、粒子群优化、贝叶斯优化等。..
  • 全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 优化的相关的知识内容可以参考 ...网格搜索GridSearchCV GridSearchCV用于系统地遍历多种参数组合,通过交叉验证确定最佳效果...
  • 贝叶斯优化 (BayesianOptimization) 1 问题提出 神经网咯是有许多超参数决定的,例如网络深度,学习率,正则等等。如何寻找最好的超参数组合,是一个老人靠经验,新人靠运气的任务。...网格搜索未...
  • 通用-利用多个参数和多种搜索算法(网格搜索,随机,贝叶斯) 安装 $ npm install hyperparameters 参数表达式 import * as hpjs from 'hyperparameters'; hpjs.choice(选项) 随机返回选项之一 hpjs.randint...
  • 1)网格搜索优化参数 网格搜索优化参数——通过遍历已定义参数的列表来评估算法的参数。 在sklearn 中使用GridSearchCV来实现对参数的跟踪、调整与评估。 GridSearchCV使用字典对象来指定需要调参的参数,可以同时...
  • 贝叶斯优化是一种用模型找到函数最小值方法,已经应用于机器学习问题中的超参数搜索,这种方法性能好,同时比随机搜索省时。此外,现在有许多Python库可以实现贝叶斯超参数调整。本文将使用Hyperopt库...
  • 在以往的大多数使用场景中,我大都会直接使用默认的基分类器模型,不会对其进行调整设置,其他的几个主要的参数比如:基分类器数量等可能会基于网格调参的形式进行最优化参数搜索, 下面是sklearn官网里面对...
  • 基于快速超参数优化,基于超参数搜索空间的高斯过程建模。 最先进的学习算法集成,在学习时无需额外的计算成本。 通过可配置的命令行界面(即将推出)与任何编程语言兼容。 基于对超参数空间的3D vizualization ...
  • Python数据分析之房价预测

    千次阅读 2019-07-22 14:55:23
    从网上爬取关于房价的相关数据属性来分析房价,并且基于一些属性来预测房价,使用的是网格搜索算法。相关的数据文件和完整代码可以从文末获取。 GridSearchCV介绍:   能够系统地遍历多种参数组合,通过...
  • keras参数调优(如何使用scikit-learn网格搜索功能):https://blog.csdn.net/wang1127248268/article/details/77200639 keras 调参, 优化, 一些设置等:...

空空如也

空空如也

1 2 3
收藏数 50
精华内容 20
关键字:

python网格搜索优化参数

python 订阅