当前位置: 首页 > 编程日记 > 正文

如何提高模型性能?这四大方法值得尝试 | CSDN 博文精选

作者 | BoCong-Deng

编辑 | 屠敏

封图 | 自东方 IC

出品 | CSDN 博客

写在前面

在我们进行模型训练时,如果你只是想要让模型具有不错的性能,那么盲目地尝试网络架构足以达到目的。而在本文中, 我们将为你提供一套用于构建最先进深度学习模型的必备技术的快速指南,从而让模型由“具有不错的性能”上升到“性能卓越且满足我们的一些需要”。本文的叙述以及代码的编写时基于TensorFlow中Keras来进行表述的。

高级架构模式

残差连接

残差连接(residual connection)是一种常见的类图网络组件,在 2015 年之后的许多网络架构 (包括Xception)中都可以见到。2015 年末,来自微软的何恺明等人在ILSVRC ImageNet 挑战赛 中获胜,其中引入了这一方法。残差连接解决了困扰所有大规模深度学习模型的两个共性问题:梯度消失和表示瓶颈。

通常来说,向任何多于 10 层的模型中添加残差连接,都可能会有所帮助。残差连接是让前面某层的输出作为后面某层的输入,从而在序列网络中有效地创造了一条 捷径。前面层的输出没有与后面层的激活连接在一起,而是与后面层的激活相加(这里假设两 个激活的形状相同)。

如果它们的形状不同,我们可以用一个线性变换将前面层的激活改变成目标形状(例如,这个线性变换可以是不带激活的 Dense 层;对于卷积特征图,可以是不带激活 1×1 卷积)。如果特征图的尺寸相同,在 Keras 中实现残差连接的方法如下,用的是恒等残差连接(identity residual connection)。这个例子假设我们有一个四维输入张量 x。

from keras import layersx = ... y = layers.Conv2D(128, 3, activation='relu', padding='same')(x) y = layers.Conv2D(128, 3, activation='relu', padding='same')(y) y = layers.Conv2D(128, 3, activation='relu', padding='same')(y)  y = layers.add([y, x])

如果特征图的尺寸不同,实现残差连接的方法如下,用的是线性残差连接(linear residual connection)。同样,假设我们有一个四维输入张量 x。

from keras import layers  x = ... y = layers.Conv2D(128, 3, activation='relu', padding='same')(x) y = layers.Conv2D(128, 3, activation='relu', padding='same')(y) y = layers.MaxPooling2D(2, strides=2)(y)  residual = layers.Conv2D(128, 1, strides=2, padding='same')(x)    y = layers.add([y, residual])

批标准化

标准化(normalization)是一大类方法,用于让机器学习模型看到的不同样本彼此之间更加 相似,这有助于模型的学习与对新数据的泛化。最常见的数据标准化形式就是你已经在本书中 多次见到的那种形式:将数据减去其平均值使其中心为0,然后将数据除以其标准差使其标准 差为 1。实际上,这种做法假设数据服从正态分布(也叫高斯分布),并确保让该分布的中心为 0, 同时缩放到方差为 1。

normalized_data = (data - np.mean(data, axis=...)) / np.std(data, axis=...)

前面的示例都是在将数据输入模型之前对数据做标准化。但在网络的每一次变换之后都应该考虑数据标准化。即使输入 Dense 或 Conv2D 网络的数据均值为0、方差为1,也没有理由 假定网络输出的数据也是这样。

批标准化(batch normalization)是Ioffe 和 Szegedy 在 2015 年提出的一种层的类型 a(在 Keras 中是 BatchNormalization),即使在训练过程中均值和方差随时间发生变化,它也可以 适应性地将数据标准化。

  • 批标准化的工作原理是,训练过程中在内部保存已读取每批数据均值 和方差的指数移动平均值。

  • 批标准化的主要效果是,它有助于梯度传播(这一点和残差连接很 像),因此允许更深的网络。对于有些特别深的网络,只有包含多个 BatchNormalization 层 时才能进行训练。例如,BatchNormalization 广泛用于Keras 内置的许多高级卷积神经网络 架构,比如 ResNet50、Inception V3 和 Xception。

