30、机器学习模型优化全解析

机器学习模型优化全解析

在机器学习领域,为了提升模型性能,我们常常需要考虑使用更复杂的模型。下面就来详细探讨几种有效的模型优化方法。

深度神经网络模型

在TensorFlow playground的示例应用中,分类器的目标是将蓝色点和橙色点分开。输入为每个点的两个坐标X1和X2。第一个神经元计算X1和X2的加权和,ReLU神经元学习到的分离面是一条线,如图1所示。

graph LR
    A[输入X1和X2] --> B[第一个神经元计算加权和]
    B --> C[学习到一条线]

第二个ReLU神经元为输入参数学习不同的权重,即不同的线。单个神经元并不是很好的分类器,但隐藏层中有四个这样的神经元,它们的组合最终形成一个多边形,能够很好地对输入数据进行分类,如图2所示。

对于更复杂的布局,单个多边形可能不够,需要多层网络构建由多个多边形组成的分离面。增加网络的复杂度(如添加更多节点)有助于神经网络学习更复杂的形状,不过网络只是用多边形近似模式,学习范围受数据限制。

需要注意的是,前面的示例是针对二维输入的可视化,在实际问题中,输入更多,分离面和多边形的类比会失效,但理解隐藏层神经元组合形成分离超平面是有帮助的。

嵌入技术

逻辑回归可以看作是输入的加权和后接一个S形激活函数。为了引入更多自由参数并学习更复杂的分离面,可以引入隐藏层神经元。每个神经元计算输入的加权和并通过激活函数(如ReLU),不同神经元的权重不同,专门进行不同的线性分离,整体分类器是这些线性分离器的组合。

在神经网络中,直接使用实值数字没问题,但直接在深度神经网络中使用独热编码的稀疏列并不可取。例如,将“origin”变量离散化为1000个桶,独热编码会产生1000列的极稀疏矩阵。为避免列数爆炸,可对分类字段进行降维,即嵌入技术。

在TensorFlow中,可使用嵌入列对稀疏列进行降维,代码如下:

def create_embed(sparse_col):
    nbins = col.bucket_size
    dim = 1 + int(round(np.log2(nbins)))
    return tflayers.embedding_column(sparse_col, dimension=dim)

该代码将稀疏列嵌入到(1 + log2N)个值中,N是该列的桶数。例如,有1024个值的列将被量化为11个分量的向量,量化的权重由神经网络训练过程确定。

创建稀疏列的嵌入后,使用深度神经网络就很简单了。使用实值列,对所有稀疏列创建嵌入,然后从实值和嵌入的稀疏列创建深度神经网络,代码如下:

def dnn_model(output_dir):
    real, sparse = get_features()
    all = {}
    all.update(real)
    embed = {
        colname : create_embed(col) \
            for colname, col in sparse.items()
    }
    all.update(embed)
    estimator = tflearn.DNNClassifier(model_dir=output_dir,
                                      feature_columns=all.values(),
                                      hidden_units=[64, 16, 4])
    estimator.params["head"]._thresholds = [0.7]
    return estimator

该网络有三个隐藏层,分别有64、16和4个神经元,默认使用ReLU激活函数。关于层数和神经元数量,通常从近似输入节点数开始,后续层逐渐减少,但具体还需实验确定。

以下是使用嵌入技术创建稀疏列的实验结果:
| 实验编号 | 模型 | 特征 | RMSE |
| ---- | ---- | ---- | ---- |
| 1(方便重复) | 线性 | 所有输入原样 | 0.196 |
| 4 | 深度神经网络 | 所有输入变量,嵌入到log2N | 0.196 |

可以看到,单独使用深度神经网络并没有比逻辑回归模型有性能提升,这表明在机器学习中,数据工程比数据科学可能带来更大回报。

宽深模型

在放弃模型改进之前,可尝试宽深模型。该模型由两部分组成:一部分是将输入直接连接到输出的线性模型;另一部分是通过深度神经网络连接输入和输出。将稀疏列放在线性部分,实值列放在深度部分。

对于精度过高可能导致过拟合的实值列,可进行离散化并转换为分类列。还可对组合效果好的分类特征应用特征交叉,例如颜色和尺寸的特征交叉会产生颜色 - 尺寸组合的稀疏列。

以航班数据为例,出发和到达机场的纬度和经度本身对航班是否晚点影响不大,但机场位置和城市对之间的航线有影响。可将纬度和经度离散化并交叉桶,将国家划分为网格,代码如下:

