专栏首页相约机器人设计神经网络的普及与设计方法

设计神经网络的普及与设计方法

很多初学者都会有这样的疑问,训练神经网络到底是什么?怎么进行设计?即使对于已经入门的人,在设计神经网络时也会有很多疑问,例如:什么是良好的学习率?应具有多少个隐藏层?dropout真的有用吗?为什么梯度消失了?

本文将为大家普及下神经网络的基础,以及针对神经网络的一些更令人困惑的方面进行分析,介绍一些有关神经网络设计的方法与策略。

1.基本的神经网络结构

输入神经元

  • 是神经网络用来进行预测的特征数量。
  • 输入向量每个特征需要对应一个输入神经元。对于结构化数据,是指数据集中属性的个数。需要从样本原型中仔细选择,并整理这些属性做为输入特征,同时要删除可能包含超出训练范围(导致过度拟合)的特征。对于图像数据,则是图像的尺寸(例如MNIST数据集中的输入为28 * 28 = 784)。

输出神经元

  • 输出神经元就是要做出的预测结果,主要分为回归和分类两种。
  • 回归任务:可以是一个值(例如,房屋价格)。对于多变量回归,每个预测值一个神经元(例如,对于边界框,它可以是4个神经元-边界框的高度,宽度,x坐标,y坐标每个神经元)。
  • 分类任务:又分为2分类和多分类。对于2分类(垃圾邮件而非垃圾邮件),每个显性类别对应一个输出神经元,其中输出表示显性类别的概率。对于多分类(例如,在物体检测中可以将实例分类为汽车,狗,房屋等),每个类别都对应一个输出神经元,并在输出层上使用softmax激活特征来确保最终概率总和为1。

隐藏层和每个隐藏层的神经元

  • 隐藏层的数量依赖于处理问题和神经网络的体系结构。实质上是在尝试找出一个适当的神经网络结构——不太大,也不太小,恰到好处。
  • 通常在数值分析领域中,1-5个隐藏层可以解决大多数问题。在处理图像或语音数据时,网络结构会比较复杂,需要上百个神经层。同时训练起来也需要花费很大的算力。当然,还可以使用一些预训练的模型(YOLO, ResNet, VGG),将这些网络的主要部分提取出来,放到自己的网络中,并在其基础之上训练模型。在这种情况下,模型仍然只需要训练后面自己添加的几层即可。
  • 对于某些数据集,拥有较大的第一层并在其后跟随较小的层将导致更好的性能,因为第一层可以学习很多较低层的特征,这些低层特征可以馈入后续层中的一些较高阶特征。
  • 每一层中的神经元越多,拟合能力越强;网络层数越多泛化能力越强。
  • 在手动设计时,建议从1–5层和1–100个神经元开始,然后慢慢添加更多的层和神经元,直到您开始过度拟合为止。还可以在“ 权重和偏差”的可视化图像中跟踪损失和准确性,以查看哪些隐藏层+隐藏神经元组合导致最佳损失。当然现在也有很多利用机器设计模型的算法,会使模型的产生更加智能。
  • 选择较小数目的层/神经元时要记住的一点,如果此数目太小,网络将无法学习数据中的基础模式。解决此问题的方法是从大量的隐藏层+隐藏的神经元开始,然后使用dropout和提早停止方法来减小神经网络的大小。
  • 还可以采用过 拟合然后正则化的方法——“首先将模型放大到足以使其过拟合(即专注于训练损失),然后适当地对其进行正则化(放弃一些训练损失以改善验证损失)。”

损失函数

  • 回归:均方误差是要优化的最常见损失函数,除非存在大量异常值。一般请况下,可以使用平均绝对误差或Huber损失。
  • 分类: 通常使用交叉熵 。

批次大小

  • 尽量使用大批次进行处理,因为它们可以利用GPU的特征来每次处理更多的训练实例。 OpenAI已发现较大的批处理大小(用于图像分类 和 语言建模的批处理大小为数万,对于 RL代理而言为数百万 )对于缩放和并行化非常有用。
  • 但是这也不绝对,在某种请况下,增加批次数量会降低可接受的学习率范围,从而影响模型稳定训练的收敛性。通常,通过2到32之间的小批次训练可以获得很好的性能。
  • 如果数据规模不是很大,建议从较小批次开始,然后逐渐增加大小并在训练结果的输出曲线中监视性能以确定最佳拟合。

迭代次数

  • 建议从大的迭代次数开始,并使用“早期停止”来停止训练,直到性能不再提高。

样本属性的数值范围

  • 在训练之前确保所有样本属性的数值范围相似——用归一化进行处理。这样才能使模型更快的收敛。当样本属性的数值范围不同(例如,数千美元的薪水和数十年的经验)时,损失函数将偏重于范围大的一方。这意味着与使用归一化特征相比,模型更加难于训练。