BatchNormalization 层通常在卷积层或密集连接层之后使用。

conv_model.add(layers.Conv2D(32, 3, activation='relu'))   conv_model.add(layers.BatchNormalization())  dense_model.add(layers.Dense(32, activation='relu'))   dense_model.add(layers.BatchNormalization())

BatchNormalization 层接收一个axis 参数,它指定应该对哪个特征轴做标准化。这 个参数的默认值是-1,即输入张量的最后一个轴。对于 Dense 层、Conv1D 层、RNN 层和将 data_format 设为 “channels_last”(通道在后)的 Conv2D 层,这个默认值都是正确的。但有少数人使用将 data_format 设为 “channels_first”(通道在前)的 Conv2D 层,这时 特征轴是编号为 1 的轴,因此 BatchNormalization 的 axis 参数应该相应地设为 1。

深度可分离卷积

如果我告诉你,有一个层可以替代 Conv2D,并可以让模型更加轻量(即更少的可训练权 重参数)、速度更快(即更少的浮点数运算),还可以让任务性能提高几个百分点,你觉得怎么样?我说的正是深度可分离卷积(depthwise separable convolution)层(SeparableConv2D)的作用。这个层对输入的每个通道分别执行空间卷积,然后通过逐点卷积(1×1 卷积)将输出通道混合,如下图。这相当于将空间特征学习和通道特征学习分开,如果你假设输入的 空间位置高度相关,但不同的通道之间相对独立,那么这么做是很有意义的。它需要的参数要少很多,计算量也更小,因此可以得到更小、更快的模型。因为它是一种执行卷积更高效的方法, 所以往往能够使用更少的数据学到更好的表示,从而得到性能更好的模型。

超参数优化

构建深度学习模型时,你必须做出许多看似随意的决定:应该堆叠多少层?每层应该 包含多少个单元或过滤器?激活应该使用 relu 还是其他函数?在某一层之后是否应该使用 BatchNormalization ?应该使用多大的dropout 比率?还有很多。这些在架构层面的参数叫作超参数(hyperparameter),以便将其与模型参数区分开来,后者通过反向传播进行训练。

在实践中,经验丰富的机器学习工程师和研究人员会培养出直觉,能够判断上述选择哪些 可行、哪些不可行。也就是说,他们学会了调节超参数的技巧。但是调节超参数并没有正式成 文的规则。如果你想要在某项任务上达到最佳性能,那么就不能满足于一个容易犯错的人随意 做出的选择。即使你拥有很好的直觉,最初的选择也几乎不可能是最优的。你可以手动调节你 的选择、重新训练模型,如此不停重复来改进你的选择,这也是机器学习工程师和研究人员大 部分时间都在做的事情。但是,整天调节超参数不应该是人类的工作,最好留给机器去做。

因此,你需要制定一个原则,系统性地自动探索可能的决策空间。你需要搜索架构空间, 并根据经验找到性能最佳的架构。这正是超参数自动优化领域的内容。这个领域是一个完整的 研究领域,而且很重要。

超参数优化的过程通常如下所示。

  • 选择一组超参数(自动选择)。

  • 构建相应的模型。

  • 将模型在训练数据上拟合,并衡量其在验证数据上的最终性能。

  • 选择要尝试的下一组超参数(自动选择)。

  • 重复上述过程。

  • 最后,衡量模型在测试数据上的性能。

这个过程的关键在于,给定许多组超参数,使用验证性能的历史来选择下一组需要评估的 超参数的算法。有多种不同的技术可供选择:贝叶斯优化、遗传算法、简单随机搜索等。训练模型权重相对简单:在小批量数据上计算损失函数,然后用反向传播算法让权重向正确的方向移动。与此相反,更新超参数则非常具有挑战性。我们来考虑以下两点。

  • 计算反馈信号(这组超参数在这个任务上是否得到了一个高性能的模型)的计算代价可能非常高,它需要在数据集上创建一个新模型并从头开始训练。

  • 超参数空间通常由许多离散的决定组成,因而既不是连续的,也不是可微的。因此,你通常不能在超参数空间中做梯度下降。相反,你必须依赖不使用梯度的优化方法,而这些方法的效率比梯度下降要低很多。