latbuckets = np.linspace(20.0, 50.0, nbuckets).tolist()  # USA
lonbuckets = np.linspace(-120.0, -70.0, nbuckets).tolist() # USA
disc = {}
disc.update({
    'd_{}'.format(key) : tflayers.bucketized_column(real[key], latbuckets) \
        for key in ['dep_lat', 'arr_lat']
})
disc.update({
    'd_{}'.format(key) : tflayers.bucketized_column(real[key], lonbuckets) \
        for key in ['dep_lon', 'arr_lon']
})
sparse['dep_loc'] = tflayers.crossed_column([disc['d_dep_lat'], 
                          disc['d_dep_lon']], nbuckets*nbuckets)
sparse['arr_loc'] = tflayers.crossed_column([disc['d_arr_lat'],
                         disc['d_arr_lon']], nbuckets*nbuckets)
sparse['dep_arr'] = tflayers.crossed_column([sparse['dep_loc'],
                         sparse['arr_loc']], nbuckets ** 4)
sparse['ori_dest'] = tflayers.crossed_column([sparse['origin'],
                         Sparse['dest'], hash_bucket_size=1000)

对稀疏列创建嵌入并更新实值列后,创建宽深模型,代码如下:

estimator = \
    tflearn.DNNLinearCombinedClassifier(model_dir=output_dir,
                             linear_feature_columns=sparse.values(),
                             dnn_feature_columns=real.values(),
                             hidden_units=[64, 16, 4])

使用改进后的模型和额外的工程特征进行训练,能获得更好的性能,如下表所示:
| 实验编号 | 模型 | 特征 | RMSE |
| ---- | ---- | ---- | ---- |
| 1(方便重复) | 线性 | 所有输入原样 | 0.196 |
| 5 | 宽深模型 | 所有输入变量,特征交叉,嵌入 | 0.187 |

使用更合适的机器学习模型和反映人类对问题洞察的特征,有助于提高模型性能。

超参数调优

在模型中,有很多选择是随意的,如层数、隐藏节点数、批量大小、离散化的桶数等。这些选择会影响模型性能,过多或过少的层可能导致次优分类或过拟合,批量大小过大会降低优化器对特定数据点的敏感性,桶数选择不当会影响模型的区分能力或导致过拟合。

为了找到最佳参数组合,可使用Cloud ML Engine的非线性超参数调优功能。具体步骤如下:
1. 模型修改 :
- 添加超参数评估指标,例如:

eval_metrics = {
    'rmse' : tflearn.MetricSpec(metric_fn=my_rmse, prediction_key='probabilities'),
    'training/hptuning/metric' : tflearn.MetricSpec(metric_fn=my_rmse, prediction_key='probabilities')
}
- 更改输出目录,避免不同运行相互覆盖:
output_dir = os.path.join(
    output_dir,
    json.loads(
        os.environ.get('TF_CONFIG', '{}')
    ).get('task', {}).get('trial', '')
)
- 为每个超参数添加命令行参数,例如:
parser.add_argument(
    '--batch_size',
    help='Number of examples to compute gradient on',
    type=int,
    default=512
)
  1. 超参数配置文件 :
trainingInput:
  scaleTier: STANDARD_1
  hyperparameters:
    goal: MINIMIZE
    maxTrials: 50
    maxParallelTrials: 5
    params:
    - parameterName: batch_size
      type: INTEGER
      minValue: 16
      maxValue: 512
      scaleType: UNIT_LOG_SCALE
    - parameterName: nbuckets
      type: INTEGER
      minValue: 5
      maxValue: 10
      scaleType: UNIT_LINEAR_SCALE
    - parameterName: hidden_units
      type: CATEGORICAL
      categoricalValues: ["64,16", "64,16,4", "64,64,64,8", "256,64,16"]   

该文件指定了超参数的搜索空间,如批量大小在16到512之间以对数尺度搜索,桶数在5到10之间线性分布,隐藏单元指定了几个候选值。

  1. 运行超参数调优 :
    使用 gcloud 提交超参数调优作业,与提交训练作业类似,只是多了指向配置文件的参数:
gcloud ml-engine jobs submit training $JOBNAME \
  --region=$REGION \
  --module-name=trainer.task \
  --package-path=$(pwd)/flights/trainer \
  --job-dir=$OUTPUT_DIR \
  --staging-bucket=gs://$BUCKET \
  --config=hyperparam.yaml \
  -- \
  --output_dir=$OUTPUT_DIR \
  --traindata $DATA_DIR/train$PATTERN \
  --evaldata $DATA_DIR/test$PATTERN \
  --num_training_epochs=5

通过超参数调优,能找到更合适的参数组合,但要注意,虽然调优可能带来性能提升,但特征工程对模型性能的影响更为显著。例如,添加关键特征可将RMSE从0.25降至0.19,而添加额外层带来的RMSE改进不到0.01。

更改学习率

在超参数调优接近尾声时,可尝试更改学习率。损失函数的波动可能意味着需要降低学习率,同时,目前增加层仍有帮助,可尝试四、五、六层网络。批量大小可降至100,但不宜降至16,以免训练过慢且损失函数波动增大。

在使用Estimator API时,更改学习率并不容易,因为它屏蔽了底层细节。但可以将学习率作为命令行参数传递给创建模型的函数。 DNNLinearCombinedClassifier 使用两个优化器(FtrlOptimizer和AdagradOptimizer),为简单起见,可让深度列的学习率是宽列学习率的四分之一,代码如下:

def wide_and_deep_model(output_dir, 
                        nbuckets=5, hidden_units='64,32', learning_rate=0.01):
    ...
    estimator = \
        tflearn.DNNLinearCombinedClassifier(model_dir=output_dir,
               linear_feature_columns=sparse.values(),
               dnn_feature_columns=real.values(),
               dnn_hidden_units=parse_hidden_units(hidden_units),
               linear_optimizer=tf.train.FtrlOptimizer(
                             learning_rate=learning_rate),
               dnn_optimizer=tf.train.AdagradOptimizer(
                                learning_rate=learning_rate/4))

注意,要设置学习率,必须传入适当初始化的优化器对。

通过以上一系列的模型优化方法,从深度神经网络到宽深模型,再到超参数调优和学习率调整,我们可以逐步提升机器学习模型的性能,但在整个过程中,要始终重视特征工程的重要性。

机器学习模型优化全解析

超参数调优结果分析

在运行超参数调优后,会得到各种试验的输出结果。我们可以使用TensorFlow自带的TensorBoard工具来监控输出目录。例如,某次试验中,损失函数出现波动,尽管在小批量计算时有些波动是正常的,但即使是平滑后的曲线收敛也不稳定,这表明可能需要降低学习率。

以下是部分试验的结果:
| 试验编号 | 最终指标(RMSE) | 训练步数 | 超参数(批量大小,隐藏单元,桶数) |
| ---- | ---- | ---- | ---- |
| 1 | 0.202596 | 3559 | 170,64,16,6 |
| 2 | 0.186319 | 33637 | 16,64,64,64,8,10 |
| 18 | 0.187016 | 5097 | 100,64,16,4,5 |

从这些结果可以看出,不同的超参数组合对模型性能有不同的影响。最小的批量大小、最多的隐藏层和最大的桶数组合取得了较好的结果,但与更简单的网络模型相比,性能提升并不显著。这再次强调了特征工程的重要性,我们通过添加关键特征能够实现更大幅度的RMSE降低,而增加网络层数带来的提升相对较小。

深入理解模型组件

为了更好地优化模型,我们需要深入理解模型的各个组件。例如,在宽深模型中,线性部分和深度部分的作用不同。线性部分直接连接输入和输出,对于稀疏列的处理更为有效;深度部分通过神经网络能够学习到更复杂的模式。

下面是宽深模型的工作流程mermaid流程图:

graph LR
    A[输入数据] --> B[分离实值列和稀疏列]
    B --> C[实值列直接使用]
    B --> D[稀疏列进行嵌入处理]
    C --> E[构建深度部分]
    D --> E
    D --> F[构建线性部分]
    E --> G[DNN部分计算]
    F --> H[线性部分计算]
    G --> I[合并结果]
    H --> I
    I --> J[输出预测结果]

在这个流程中,输入数据首先被分离为实值列和稀疏列。实值列直接用于构建深度部分,稀疏列则先进行嵌入处理,一部分用于深度部分,一部分用于线性部分。最后,将两部分的计算结果合并得到最终的预测结果。

持续优化的思路

在完成一轮超参数调优和模型训练后,我们不能满足于当前的结果,而应该持续探索优化的可能性。以下是一些持续优化的思路:
1. 增加特征 :继续挖掘与问题相关的特征,例如在航班延误预测中,可以考虑天气数据、机场繁忙程度等因素。
2. 尝试不同的模型架构 :除了宽深模型,还可以尝试其他类型的神经网络模型,如卷积神经网络(CNN)或循环神经网络(RNN),根据问题的特点选择合适的模型。
3. 优化数据处理流程 :检查数据清洗、预处理等步骤,确保数据的质量和一致性。例如,处理缺失值、异常值等。
4. 调整超参数范围 :根据上一轮超参数调优的结果,缩小或扩大某些超参数的范围,进行更精细的调优。

总结与展望

在机器学习模型优化的过程中,我们涉及了多种方法,包括深度神经网络模型、嵌入技术、宽深模型、超参数调优等。这些方法相互配合,能够逐步提升模型的性能。但需要注意的是,特征工程始终是提升模型性能的关键因素,它能够为模型提供更有价值的信息。

未来,随着数据量的不断增加和计算能力的提升,我们可以尝试更复杂的模型和更精细的调优策略。同时,结合领域知识和人类的洞察力,能够更好地理解问题和优化模型。例如,在航班延误预测中,结合航空领域的专业知识,能够更准确地选择特征和调整模型。

总之,机器学习模型优化是一个持续的过程,需要不断地尝试和探索,以找到最适合问题的解决方案。通过本文介绍的方法和思路,希望能够为你在模型优化的道路上提供一些帮助。

相关推荐

SIMPLIS实战:从零构建理想BUCK电路,精准计算与POP稳态分析

本文详细介绍了如何使用SIMPLIS软件从零开始构建并仿真一个理想的BUCK降压电路。通过设定关键参数、计算理想器件值,并搭建仿真模型,文章重点演示了暂态仿真以观察电路上电过程,并深入讲解了高效的POP(周期性工作点)稳态分析技术,帮助工程师快速验证设计、评估稳态性能,从而加速电源设计迭代。

weixin_29165465的博客 392

别再混淆了!一张图看懂SAP特殊采购类30/40/70/80的区别与选型指南

本文深度解析SAP特殊采购类30/40/70/80的核心逻辑与业务影响,通过对比框架和真实案例帮助用户掌握其适用边界。重点介绍委外加工(类型30)、工厂间转移(类型40/70)及计划与执行分离(类型80)的配置要点与常见问题,提供选型决策树和实施检查清单,助力企业优化供应链管理。

weixin_26938645的博客 450

手把手教你用Switched-Capacitor Converter实现高效DC-DC转换(附常见拓扑对比)

本文详细介绍了开关电容转换器(SC)在高效DC-DC电源设计中的应用,对比了四种常见拓扑结构的优缺点,并提供了损耗分析与效率优化的实战技巧。通过无电感设计,SC转换器在5G模块和可穿戴设备中展现出超高功率密度和微小体积的优势,是电源管理领域的革命性技术。

weixin_30790841的博客 272

基于FPGA的AGC自适应增益控制系统开发

自动增益控制(AGC)是一种在接收信号过程中自动调整放大器增益的技术,以确保输出信号的幅度保持在一个恒定的水平。基于FPGA实现AGC系统具有高性能、低延迟和高度可配置的特点,广泛应用于无线通信、音频处理和雷达等领域。FPGA上的AGC系统提供了一种高效且灵活的方法来处理变化的信号环境。在实际应用中,通过合理的设计和优化,可以显著提高信号处理系统的鲁棒性和可靠性。

走向CTO的路上... 1694

Matlab 轴承信号仿真+分析

文章目录项目说明1、信号仿真1.1 仿真公式1.2 信号参数设置1.3 代码实现2、仿真信号分析2.1 小波变换2.2 快速谱峭度 项目说明 本文主要解决两个问题: 1、仿真包含周期性冲击信号、随机干扰冲击信号、调制干扰信号以及随机噪声四个成分的故障轴承信号; 2、使用小波变换以及快速谱峭度对该仿真信号进行分析。 1、信号仿真 1.1 仿真公式 这里的仿真信号公式主要参考了包文杰学者的硕士论文《加权谱峭度故障诊断方法研究与应用》,列举公式如下: 周期性冲击信号仿真 随机干扰冲击信号仿真 调制

cocofisher的博客 9267

【第33话:车辆控制】自动驾驶车辆运动学模型推导及详解

自动驾驶车辆的运动学模型以自行车模型为核心,通过状态方程。

一碗白开水一 830

基于STM32设计的水下水质检测装置(微信小程序)(205)

本项目设计了一款基于STM32微控制器为核心的水下水质检测设备,该设备具有高度集成化、智能化的特点,能够实时监测水深、温度、浊度及溶解性总固体(TDS)等关键水质参数,并通过4G网络将数据上传至腾讯云IOT物联网平台,实现远程监控和数据分析。同时,为了便于操作和移动观测,还配套开发了微信小程序,用户可通过微信小程序实时查看并控制设备的各项功能,如调整下潜深度等。

1250

ADS1115 0-10V高精度ADC模块原理图设计,已量产

在水质监测、智能气象站、环境感知等领域,0-10V 电压输出的传感器占据了重要地位。这类传感器输出信号稳定、抗干扰能力强,但对数据采集模块的精度、线性度和易用性提出了严苛要求。本文将深度解析一款专为 0-10V 传感器设计的高精度 ADC 模块,从硬件架构、性能指标到工程化实践,全面呈现其设计思路与核心价值。

不脱发的程序猿 272

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

上一篇: 29、使用 TensorFlow 构建航班准点预测模型
下一篇: 31、机器学习模型调优、部署与实时应用全解析
cuda7parallel
博客等级 码龄1天 0粉丝 1273原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值