2.学习率

  • 选择学习速度非常重要,每当调整网络的其他超参数时,都需要重新调整学习率。
  • 为了找到最佳的学习率,可以从一个非常低的值(10 ^ -6)开始,然后将其慢慢乘以一个常数,直到达到一个非常高的值(例如10)。在训练曲线中衡量模型的性能(相对于学习率的日志),以确定哪种速率最适合。然后,可以使用此学习率来重新训练模型。
  • 当然在一些兼容性比较好的优化器上,学习率的重要性会相对减弱。
  • 通常,使用SGD优化器时,配合手动的学习率查找器方法,可以训练出最佳模型。

3.动量

  • 梯度下降朝着局部极小值采取微小且一致的步骤,而当梯度很小时,收敛可能需要很多时间。另一方面,动量考虑了以前的梯度,并通过更快地越过谷底并避免局部最小值来加速收敛。
  • 通常,希望动量值非常接近1。对于较小的数据集,0.9是一个很好的起点,并且您希望逐渐接近更大的数据集(0.999)。(设置nesterov = True可使动量将成本函数的梯度考虑到当前点之前几步,从而使其更准确,更快。)

4.消失+爆炸梯度

  • 就像人一样,并非所有的神经网络层都以相同的速度学习。因此,当反向传播算法将误差梯度从输出层传播到第一层时,该梯度变得越来越小,直到到达第一层时几乎可以忽略不计。这意味着第一层的权重不会在每个步骤中显着更新。
  • 这是梯度消失的问题 。(当某些图层的梯度逐梯度大时,会出现类似的爆炸梯度问题,从而导致某些图层相对于其他图层的权重更新很大。)

激活函数

常用的激活函数按以下顺序如下(从最低→最高性能):logistic → tanh → ReLU → Leaky ReLU → ELU → SELU。

ReLU是最流行的激活函数,如果您不想调整激活函数,ReLU是一个很好的起点。但是, ReLU的有效性不如 ELU 或 GELU。

另外还可以尝试以下几种很有特点的激活函数:

  • 可以缓解神经网络过度拟合的激活函数:RReLU
  • 可以减少运行时延迟的激活函数:Leaky ReLU
  • 用于大规模训练集的激活函数:PReLU
  • 快速推理的激活函数:Leaky ReLU
  • 提升范化的激活函数:ELU
  • 强大的整体激活函数:SELU

要善于尝试一些不同的激活函数,然后观察训练效果!

输出层的激活函数

回归: 回归问题不需要为其输出神经元激活函数,输出可以采用任何值。如果要将值限制在某个范围内的情况下,可以用tanh输出-1→1的值,并将logistic函数用于0→1值。如果只是需要正输出,则可以使用softplus激活函数。

分类: 使用Sigmoid激活函数进行二分类,以确保输出介于0和1之间。使用softmax进行多分类,以确保输出概率加起来为1。

权重初始化方法

  • 正确的权重初始化方法可以大大加快收敛时间。初始化方法的选择取决于激活函数。可以尝试的一些事情:
  • 使用ReLU或Leaky RELU时,建议使用 He初始化
  • 使用SELU或ELU时,建议使用 LeCun初始化
  • 使用softmax,logistic或tanh时,建议使用 Glorot初始化
  • 大多数初始化方法具有统一和正态分布的特点。

批次标准

  • BatchNorm只需学习各层输入的最佳方式和规模。它通过零中心化和归一化其输入向量,然后缩放和移动它们来实现。它也像正则化器一样工作,这意味着不需要dropout或L2 reg。
  • 使用BatchNorm可以使用更大的学习率(这将导致更快的收敛),并通过减少消失梯度的问题而导致大多数神经网络的巨大改进。唯一的缺点是由于每层都需要额外的计算,因此会稍微增加训练时间。

梯度裁剪

  • 减少梯度以免爆炸的一种好方法,尤其是在训练RNN时,是在超过特定值时简单地裁剪。建议尝试使用clipnorm而不是clipvalue,这样可以使梯度矢量的方向保持一致。Clipnorm包含l2范数大于某个阈值的任何梯度。
  • 尝试一些不同的阈值,以找到最适合的阈值。

提前停止

  • 提前停止可使通过训练具有更多隐藏层,隐藏神经元和所需时间段更多的模型来实现它,并在性能连续连续n个周期停止改善时停止训练。它可以保存性能最佳的模型。可以通过在适合模型时设置回调并设置save_best_only = True来启用Early Stopping。