这些挑战非常困难,而这个领域还很年轻,因此我们目前只能使用非常有限的工具来优 化模型。通常情况下,随机搜索(随机选择需要评估的超参数,并重复这一过程)就是最好的 解决方案,虽然这也是最简单的解决方案。但有一种工具确实比随机搜索更好,它就是 Hyperopt。它是一个用于超参数优化的Python 库,其内部使用Parzen 估计器的树来预测哪组超 参数可能会得到好的结果。另一个叫作Hyperas 的库将Hyperopt 与 Keras 模型集成在一起。一 定要试试。

模型集成

想要在一项任务上获得最佳结果,另一种强大的技术是模型集成(model ensembling)。集 成是指将一系列不同模型的预测结果汇集到一起,从而得到更好的预测结果。观察机器学习竞赛, 特别是Kaggle 上的竞赛,你会发现优胜者都是将很多模型集成到一起,它必然可以打败任何单 个模型,无论这个模型的表现多么好。

集成依赖于这样的假设,即对于独立训练的不同良好模型,它们表现良好可能是因为不同 的原因:每个模型都从略有不同的角度观察数据来做出预测,得到了“真相”的一部分,但不 是全部真相。你可能听说过盲人摸象的古代寓言:一群盲人第一次遇到大象,想要通过触摸来 了解大象。每个人都摸到了大象身体的不同部位,但只摸到了一部分,比如鼻子或一条腿。这 些人描述的大象是这样的,“它像一条蛇”“像一根柱子或一棵树”,等等。这些盲人就好比机器 学习模型,每个人都试图根据自己的假设(这些假设就是模型的独特架构和独特的随机权重初 始化)并从自己的角度来理解训练数据的多面性。每个人都得到了数据真相的一部分,但不是 全部真相。将他们的观点汇集在一起,你可以得到对数据更加准确的描述。大象是多个部分的 组合,每个盲人说的都不完全准确,但综合起来就成了一个相当准确的故事。

我们以分类问题为例。想要将一组分类器的预测结果汇集在一起[即分类器集成(ensemble the classifiers)],最简单的方法就是将它们的预测结果取平均值作为预测结果。

preds_a = model_a.predict(x_val)   preds_b = model_b.predict(x_val) preds_c = model_c.predict(x_val) preds_d = model_d.predict(x_val)final_preds = 0.25 * (preds_a + preds_b + preds_c + preds_d)

只有这组分类器中每一个的性能差不多一样好时,这种方法才奏效。如果其中一个分类器 性能比其他的差很多,那么最终预测结果可能不如这一组中的最佳分类器那么好。

将分类器集成有一个更聪明的做法,即加权平均,其权重在验证数据上学习得到。通常来 说,更好的分类器被赋予更大的权重,而较差的分类器则被赋予较小的权重。为了找到一组好 的集成权重,你可以使用随机搜索或简单的优化算法(比如 Nelder-Mead 方法)。

preds_a = model_a.predict(x_val)  preds_b = model_b.predict(x_val)  preds_c = model_c.predict(x_val)  preds_d = model_d.predict(x_val)  final_preds = 0.5 * preds_a + 0.25 * preds_b + 0.1 * preds_c + 0.15 * preds_d

还有许多其他变体,比如你可以对预测结果先取指数再做平均。一般来说,简单的加权平均, 其权重在验证数据上进行最优化,这是一个很强大的基准方法。想要保证集成方法有效,关键在于这组分类器的多样性(diversity)。多样性就是力量。如 果所有盲人都只摸到大象的鼻子,那么他们会一致认为大象像蛇,并且永远不会知道大象的真 实模样。是多样性让集成方法能够取得良好效果。用机器学习的术语来说,如果所有模型的偏 差都在同一个方向上,那么集成也会保留同样的偏差。如果各个模型的偏差在不同方向上,那么这些偏差会彼此抵消,集成结果会更加稳定、更加准确。

