精华内容
下载资源
问答
  • 参数 定义:模型内部的配置变量,可以用数据估计它的值。 特征: 进行模型预测时需要...模型参数常应用于估计模型参数的过程中。 模型参数通常由实践者直接指定。 模型参数通常可以使用启发式方法来设置。 模

    参数

    定义:模型内部的配置变量,可以用数据估计它的值。

    特征:

    1. 进行模型预测时需要模型参数。
    2. 模型参数值可以定义模型功能。
    3. 模型参数用数据估计或数据学习得到。
    4. 模型参数一般不由实践者手动设置。
    5. 模型参数通常作为学习模型的一部分保存。

    例子:

    1. 人造神经网络中的权重。
    2. 支持向量机中的支持向量。
    3. 线性回归或逻辑回归中的系数。

    超参数

    定义:模型外部的配置,其值不能从数据估计得到。

    特征:

    1. 模型超参数常应用于估计模型参数的过程中。
    2. 模型超参数通常由实践者直接指定。
    3. 模型超参数通常可以使用启发式方法来设置。
    4. 模型超参数通常根据给定的预测建模问题而调整。

    例子:

    1. 训练神经网络的学习速率。
    2. 支持向量机的C和sigma超参数。
    3. k邻域中的k。
    4. 网络结构,包括神经元之间的连接关系、层数、每层的神经元数量、激活函数的类型。
    5. 优化参数,包括优化方法、学习率、小批量的样本数量。
    6. 正则化系数

    模型参数是根据数据自动估算的。但模型超参数是手动设置的,并且在过程中用于帮助估计模型参数。

    超参数优化方法

    1. 网格搜索

    通过尝试所有超参数的组合来寻址合适一组超参数配置的方法。根据这些超参数的不同组合方式分别训练一个模型,然后测试这些模型在开发集上的性能,选取一组性能最好的配置。
    详细解释和代码可以参考超参数优化机器学习模型的超参数优化

    1. 随机搜索

    对超参数进行随机组合,然后选择一个性能最好的配置。在超参数网格的基础上选择随机的组合来进行模型训练。随机寻优方法找到最优参数的机会相对更高,但是这一方法适用于低维数据的情况,可以在较少迭代次数的情况下找到正确的参数集合,并且花费的时间较少。
    详细解释和代码可以参考机器学习模型的超参数优化超参数优化

    1. 贝叶斯优化

    自适应的超参数搜索方法,根据当前已经试验的超参数组合,来预测下一个可能带来最大收益的组合。通过构造一个函数的后验分布(高斯过程)来工作的,该后验分布最好地描述了要优化的函数。随着观测次数的增加,后验分布得到改善,算法更加确定参数空间中哪些区域值得探索,哪些区域不值得探索。
    详细解释可参考深度学习之10——超参数优化机器学习模型的超参数优化超参数优化,代码可参考4种主流超参数调优技术

    1. 动态资源分配

    一种有效方法是逐次减半(successive halving),将超参数优化看作是一种非随机的最优臂问题,假设要尝试N组超参数配置,总共可利用的资源预算为B,我们可以通过 T = [ l o g 2 ( N ) − 1 ] T = [log_2(N)-1] T=[log2(N)1] 轮逐次减半的方法来选取最优的配置。
    详细解释可参考深度学习之10——超参数优化

    1. 神经架构搜索

    通过神经网络来自动实现网络架构的设计。一个神经网络的架构可以用一个变长的字符串来描述。利用元学习的思想,神经架构搜索利用一个控制器来生成另一个子网络的架构描述。控制器可以由一个循环神经网络来实现。控制器的训练可以通过强化学习来完成,其奖励信号为生成的子网络在开发集上的准确率。
    详细解释参考深度学习之10——超参数优化

    1. 基于梯度的优化方法(Gradient-based Optimization)

    计算超参数的梯度,并且通过梯度下降算法进行优化。参考机器学习模型的超参数优化

    1. 进化寻优(Evolutionary Optimization)

    来源于生物学概念,由于自然进化是不断变化的环境中发生的一个动态过程,因此适用于超参数寻优问题,因为超参数寻优也是一个动态过程。参考机器学习模型的超参数优化

    一般性的经验法则,任何时候想要优化调整超参数,优先考虑网格化寻优方法和随机寻优方法。

    参考资料

    机器学习中的参数与超参数之间的区别
    手把手教你区分参数和超参数
    机器学习中模型参数与超参数的区别
    4种主流超参数调优技术
    超参数优化
    深度学习之10——超参数优化
    机器学习模型的超参数优化

    展开全文
  • 最新版本的 NNI 对机器学习生命周期的各个环节做了更加全面的支持,包括特征工程、神经网络架构搜索(NAS)、超参调优和模型压缩在内的步骤,你都能使用自动机器学习算法来完成。 无论你是刚刚入门机器学习的小白...

    点击我爱计算机视觉标星,更快获取CVML新技术


    2018年9月,微软亚洲研究院发布了第一版 NNI (Neural Network Intelligence) ,目前已在 GitHub 上获得 3.8K 星,成为最热门的自动机器学习(AutoML)开源项目之一。

    作为为研究人员和算法工程师量身定制的自动机器学习工具和框架,NNI 在过去一年中不断迭代更新,我们发布了稳定 API 的 1.0 版本,并且不断将最前沿的算法加入其中,加强对各种分布式训练环境的支持。

    最新版本的 NNI 对机器学习生命周期的各个环节做了更加全面的支持,包括特征工程、神经网络架构搜索(NAS)、超参调优和模型压缩在内的步骤,你都能使用自动机器学习算法来完成

    无论你是刚刚入门机器学习的小白,还是身经百战的“调参大法师”,NNI 都能助你一臂之力。在这篇文章中,我们会全方位解读 NNI 最新版本中的各项功能,让大家了解这个简单易用的自动机器学习工具。

    概述

    自动机器学习是近年来火热的应用和研究方向,各种自动机器学习工具也层出不穷,它们各有优点与局限性。有的聚焦于算法,但不支持分布式训练;有的功能强大,但没有易用的用户界面,学习成本较高;有的只支持特定领域,不提供通用功能;还有的只能在云端使用。

    微软自动深度学习工具 NNI 具备以下优势:

    支持多种框架:提供基于 Python 的 SDK,支持 PyTorch、TensorFlow、scikit-learn、LightGBM 等主流框架和库;

    支持多种训练平台:除在本机直接运行外,还能通过 SSH 调度一组 GPU 服务器,或通过 FrameworkController、KubeFlow、OpenPAI 等在 Kubernetes 下调度大规模集群;

    支持机器学习生命周期中的多环节:特征工程、神经网络架构搜索(NAS)、超参调优和模型压缩等;

    提供易用的命令行工具和友好的 WEB 用户界面

    大量的示例能帮助你很快上手;

    • 最后划重点,NNI的所有文档都有中文版! 

    完整中文文档请参考:https://aka.ms/nnizh

    自动机器学习工具对比

    NNI 入门与超参优化

    机器学习和人工智能通过近些年的厚积薄发,已经形成不少经典的机器学习算法和深度学习网络,这些算法各有特点,在不同的数据集上所需要的超参也有所不同。而自动机器学习中的超参优化就是为了解决这个问题,通过启动多个实例来找到调优结果较好的组合。

    NNI 的超参调优功能就是为这样的场景准备的。在超参搜索算法上,NNI 不仅提供了 TPE、SMAC、进化算法等优秀算法,还提供了遍历、批处理、随机、Hyperband 等十多种算法。另外,还支持自动终止低效实例,加速学习过程。

    NNI 的安装基于 Python pip 命令,“pip install nni”即可一步完成。

    NNI 的使用也非常简单:首先,定义好需要搜索的超参空间;然后,在需要调参的网络启动之前,通过 NNI 的接口读取参数并在训练中将精确度等指标传入 NNI;最后,配置好要使用的调参算法等,即可开始。

    具体过程可参考入门教程:https://aka.ms/nnizq

    你也可以在这里找到所有示例:https://aka.ms/nnize

    一图了解 NNI 使用

    NNI 的超参调优不仅能用于机器学习,对于各类系统、数据库的繁杂参数都可以根据实际场景进行有针对性的调优。使用过程和超参调优非常类似,通过 Python 为系统传入不同的参数配置,然后将确定的调优指标(如读写速度,磁盘空间大小等)回调给 NNI 即可。

    更多信息请访问:https://aka.ms/nnizrd

    NNI 在运行中,可随时通过界面了解进度

    分析超参之间的关联关系,快速发现规律

    自动特征工程

    特征工程是应用经典机器学习算法的前置步骤,通过特征工程,能让机器学习过程更快得到较好的结果。

    前面介绍的 NNI 的超参调优功能,可直接应用于特征增强、自动特征选择等特征工程中的各个子领域。为使新手轻松上手,NNI 还内置了基于梯度和决策树的自动特征选择算法,同时还提供了扩展其它算法的接口。

    NNI 团队还对自动特征工程的效果进行了对比,在流行的 colon-cancer、gisette、rcv1、neews20.binary、real-sim 等数据集上进行了测试。我们发现如果在成千上万个特征中仅选择前20个,决策树基本都能取得较好的结果,如果选出更多特征,会得到更好的效果。

    更多信息请访问:https://aka.ms/nnizfe

    神经网络结构搜索(NAS)

    神经网络搜索(Neural Architecture Search,简称 NAS)通过自动搜索网络结构来获得较好的性能,在今年涌现了大量研究成果。NAS 算法多种多样,实现也各不相同。

    为了促进 NAS 的创新,我们对 NAS 算法抽象与实现进行了探索,让用户不仅能在自己的数据集上直接应用算法,还能很容易地横向比较不同 NAS 算法的效果。

    NNI 中实现了 ENAS、DARTS、P-DARTS 算法,并提供了 one-shot 算法的接口。另外,还支持了网络模态(Network Morphism)这样的经典搜索方法。

    算法介绍及用法:https://aka.ms/nnizn

    模型压缩

    随着深度学习的发展,模型也越来越大。虽然精确度有了很大的提升,但较大的模型尺寸不仅会影响推理速度,还对部署的硬件要求较高。因此,模型压缩也是一个热门话题。

    主要的模型压缩算法可分为两类,一类是压缩网络结构的剪枝算法,另一类是减小模型精度的量化算法。NNI 目前提供了 AGP、L1Filter、Slim、Lottery Ticket、FPGM、QAT、DoReFa 等9种模型压缩算法。用户也可根据需要,通过 NNI 的模型压缩接口来实现自己的压缩算法。

    相关算法介绍及用法:https://aka.ms/nnizc

    结语

    随着人工智能的发展,理论和建模方法也始终在不断演进。立足于研究与应用的最前线,我们希望将最好用的工具提供给每一位研究员和算法工程师,加速人工智能领域的发展进步。

    2020年,我们将加速创新,力图让 NNI 能够提供全生命周期的自动化框架、更丰富的算法、更高效的分布式调参效率,进一步提升 NNI 的易用性和用户体验。

    作为一个开源项目,我们期待大家为 NNI 添加新算法、功能、示例,也希望大家为 NNI 提出建议、报告问题,让我们为大家提供更好的工具,如果您有任何反馈与建议,欢迎在 GitHub 社区中告知我们。

    NNI 的 GitHub 社区:https://aka.ms/nniis

    NNI 中文文档链接:https://aka.ms/nnizh


    AutoML &NAS交流群

    关注最新最前沿的自动机器学习、神经架构搜索技术,扫码添加CV君拉你入群,(如已为CV君其他账号好友请直接私信)

    (请务必注明:AutoML)

    喜欢在QQ交流的童鞋,可以加52CV官方QQ群:805388940。

    (不会时时在线,如果没能及时通过验证还请见谅)


    长按关注我爱计算机视觉

    展开全文
  • Talos - Keras模型超参调优工具
  • 超参调优的概念是找到模型的最佳参数:例如逻辑回归的最大迭代次数或决策树的最大深度 为模型找到最佳参数:grid search和train-validation spliting 网格搜索 网格搜索是一个详尽的算法,根据给定评估指标,...
    from pyspark.sql import SparkSession
    
    spark = SparkSession.builder.getOrCreate()
    
    import pyspark.sql.types as typ
    
    labels = [
        ('INFANT_ALIVE_AT_REPORT', typ.IntegerType()),
        ('BIRTH_PLACE', typ.StringType()),
        ('MOTHER_AGE_YEARS', typ.IntegerType()),
        ('FATHER_COMBINED_AGE', typ.IntegerType()),
        ('CIG_BEFORE', typ.IntegerType()),
        ('CIG_1_TRI', typ.IntegerType()),
        ('CIG_2_TRI', typ.IntegerType()),
        ('CIG_3_TRI', typ.IntegerType()),
        ('MOTHER_HEIGHT_IN', typ.IntegerType()),
        ('MOTHER_PRE_WEIGHT', typ.IntegerType()),
        ('MOTHER_DELIVERY_WEIGHT', typ.IntegerType()),
        ('MOTHER_WEIGHT_GAIN', typ.IntegerType()),
        ('DIABETES_PRE', typ.IntegerType()),
        ('DIABETES_GEST', typ.IntegerType()),
        ('HYP_TENS_PRE', typ.IntegerType()),
        ('HYP_TENS_GEST', typ.IntegerType()),
        ('PREV_BIRTH_PRETERM', typ.IntegerType())
    ]
    schema = typ.StructType([
        typ.StructField(e[0], e[1], False) for e in labels
    ])
    births = spark.read.csv('file:///Program Files/Pyproject/pyspark/data/births_transformed.csv.gz',
                           header=True,
                           schema=schema)
    

    创建转换器

    import pyspark.ml.feature as ft
    
    # 使用OneHotEncode方法来对BIRTH_PLACE列进行编码。该方法不接受StringType列:只能处理数字类型,所以将该列转换为IntegerType
    births = births.withColumn('BIRTH_PLACE_INT',
                               births['BIRTH_PLACE'].cast(typ.IntegerType()))
    
    # 创建转换器
    encoder = ft.OneHotEncoder(inputCol='BIRTH_PLACE_INT',
                               outputCol='BIRTH_PLACE_VEC')
    

    创建单一的列,它将所有特征整合在一起,使用VectorAssembler方法:

    featuresCreator = ft.VectorAssembler(
                        inputCols=[
                            col[0] 
                            for col in labels[2:]
                                  ] + [encoder.getOutputCol()],
                        outputCol='features'
    )
    

    传递给VectorAssembler对象地inputCol参数是一个列表,该列表包含所有要合并在一起组成outputCol————‘features’列。

    创建评估器

    使用逻辑回归模型。

    import pyspark.ml.classification as cl
    
    # 创建模型
    logistic = cl.LogisticRegression(maxIter=10, 
                                     regParam=0.01, 
                                     labelCol='INFANT_ALIVE_AT_REPORT')
    

    如果目标列地名称为”label“,则不必指定labelCol参数。如果featureCreator地输出名称不是‘feature’,那么必须通过在featuresCreator对象上调用getOutputCol()方法来指定featuresCol

    创建一个管道

    建立管道并拟合模型

    from pyspark.ml import Pipeline
    

    管道概念图
    %E7%BB%98%E5%9B%BE1.png

    pipline = Pipeline(stages=[encoder, 
                               featuresCreator, 
                               logistic
                              ])
    

    拟合模型

    拟合模型前,需要把数据集分成训练数据和测试数据。DataFrame API提供了.randomSplit()方法

    births_train, births_test = births.randomSplit([0.7, 0.3], seed=666)
    

    seed参数给randomizer提供了一个种子
    只要列表地元素总合为1,可以将数据集拆分成两个以上地子集,并输出多个子集

    train, test, val = births.randomSplit([0.7, 0.2, 0.1], seed=666)
    

    以上随机将70%地出生数据放到训练模型中,20%放入测试模型,而val DataFrame将保留剩余10%。

    # 运行管道并评估模型:
    model = pipline.fit(births_train)
    
    test_model = model.transform(births_test)
    

    管道对象的.fit()方法以训练数据集作为输入。births_train数据集有限被传给encoder对象。在endcoder极端创建的DataFrame将被传递给创建”features“列的featuresCreator。输出被传递给评估最终模型的logistic对象
    .fit()方法返回用于预测的PipelineModel对象,将之前创建的测试数据集传递给要调用的.transfrom()方法来获得预测。test_model示例如下命令:

    test_model.take(1)
    
    [Row(INFANT_ALIVE_AT_REPORT=0, BIRTH_PLACE='1', MOTHER_AGE_YEARS=13, FATHER_COMBINED_AGE=99, CIG_BEFORE=0, CIG_1_TRI=0, CIG_2_TRI=0, CIG_3_TRI=0, MOTHER_HEIGHT_IN=66, MOTHER_PRE_WEIGHT=133, MOTHER_DELIVERY_WEIGHT=135, MOTHER_WEIGHT_GAIN=2, DIABETES_PRE=0, DIABETES_GEST=0, HYP_TENS_PRE=0, HYP_TENS_GEST=0, PREV_BIRTH_PRETERM=0, BIRTH_PLACE_INT=1, BIRTH_PLACE_VEC=SparseVector(9, {1: 1.0}), features=SparseVector(24, {0: 13.0, 1: 99.0, 6: 66.0, 7: 133.0, 8: 135.0, 9: 2.0, 16: 1.0}), rawPrediction=DenseVector([1.0573, -1.0573]), probability=DenseVector([0.7422, 0.2578]), prediction=0.0)]
    

    逻辑回归模型输出类几列:rawPrediction是特征和β系数的线性组合的值,probability是每个类别计算出的概率,最后predicition的最总分类

    评估模型的性能

    import pyspark.ml.evaluation as ev
    
    # 使用BinaryClassficationEvalutator来检验模型表现:
    evalutor = ev.BinaryClassificationEvaluator(rawPredictionCol='probability',
                                               labelCol='INFANT_ALIVE_AT_REPORT')
    

    rawPredictionCol可以是由评估器产生的rawprediction列,也可以是probability

    print(evalutor.evaluate(test_model,
                           {evalutor.metricName: 'areaUnderROC'}))
    print(evalutor.evaluate(test_model,
                           {evalutor.metricName: 'areaUnderPR'}))
    
    0.7401301847095617
    0.7139354342365674
    

    保存模型

    pyspark允许保存管道定义以备以后使用。可以保存管道结构,还可以报错所有转换器和评估器定义:

    piplinePath = './infant_oneHotEncoder_Logistic_Pipeline'
    pipline.write().overwrite().save(piplinePath)
    

    所以,可以随后加载并直接使用.fit()并预测:

    loadedPipeline = Pipeline.load(piplinePath)
    loadedPipeline.fit(births_train).transform(births_test).take(1)
    
    [Row(INFANT_ALIVE_AT_REPORT=0, BIRTH_PLACE='1', MOTHER_AGE_YEARS=13, FATHER_COMBINED_AGE=99, CIG_BEFORE=0, CIG_1_TRI=0, CIG_2_TRI=0, CIG_3_TRI=0, MOTHER_HEIGHT_IN=66, MOTHER_PRE_WEIGHT=133, MOTHER_DELIVERY_WEIGHT=135, MOTHER_WEIGHT_GAIN=2, DIABETES_PRE=0, DIABETES_GEST=0, HYP_TENS_PRE=0, HYP_TENS_GEST=0, PREV_BIRTH_PRETERM=0, BIRTH_PLACE_INT=1, BIRTH_PLACE_VEC=SparseVector(9, {1: 1.0}), features=SparseVector(24, {0: 13.0, 1: 99.0, 6: 66.0, 7: 133.0, 8: 135.0, 9: 2.0, 16: 1.0}), rawPrediction=DenseVector([1.0573, -1.0573]), probability=DenseVector([0.7422, 0.2578]), prediction=0.0)]
    

    以上代码产生相同的结果
    也可以保存评估模型;此时要保存PipelineModel,而不是保存管道

    from pyspark.ml import PipelineModel
    
    modelPath = './infant_oneHotEncoder_Logistic_PipelineModel'
    model.write().overwrite().save(modelPath)
    
    loadedPipelineModel = PipelineModel.load(modelPath)
    test_reloadedModel = loadedPipelineModel.transform(births_test)
    
    test_reloadedModel.take(1)
    
    [Row(INFANT_ALIVE_AT_REPORT=0, BIRTH_PLACE='1', MOTHER_AGE_YEARS=13, FATHER_COMBINED_AGE=99, CIG_BEFORE=0, CIG_1_TRI=0, CIG_2_TRI=0, CIG_3_TRI=0, MOTHER_HEIGHT_IN=66, MOTHER_PRE_WEIGHT=133, MOTHER_DELIVERY_WEIGHT=135, MOTHER_WEIGHT_GAIN=2, DIABETES_PRE=0, DIABETES_GEST=0, HYP_TENS_PRE=0, HYP_TENS_GEST=0, PREV_BIRTH_PRETERM=0, BIRTH_PLACE_INT=1, BIRTH_PLACE_VEC=SparseVector(9, {1: 1.0}), features=SparseVector(24, {0: 13.0, 1: 99.0, 6: 66.0, 7: 133.0, 8: 135.0, 9: 2.0, 16: 1.0}), rawPrediction=DenseVector([1.0573, -1.0573]), probability=DenseVector([0.7422, 0.2578]), prediction=0.0)]
    

    超参调优

    一般第一个模型几乎不可能是最好的模型。仅仅只是查看一系列指标便因为它通过了预先设定的性能阈值从而接受模型并不是寻求最佳模型的科学方法
    超参调优的概念是找到模型的最佳参数:例如逻辑回归的最大迭代次数或决策树的最大深度
    为模型找到最佳参数:grid search和train-validation spliting

    网格搜索

    网格搜索是一个详尽的算法,根据给定评估指标,循环遍历定义的参数值列表,估计各个单独的模型,从而选定一个最佳模型
    如果定义的要优化的参数太多或者这些参数的值太多,则可能需要大量时间才能选出最佳模型,因为随着参数和参数值的增加,要估计的模型数量将迅速增长

    # 加载.tuning包
    import pyspark.ml.tuning as tune
    
    # 指定模型和要遍历参数的列表
    logistic = cl.LogisticRegression(labelCol='INFANT_ALIVE_AT_REPORT')
    grid = tune.ParamGridBuilder() \
                .addGrid(logistic.maxIter, [2, 10, 50]) \
                .addGrid(logistic.regParam, [0.01, 0.05, 0.3]).build()
    

    指定要优化参数的模型,确定优化的参数以及要测试的参数的值。使用.tuning子包中的ParamGridBuilder()对象,并使用.addGrid()方法继续将参数添加到网格中:第一个参数是要优化模型的参数对象,第二个参数是要循环值的列表。在.ParamGridBuilder上调用.build()方法构建网格

    evalutor = ev.BinaryClassificationEvaluator(rawPredictionCol='probability',
                                               labelCol='INFANT_ALIVE_AT_REPORT')
    

    再次使用BinaryClassificationEvaluator。可以创建验证逻辑

    cv = tune.CrossValidator(estimator=logistic,
                             estimatorParamMaps=grid, 
                             evaluator=evalutor
                            )
    

    使用CrossValidator需要评估器、estimatorParamMaps和evaluator。该模型循环遍历值的网络,评估各个模型,并使用evaluator比较性能

    pipeline = Pipeline(stages=[encoder, featuresCreator])
    data_transformer = pipline.fit(births_train)
    
    # 寻找最佳参数组合
    cvModel = cv.fit(data_transformer.transform(births_train))
    
    data_train = data_transformer.transform(births_test)
    results = cvModel.transform(data_train)
    print(evalutor.evaluate(results, {evalutor.metricName: 'areaUnderROC'}))
    print(evalutor.evaluate(results, {evalutor.metricName: 'areaUnderPR'}))
    

    在这里插入图片描述

    过程:

    results = [
        (
        [
            {key.name: paramValue}
            for key, paramValue in zip(params.key(),
                                       params.values())
        ], metric)
        for params, metric in zip(
            cvModel.getEstimatorParamMaps(),
            cvModel.avgMetrics)
    ]
    sorted(results,
          key=lambda el: el[1],
          reversed=True)[0]
    

    展开全文
  • python自带超参调优

    千次阅读 2019-04-03 20:17:40
    可以看到,不调的话模型20此交叉验证AUC均值是0.965162,算是一个不错的模型,那么如果用bayes调结果会怎么样呢 bayes调初探 我们先定义一个目标函数,里面放入我们希望优化的函数。比如此时,函数输入...

    一、bayesian-optimization

    安装

    pip install bayesian-optimization

    前期准备

    from sklearn.datasets import make_classification
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.cross_validation import cross_val_score
    from bayes_opt import BayesianOptimization
    
    # 产生随机分类数据集,10个特征, 2个类别
    x, y = make_classification(n_samples=1000,n_features=10,n_classes=2)

    我们先看看不调参的结果:

    rf = RandomForestClassifier()
    print(np.mean(cross_val_score(rf, x, y, cv=20, scoring='roc_auc')))
    
    >>> 0.965162

    可以看到,不调参的话模型20此交叉验证AUC均值是0.965162,算是一个不错的模型,那么如果用bayes调参结果会怎么样呢

    bayes调参初探

    我们先定义一个目标函数,里面放入我们希望优化的函数。比如此时,函数输入为随机森林的所有参数,输出为模型交叉验证5次的AUC均值,作为我们的目标函数。因为bayes_opt库只支持最大值,所以最后的输出如果是越小越好,那么需要在前面加上负号,以转为最大值。由于bayes优化只能优化连续超参数,因此要加上int()转为离散超参数。

    def rf_cv(n_estimators, min_samples_split, max_features, max_depth):
        val = cross_val_score(
            RandomForestClassifier(n_estimators=int(n_estimators),
                min_samples_split=int(min_samples_split),
                max_features=min(max_features, 0.999), # float
                max_depth=int(max_depth),
                random_state=2
            ),
            x, y, scoring='roc_auc', cv=5
        ).mean()
        return val
    

    然后我们就可以实例化一个bayes优化对象了:

     rf_bo = BayesianOptimization(
            rf_cv,
            {'n_estimators': (10, 250),
            'min_samples_split': (2, 25),
            'max_features': (0.1, 0.999),
            'max_depth': (5, 15)}
        )

    里面的第一个参数是我们的优化目标函数,第二个参数是我们所需要输入的超参数名称,以及其范围。超参数名称必须和目标函数的输入名称一一对应。

    完成上面两步之后,我们就可以运行bayes优化了!

    rf_bo.maximize()

    完成的时候会不断地输出结果,如下图所示:

    等到程序结束,我们可以查看当前最优的参数和结果:

    rf_bo.res['max']
    
    >>> {'max_params': {'max_depth': 5.819908283575526,
      'max_features': 0.4951745603509127,
      'min_samples_split': 2.3110014720414958,
      'n_estimators': 249.73529231990733},
     'max_val': 0.9774079407940794}

    bayes调参进阶

    上面bayes算法得到的参数并不一定最优,当然我们会遇到一种情况,就是我们已经知道有一组或是几组参数是非常好的了,我们想知道其附近有没有更好的。这个操作相当于上文bayes优化中的Explore操作,而bayes_opt库给了我们实现此方法的函数:

    
    rf_bo.explore(
        {'n_estimators': [10, 100, 200],
            'min_samples_split': [2, 10, 20],
            'max_features': [0.1, 0.5, 0.9],
            'max_depth': [5, 10, 15]
        }
    )

    这里我们添加了三组较优的超参数,让其在该参数基础上进行explore,可能会得到更好的结果。

    同时,我们还可以修改高斯过程的参数,高斯过程主要参数是核函数(kernel),还有其他参数可以参考sklearn.gaussianprocess

    gp_param={'kernel':None}
    rf_bo.maximize(**gp_param)

    最终我们的到参数如下:

    {'max_params': {'max_depth': 5.819908283575526,
      'max_features': 0.4951745603509127,
      'min_samples_split': 2.3110014720414958,
      'n_estimators': 249.73529231990733},
     'max_val': 0.9774079407940794}

    运行交叉验证测试一下:

    rf = RandomForestClassifier(max_depth=6, max_features=0.39517, min_samples_split=2, n_estimators=250)
    np.mean(cross_val_score(rf, x, y, cv=20, scoring='roc_auc'))
    >>> 0.9754953

    得到最终结果是0.9755,比之前的0.9652提高了约0.01,做过kaggle的朋友都懂,这在后期已经是非常大的提高了!到后面想提高0.001都极其困难,因此bayes优化真的非常强大!

    结束!

    Reference

     二、Hyperopt
      安装:

    pip install hyperopt
    def q (args) :
        x, y = args
        return x ∗∗ 2 + y ∗∗ 2

    Hyperopt提供了一个优化接口,这个接口接受一个评估函数和参数空间,能计算出参数空间内的一个点的损失函数值。用户还要指定空间内参数的分布情况。 
    Hyheropt四个重要的因素:指定需要最小化的函数,搜索的空间,采样的数据集(trails database)(可选),搜索的算法(可选)。 
    首先,定义一个目标函数,接受一个变量,计算后返回一个函数的损失值,比如要最小化函数q(x,y) = x**2 + y**2:
     

    from hyperopt import hp
    space = [hp.uniform(’x’, 0, 1), hp.normal(’y’, 0, 1)]

    然后,定义一个参数空间,比如x在0-1区间内取值,y是实数,所以

    第三,指定搜索的算法,算法也就是hyperopt的fmin函数的algo参数的取值。当前支持的算法由随机搜索(对应是hyperopt.rand.suggest),模拟退火(对应是hyperopt.anneal.suggest),TPE算法。举个栗子:
     

    from hyperopt import hp, fmin, rand, tpe, space_eval
    best = fmin(q, space, algo=rand.suggest)
    print space_eval(space, best)

     搜索算法本身也有内置的参数决定如何去优化目标函数,我们可以指定搜索算法的参数,比如针对TPE,指定jobs:

     

    from functools import partial
    from hyperopt import hp, fmin, tpe
    algo = partial(tpe.suggest, n_startup_jobs=10)
    best = fmin(q, space, algo=algo)
    print space_eval(space, best)

    关于参数空间的设置,比如优化函数q,输入fmin(q,space=hp.uniform(‘a’,0,1)).hp.uniform函数的第一个参数是标签,每个超参数在参数空间内必须具有独一无二的标签。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)前闭后开的区间内的随机整数。 
    搜索空间可以含有list和dictionary.
     

    from hyperopt import hp
    list_space = [
    hp.uniform(’a’, 0, 1),
    hp.loguniform(’b’, 0, 1)]
    tuple_space = (
    hp.uniform(’a’, 0, 1),
    hp.loguniform(’b’, 0, 1))
    dict_space = {
    ’a’: hp.uniform(’a’, 0, 1),
    ’b’: hp.loguniform(’b’, 0, 1)}

    使用sample函数从参数空间内采样:
     

    from hyperopt.pyll.stochasti import sample
    print sample(list_space)
    # => [0.13, .235]
    print sample(nested_space)
    # => [[{’case’: 1, ’a’, 0.12‘}, {’case’: 2, ’b’: 2.3}],
    # ’extra_literal_string’,
    # 3]

    在参数空间内使用函数:
     

    from hyperopt.pyll import scope
    def foo(x):
    return str(x) ∗ 3
    expr_space = {
    ’a’: 1 + hp.uniform(’a’, 0, 1),
    ’b’: scope.minimum(hp.loguniform(’b’, 0, 1), 10),
    ’c’: scope.call(foo, args=(hp.randint(’c’, 5),)),
    }

    —————–这是一条有点短的昏割线———————————–

    在blog上发现了一段使用感知器判别鸢尾花数据的代码,使用的学习率是0.1,迭代40次得到了一个测试集上正确率为82%的结果。使用hyperopt优化参数,将正确率提升到了91%。

    from sklearn import datasets
    import numpy as np
    from sklearn.cross_validation import train_test_split
    from sklearn.metrics import accuracy_score
    iris = datasets.load_iris()
    X = iris.data
    y = iris.target
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
    
    
    from sklearn.preprocessing import StandardScaler
    sc = StandardScaler()
    sc.fit(X_train)
    X_train_std = sc.transform(X_train)
    X_test_std = sc.transform(X_test)
    
    from sklearn.linear_model import Perceptron
    ppn = Perceptron(n_iter=40, eta0=0.1, random_state=0)
    ppn.fit(X_train_std, y_train)
    
    y_pred = ppn.predict(X_test_std)
    print accuracy_score(y_test, y_pred)
    
    def percept(args):
        global X_train_std,y_train,y_test
        ppn = Perceptron(n_iter=int(args["n_iter"]),eta0=args["eta"]*0.01,random_state=0)
        ppn.fit(X_train_std, y_train)
        y_pred = ppn.predict(X_test_std)
        return -accuracy_score(y_test, y_pred)
    
    from hyperopt import fmin,tpe,hp,partial
    space = {"n_iter":hp.choice("n_iter",range(30,50)),
             "eta":hp.uniform("eta",0.05,0.5)}
    algo = partial(tpe.suggest,n_startup_jobs=10)
    best = fmin(percept,space,algo = algo,max_evals=100)
    print best
    print percept(best)
    #0.822222222222
    #{'n_iter': 14, 'eta': 0.12877033763511717}
    #-0.911111111111

    xgboost具有很多的参数,把xgboost的代码写成一个函数,然后传入fmin中进行参数优化,将交叉验证的auc作为优化目标。auc越大越好,由于fmin是求最小值,因此求-auc的最小值。所用的数据集是202列的数据集,第一列样本id,最后一列是label,中间200列是属性。
     

    #coding:utf-8
    import numpy as np
    import pandas as pd
    from sklearn.preprocessing import MinMaxScaler
    import xgboost as xgb
    from random import shuffle
    from xgboost.sklearn import XGBClassifier
    from sklearn.cross_validation import cross_val_score
    import pickle
    import time
    from hyperopt import fmin, tpe, hp,space_eval,rand,Trials,partial,STATUS_OK
    
    def loadFile(fileName = "E://zalei//browsetop200Pca.csv"):
        data = pd.read_csv(fileName,header=None)
        data = data.values
        return data
    
    data = loadFile()
    label = data[:,-1]
    attrs = data[:,:-1]
    labels = label.reshape((1,-1))
    label = labels.tolist()[0]
    
    minmaxscaler = MinMaxScaler()
    attrs = minmaxscaler.fit_transform(attrs)
    
    index = range(0,len(label))
    shuffle(index)
    trainIndex = index[:int(len(label)*0.7)]
    print len(trainIndex)
    testIndex = index[int(len(label)*0.7):]
    print len(testIndex)
    attr_train = attrs[trainIndex,:]
    print attr_train.shape
    attr_test = attrs[testIndex,:]
    print attr_test.shape
    label_train = labels[:,trainIndex].tolist()[0]
    print len(label_train)
    label_test = labels[:,testIndex].tolist()[0]
    print len(label_test)
    print np.mat(label_train).reshape((-1,1)).shape
    
    
    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
        print "max_depth:" + str(max_depth)
        print "n_estimator:" + str(n_estimators)
        print "learning_rate:" + str(learning_rate)
        print "subsample:" + str(subsample)
        print "min_child_weight:" + str(min_child_weight)
        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)
    

     

    展开全文
  • 吴恩达深度学习——参数调优

    千次阅读 2020-05-24 18:56:11
    本文主要介绍了如何进行参数调优,包括如何选择合适的范围。其次介绍了Batch Norm批归一化以及Softmax回归,最后简单介绍了一下TensorFlow。
  • GridSearchCV 超参调优

    2018-09-07 16:51:47
    http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html
  • 超参调优往往根据所谓的“经验值”,而超参往往对模型效果至关重要。调优的过程可视为“黑盒优化”,我们需要寻找一些方法来获取最优的超参数。 需要考虑的要素 目标函数,即算法需要最大化/最小化的目标。 ...
  • 参数调优方法整理大全

    千次阅读 2019-11-06 19:08:21
    机器学习中总是会碰见调这种枯燥无味且消耗时间的事情,所幸,有很多可以帮助你自动调的库以及相应的...参数优化也就是常说的调,python-sklearn里常用的有GridSearchCV和RandomizedSearchCV可以用。其中Gr...
  • 对于神经网络的参数调优而言,调大师们有时候也难免捉襟见肘(承认自己不行),如果单纯地依靠手动的方式进行参数选取调优,除非你觉得你的手够快(其实是机器足够快),你又有足够的耐心,那恭喜你加入手工调的...
  • 整理 | 凯隐编辑 | Jane出品 | AI科技大本营(ID:rgznai100)【导读】Optuna是一款为机器学习任务设计的自动参数优化软件框架,是一款按运行定义(define...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,213
精华内容 1,685
关键字:

超参调优