5.dropout

  • Dropout是一种出色的正则化技术,可让您大幅提高性能(对于最先进的模型而言,性能提高约2%),因为该技术实际上是如此简单。在每个训练步骤中,所有dropout行为都是随机关闭每一层神经元的百分比。这使网络更加健壮,因为它不能依赖任何特定的输入神经元集合来进行预测。知识分布在整个网络中。在训练过程中会生成大约2 ^ n(其中n是体系结构中神经元的数量)的稍微唯一的神经网络,并将其整合在一起以进行预测。
  • 良好的dropout率介于0.1到0.5之间,对于RNN来说,是0.3,对于CNN来说,是0.5。对较大的图层使用较大的费率。增加dropout率可减少过度拟合,而降低dropout率则有助于防止过度拟合。
  • 要在网络的较前层中尝试不同的dropout率,并查看训练曲线以选择效果最好的丢弃率。绝对不要在输出层中使用dropout。

6.优化器

  • 一般建议是,如果非常关注收敛质量并且时间不是很重要的话,请使用随机梯度下降。
  • 如果关心收敛时间,并且接近最佳收敛点就足够了,请尝试使用Adam,Nadam,RMSProp和Adamax优化器!
  • Adam/Nadam 通常是一个很好的起点,并且倾向于兼容学习速度不佳和其他非最优的超参数。
  • 在卷积网络中,一个经过手动调整的SGD,总是会胜过Adam。”
  • 另外Nadam也是非常好的优化器, Nadam是使用Nesterov技术的常规Adam优化器,因此收敛速度比Adam快。

7.学习率调度

  • 在训练中,不希望学习率过高,以免成本函数围绕最优值跳动并产生差异。也不希望学习率太低,因为这意味着收敛将花费很长时间。
  • 较高和较低的学习率都有其优势,可以通过学习速率调度,从更高的速率开始,以便更快地通过梯度斜率,并在到达超参数空间中的梯度谷时降低速度,需要采取较小的步骤。
  • 有许多种调度学习率的方法,包括成倍地降低学习率,使用步进函数或在性能开始下降或使用1周期计划时对其进行调整。
  • 在训练完所有其他超参数之前,可以使用恒定的学习率。并最终实现学习率衰减调度。

总结

在这篇文章探讨了神经网络许多方面的知识点,包括如何建立基本的神经网络(包括选择隐藏层数,隐藏神经元,批次大小等)。希望这些方法能够对你有所帮助。

本文分享自微信公众号 - 相约机器人(xiangyuejiqiren),作者:代码医生

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 22个深度学习面试问题

    3)使人们对模型有更好的理解-我们可以查看过滤器的权重并可视化网络“学习”的内容。

    代码医生工作室
  • 重回榜首的BERT改进版开源了,千块V100、160GB纯文本的大模型

    BERT 自诞生以来就展现出了卓越的性能,GLUE 排行榜上前几名的模型一度也大多使用 BERT。然而,XLNet 的横空出世,打破了 BERT 的纪录。不过,...

    代码医生工作室
  • PyTorch如何加速数据并行训练?分布式秘籍大揭秘

    在芯片性能提升有限的今天,分布式训练成为了应对超大规模数据集和模型的主要方法。本文将向你介绍流行深度学习框架 PyTorch 最新版本( v1.5)的分布式数据...

    代码医生工作室
  • 深度学习三人行(第4期)---- TF训练DNN之进阶

    智能算法
  • Yoshua Bengio:在能量模型中使用提前推断近似反向传播

    用户1737318
  • 《机器学习实战:基于Scikit-Learn、Keras和TensorFlow》第11章 训练深度神经网络

    第 10 章介绍了人工神经网络,并训练了第一个深度神经网络。 但它非常浅,只有两个隐藏层。 如果你需要解决非常复杂的问题,例如检测高分辨率图像中的数百种类型的对...

    SeanCheney
  • 《Scikit-Learn与TensorFlow机器学习实用指南》 第4章 训练模型

    在之前的描述中,我们通常把机器学习模型和训练算法当作黑箱来处理。如果你动手练习过前几章的一些示例,就能惊奇地发现优化回归系统、改进数字图像的分类器、甚至可以零基...

    SeanCheney
  • 机器学习三人行(系列五)----你不了解的线性模型(附代码)

    到目前为止,我们已经将机器学习模型和他们的训练算法大部分视为黑盒子。 如果你经历了前面系列的一些操作,如回归系统、数字图像分类器,甚至从头开始建立一个垃圾邮件分...

    智能算法
  • SQL Sever基本知识

    create table tablename(col_name1 type,col_name2 type,...) 在数据库school下创建一个student...

    慕白
  • 快速寻找同源基因---自动化运行OrthoMCL

    OrthoMCL (http://orthomcl.org/orthomcl/) 是现在用的最多的一款来找直系同源基因(Orthologs)以及旁系同源基因 (...

    阿凡亮

扫码关注云+社区

领取腾讯云代金券