版权声明:本文为CSDN博主「BoCong-Deng」的原创文章。

原文:

https://blog.csdn.net/DBC_121/article/details/107515163

推荐阅读

  • 98年“后浪”科学家,首次挑战图片翻转不变性假设,一作拿下CVPR最佳论文提名

  • 残差网络的前世今生与原理 | 赠书

  • 适合 Python 入门的 8 款强大工具

  • 芯片破壁:摩尔定律的一次次“惊险”续命

  • 观点 | ETH 2.0 经济模型分析报告简述

相关文章:

ORACLE11g 没有控制文件如何通过rman备份恢复数据的详细实战过程

1、副总裁需要裸恢复的严峻现实 集团总部的信息部负责人给我打电话说为了找一年前的记录,所以需要对一年前2015年5月1日的数据进行恢复。而2016年初因为进行迁移,所以有些文件可能丢失,手上只有rman全备文件,希望在一天之内找回&a…

C语言文件等题

1.#include <stdio.h>double fun(int n){ }main(){ int n; double s; printf("\nInput n: "); scanf("%d",&n); sfun(n); printf("\n\ns%f\n\n",s); NONO();}NONO(){/* 请在此函数内打开文件&#xff0c;输入测试数据&…

使用 Vml 制作立体柱状投票统计图的完整程序

作者&#xff1a;lshdic http://blog.csdn.net/lshdic/<!--以下便是完整的 JsVml 制作柱状投票统计图的完整程序,保存为HTM文件运行即可看到效果其中 array数组中的分组可以为6个也可以为2&#xff0c;3&#xff0c;4&#xff0c;5个等,运行以下程序需要您的浏览器支持VML…

Python, C++和Java代码互翻,Facebook开发首个自监督神经编译器

译者 | 刘畅出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;将早期的编程语言&#xff08;例如COBOL&#xff09;的代码库迁移到现在的编程语言&#xff08;例如Java或C&#xff09;是一项艰巨的任务&#xff0c;它需要源语言和目标语言方面的专业知识。COBOL如今仍在…

pinpoint的id的生成

traceId的生成 public String getTransactionId() {return TransactionIdUtils.formatString(agentId, agentStartTime, transactionSequence);}public static final String TRANSACTION_ID_DELIMITER "^";public static String formatString(String agentId, long …

X@X.X域名转向的实现

www.chinacs.net 中文C#技术站 当你看到csdncsdn.com时&#xff0c;你肯定把这当作电子邮件地址&#xff0c;其实这个不一定是邮件地址&#xff0c;有可能是域名。现在有越来越多的人开始使用这个形式的地址了。初看起来&#xff0c;你不要以为这个是一个什么非常了不起的技术&…

GPT-3 的到来,程序员会被 AI 取代吗?

无需任何训练&#xff0c;AI可用任何语言编程。作者 | Frederik Bussler译者 | 弯月&#xff0c;责编 | 晋兆雨头图 | CSDN 下载自东方 IC来源 | CSDN以下为译文&#xff1a;2017年的时候&#xff0c;曾有研究人员问&#xff1a;到2040年人工智能是否承担起大多数的编程工作&am…

iphone 下拉刷新控件 EGORefreshTableHeaderView 手动显示更新

参考资料:http://blog.csdn.net/ugg/article/details/7283661 在它基础上进行修改 EGORefreshTableHeaderView 绝对是ios开发中的必选插件,其用法就不再赘述. 为了能够手动的显示更新界面而不是要等到用户实际拖动才触发(比如程序刚启动时), 通过阅读它的代码可以发现,只要自己…

Eclipse create git repository failure(egit)

2019独角兽企业重金招聘Python工程师标准>>> 启动和创建的时候会出现这样的异常信息&#xff0c;具体处理办法如下&#xff1a; cd /path/to/yourRepo.git cd .. mkdir yourRepo mv yourRepo.git yourRepo cd yourRepo git config --local --bool core.bare false g…

如何用asp.net向其他服务器post一条信息

www.chinacs.net 中文C#技术站 using System;using System.Web;using System.Net;using System.IO;using System.Text;namespace SendMessage{ public bool SendMsg(MsgInfo msg){//create requesttry{WebRequest req WebRequest.Create("http://your_post_url");…

Directx11教程(11) 增加一个debug宏

现在我们在common.h中增加一个debug的宏&#xff0c;在每个d3d11函数后调用&#xff0c;如果d3d函数出错&#xff0c;它能够给出程序中错误的代码行数。 common.h代码如下&#xff1a; #pragma once #include <d3d11.h> #include <d3dx10math.h> #if defined(DEBUG…

为什么说机器学习是预防欺诈的最佳工具?

作者 | Giorgi Mikhelidze译者 | 天道酬勤&#xff0c;责编 | 晋兆雨头图 | CSDN付费下载自视觉中国随着现代技术的发展和完善&#xff0c;生活变得越来越舒适。虽然以前人们认为同时进行复杂的操作是不可能的&#xff0c;而如今计算机使这一任务变得很容易了。 与此同时&#…

集成支付宝钱包支付iOS SDK的方法与经验

没想到&#xff0c;支付宝的SDK是我目前用过的所有第三方SDK中最难用的一个了。 下载 首先&#xff0c;你要想找到这个SDK&#xff0c;都得费点功夫。现在的SDK改名叫移动支付集成开发包了&#xff0c;下载页面在 这里 的 “请点此下载集成开发包” Baidu和Googlep排在前面的支…

系统设计与架构笔记:ETL工具开发和设计的建议

好久没写博客了&#xff0c;不是自己偷懒&#xff0c;的确是没有时间哦。 最近项目组里想做一个ETL数据抽取工具&#xff0c;这是一个研发项目&#xff0c;但是感觉公司并不是特别重视,不重视不是代表它不重要&#xff0c;而是可能不会对这个项目要求太高&#xff0c;能满足我们…

如何获取主机的IP址址

http://www.aspcn.com 飞刀 &#xff08;如需转载&#xff0c;请注明文章来自http://www.aspcn.com 谢谢合作&#xff09; 这篇文章&#xff0c;我们不准备大规模的讨论技术问题。只是向大家介绍一下我们将如何获得一台主机的IP地址。在Win32 API中我们可以使用NetWork API完成…

炸裂!Google这波操作,预警了什么?

我们都知道谷歌爸爸收购了Cask Data一家公司。长期以来&#xff0c;谷歌致力于推动围绕 GoogleCloud 的企业业务&#xff0c;但在这方面一直被亚马逊和微软吊打&#xff0c;这次的收购正是为了弥补自身的短板。被收购的 Cask Data 是一家专门提供基于Hadoop的大型数据分析服务解…

百度地图设置div样式宽高为百分比不显示地图

如题&#xff0c;不显示地图只要在样式代码里面加以 position:absolute; 代码就可以了 <style type"text/css">body, html,#allmap {width:100%;height:100%;overflow: hidden;margin:0;font-family:"微软雅黑";position:absolute;}</style> 完…

在DataGrid中显示图片

兼谈 DadaGrid 模板列的创建DadaGrid 是 ASP.NET 编程中一个很重要的控件&#xff0c;其优良的可定制功能为提高它的表现力提供了极大的方便。除了与数据源直接绑定以外&#xff0c;我们还可以通过列绑定模板对 DataGrid 的列进行自定义&#xff0c;来按照我们设定的格式显示数…

程序员注意了!人社部“就业报告”:未来5年,这10个新职业有千万缺口

7月23日&#xff0c;人社部联合阿里钉钉发布了《新职业在线学习平台发展报告》&#xff0c;报告有两个核心思想&#xff1a;83%的80后遇到过职业危机&#xff0c;79%的90后担心失业。未来5年&#xff0c;物联网和人工智能人才缺口巨大&#xff0c;新职业人才需求高达千万 这上千…

编译内核出现make CONFIG_DEBUG_SECTION_MISMATCH=y错误

故障问题&#xff1a; 编译内核时出现“make CONFIG_DEBUG_SECTION_MISMATCHy” 错误提示&#xff1a; [rootserver linux-2.6.35.13]# make modules CHK include/linux/version.h CHK include/generated/utsrelease.h CALL scripts/checksyscalls.sh Build…

IOS UITabBarViewController 修改背景颜色

做iOS的都知道&#xff0c;每个项目都有UITabBarController。有的会自定义&#xff0c;有的采取系统&#xff0c;当时我也是用系统的&#xff0c;那时候还是小白&#xff0c;好多技术不太熟练&#xff0c;都用系统的&#xff0c;那时候还是1倍和2倍图片&#xff0c;那时候适配很…

ASP.NET的实时天气及24小时天气预报(C#)

ASP.NET的实时天气及24小时天气预报(C#) 修改其中的url获得其他城市的天气情况 如广州为&#xff1a; http://weather.yahoo.com/forecast/CHXX0037_c.html 注意仅适用于获得yahoo上的天气预报 GetWeather.aspx ----------------------------------- Weather24小时天气getWeath…

中科大硬核“毕业证”:“一生一芯”计划下,5位本科生带自研芯片毕业

作者 | 包云岗编辑 | 伍杏玲本文经作者授权转载自包云岗知乎【CSDN编者按】近日&#xff0c;中国科学院大学五位本科生的硬核“毕业证”引发IT圈热议&#xff0c;在“一生一芯”培养计划下&#xff0c;由五位2016级本科生主导完成一款64位RISC-V处理器SoC芯片设计并实现流片&am…

美团选择电影票

2019独角兽企业重金招聘Python工程师标准>>> 特点: 1可以放大 (两根手指),可以看到缩略图 2可以左右滑动 3上下滑动 步骤: 1绘制座位 在美团点击 转载于:https://my.oschina.net/yanglingui/blog/776852

邮件发送类,支持HTML格式,支持优先级设置

www.chinacs.net 2002-5-9 中文C#技术站 邮件发送类&#xff0c;支持HTML格式&#xff0c;支持优先级设置。通过SOCKET类实现的using System;using System.Text;using System.IO;using System.Net;using System.Net.Sockets; namespace Blood.Com.ClassLib{ /// <summary&…

手绘10张图,把CSRF跨域攻击、JWT跨域认证说得明明白白的

作者 | 写代码的明哥来源 | Python编程时光这篇文章本应该是属于 HTTP 里的一部分内容&#xff0c;但是我看内容也挺多的&#xff0c;就单独划分一篇文章来讲下。什么是跨域请求要明白什么叫跨域请求&#xff0c;首先得知道什么叫域。域&#xff0c;是指由 协议 域名 端口号 …

WYSE Thin Clinet 常用快捷键

1. 同时按住Ctrl Alt Up&#xff08;向上方向键&#xff09;&#xff0c;即可将远程连接由全屏状态切换到Window状态2. 同时按住Ctrl Alt Down&#xff08;向下方向键&#xff09;&#xff0c;即可在远程连接进程间切换&#xff08;类似于Windows系统的Alt Tab功能&…

CSS3模拟IOS滑动开关

前言 H5站点需要IOS滑动按钮的效果,想了想似乎CSS3能搞起,就折腾出来了...挺简单的..请看注释效果 代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <title>CSS3模拟IOS开关</title> <style t…

PyTorch 1.6、TensorFlow 2.3、Pandas 1.1同日发布!都有哪些新特性?

作者 | 肖智清出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;7月29日&#xff0c;PyTorch 1.6、TenorFlow 2.3、Pandas 1.1恰巧同时发布。这三个库都是定期滚动更新&#xff0c;大约每个季度更新一次小版本。在AI内卷化达到“灰飞烟灭”的今日&#xff0c;仅仅会对P…

ENC28j60以太网芯片驱动程序简介

转载&#xff1a; 本介绍可分为三块内容&#xff1a; 1.以太网数据帧结构 符合IEEE802.3标准的以太网帧的长度是介于64-1516字节之间。主要由目标MAC地址、源MAC地址、类型/长度字段、数据有效负载、可选填充字段和循环冗余校验组成&#xff0c;另外在通过以太网介质发送数据包…