什锦甜、倪倪、胡笳、云舟编译

机器都会学习了,你的神经网络还跑不动?来看看这些建议

在很多机器学习的实验室中,机器已经进行了上万小时的训练。在这个过程中,研究者们往往会走很多弯路,也会修复很多bug,但可以肯定的是,在机器学习的研究过程中,学到经验和知识的并不仅仅是机器,我们人类也积累了丰富的经验,本文就将给你几条最实用的研究建议。

接下来本文将介绍一些训练深度神经网络时的经验(主要基于TensorFlow平台)。有些建议可能对你来说很显而易见,但对其他人来说可能很重要。有些建议可能对某些特定任务并不适用,请谨慎使用!

一般性建议

使用 ADAM优化器。和批量梯度下降等传统优化器相比,Adam优化器效果更好。

TensorFlow使用建议:保存和恢复权重时,记得在创建Adam优化器后创建Saver,因为Adam也有state(也叫学习速率的单位权重)需要恢复。

Relu是最好的非线性映射激活函数)。就像 Sublime是最好的文本编辑器, ReLU快速、简单,神奇的地方在于它在训练过程中不会逐渐减少梯度。虽然教科书中常用sigmoid作为激活函数,但是它在DNN中不能很好地传递梯度。

不要在输出层用激活函数。这一点应该很明显,但是如果你在构建网络的每一层都使用了一个共享的函数,那这个错误就很常见了。请确保你在输出层没有使用激活函数

在每一层中增加一个偏差值。这是机器学习入门知识:偏差本质上的作用是把一个平面转化到最佳拟合位置。在y=mx+b函数中, b就是一个偏差值,可以把直线移动到最佳拟合的位置。

使用方差缩放初始化(variance-scaled initialization)。在Tensorflow中,使用类似于tf.contrib.layers.variance_scaling_initializer()这样的方法初始化。

根据我们的经验,这个方法比常规的高斯分布初始化,截断正态分布初始化和Xavier初始化方法效果更好。

总体上讲,方差缩放初始化可以根据每一层输入和输出的数量(TensorFlow中默认使用输入的数量),来调整初始随机权重的方差,从而帮助信号在不需要通过截断或者批量规范化等额外的方法来在网络中传递得更深。

Xavier初始化方法和它类似,只是Xavier初始化在所有层中基本一样,如果网络的层与层之间的取值范围差异很大(常见于卷积网络),每一层使用同一个方差可能就不适用了。

输入数据归一化。在训练时,减去数据集的均值,然后除以标准差。这样可以减少权重在每个方向上的拉伸,帮助神经网络更快更好地学习。保持输入的数据以方差为均值中心可以很好的实现这点。你也要保证每次测试输入采取一致的归一化方法,从而保证你的训练集能够模拟真实数据环境。

合理地缩放数据。这与归一化处理相关,但应该在归一化之前进行。比如,数据x在现实生活中的范围是[0, 140000000],可能服从tanh(x)或者 tanh(x/C)分布,其中 C为常量,用于调整曲线帮助输入数据更好的符合tanh函数的坡度部分。尤其当你输入数据地在一端或者两端无界的情况下,神经网络在 (0,1)范围里可以学习的更好。

通常情况下,不要费力去降低学习速率。SGD中学习速率衰减更常见,但是 ADAM可以更自然地处理它。如果你一定要计较细微的性能差别:在训练结束时短暂地降低学习速率,你可能会看到一个误差突然降低一点,然后再次趋于平稳。

如果你的卷积层有64或128个滤波器,这可能就有些多余了,尤其对于深度网络来说,128个滤波器真的有些多了。如果你已经有了大量的滤波器,再添加可能毫无意义。

池化(pooling)是为了最大程度保持变换的不变性。pooling本质上是使神经网络学习图像中一部分的整体特征。比如,max pooling可以使图像在卷积网络中经过位移、旋转和缩放等变换之后,仍然保持特征的不变性。

调试神经网络

如果你的神经网络不能够学习,也就是说训练时损失或者精确度不收敛,或者不能得到预期的结果。尝试以下的建议:

  • 过拟合!如果你的网络不收敛,第一件要做的事是去过拟合一个训练点,精度应该达到 100%或99.99%,或者误差接近0。如果你的神经网络不能过拟合单个数据点,那么你的架构存在严重但可能很细微的问题。如果你可以过拟合一个数据点但训练更大的数据集时不能收敛,那么可以尝试如下建议。

  • 降低学习速率。你的网络会学习的慢一些,但是它可以下降到最小值,之前无法达到是因为步长设置的太大。(想象一下寻找最小值就相当于你想抵达沟渠最低点,而步长太大导致你直接跨过了沟渠。)

  • 提高学习率。较大的学习率有助于缩短训练时间,减少反馈环路,这就意味着可以较快地预判网络模型是不是可行。不过虽然网络模型能够更快的收敛,但是结果可能不会特别理想,甚至会有较大的振荡。(我们发现对于ADAM优化器,0.001的学习率在许多实验中收效不错。)

  • 减小批处理的样本数。使用样本数为1的批处理能够获取更细粒度的权重以更新反馈,你可以使用TensorBoard查看(或者其他调试/可视化的工具。)

  • 去掉批处理规范化。在批理样本数减少到1的同时,去掉批处理规范化,可以暴露梯度消失或者梯度爆炸的问题。我们曾有一个神经网络模型在几个星期后仍旧不能收敛。直到去掉了批处理规范化,我们才意识到在第二轮迭代后所有的输出都是NaN。批处理规范化的作用如同止血时的创口贴,但是只有在你的网络模型没有错误的情况下才管用。

  • 增加批处理的样本数。较大样本的批处理,比如使用整个数据集,减少了梯度更新的方差,可以使得每轮迭代的结果更精确。换句话说,权重迭代将朝着正确的方向进行。但是,这个方法受到物理内存大小限制。通常,前面两个使用样本数为1 的批处理和除去批处理规范化的技巧比这个技巧要更有用。

  • 检查矩阵变形。较大的矩阵变形(例如改变图像的横纵轴)会破坏空间的局部性特征,给模型的学习增添了难度,因为矩阵变形也是需要学习的一部分。(自然的特征变得四分五裂。事实上自然特征的空间局部特征也是卷积神经网络之所以有效的原因。)要特别注意多图形/通道的矩阵变形;用numpy.stack()进行适当的调整。

  • 检查损失函数。如果使用的是复杂的损失函数,就先试一下简单的例如L1或者L2损失函数。我们发现L1对于异常值没那么敏感,因此受噪音数据影响较小。

  • 检查可视化。检查你的可视化工具包(matplotlib,OpenCV,等)是否调整了数值的数量级,或者有值域限制?也可以考虑使用统一的配色方案。

案例解析

为了使上述的步骤更容易理解,这里我们展示几张(通过TensorBoard)卷积神经网络做的回归实验的损失图。

首先,这个神经网络根本没有收敛

我们尝试剪裁数值值域,以防止他们超出范围:

哎呀,看这个没有光滑处理过的线是多么的杂乱。是学习率太大了吗?我们试着衰减了学习率并只用一个样本点进行训练:

你可以看到学习率发生了变化(大概在300到3000步间)。显然,学习率降的太快了。所以,我们放缓了迭代速率,效果就好些了:

你可以看我们在2000到5000步间进行了衰减。结果好些了,但是还不够,因为损失还没有降到0。

然后我们停止了学习率的衰减并且尝试了将数值压缩到更小的值域并取代了tanh函数。虽然这样损失降到了1,我们仍然不能达到过拟合

我们就是在这一步发现,去掉批处理规范化后,网络输出很快在一到两次迭代后变成NaN。于是,我们停止了批处理规范化并且把初始化改为方差标准化。这样一下就解决了问题,用一两个输入样本训练就能达到过拟合。虽然图下方的Y轴的值被剪切了,但是初始的误差在5以上,表明误差几乎下降了4个数量级。

上图的上半部分是经过光滑处理的,但是你仍可看到对测试数据很快达到了过拟合,整个训练集的损失也降到了0.01以下。而这时我们还没有衰减学习率。我们将学习率降低了一个数量级后继续训练神经网络,得到了更加好的结果:

这些结果好太多了!但是如果我们将学习率成几何级衰减而不是将训练分成两部分会怎么样呢?

如果将学习率在每一步迭代都乘以0.9995,这个结果就不那么妙了:

原因估计是因为学习率衰减的太快。用0.999995会稍微好一些,但是结果几乎跟没有衰减一样。我们从这一系列的实验中总结出,批处理规范化掩盖了由初始化不当导致的梯度爆炸,而除了最后阶段学习率的衰减,衰减的学习率对于ADAM优化器也不是很有用。伴随着批处理正规化,剪裁值域只是掩盖了真实的问题。我们还通过使用tanh激活函数对我们高方差的输入数据进行了转化。

我希望这些基本的技巧可以对你学习深度神经网络有所帮助。事情往往就是这样,简单的细节可以产生重大的影响。

相关报道:

https://pcc.cs.byu.edu/2017/10/02/practical-advice-for-building-deep-neural-networks/

大数据文摘
大数据文摘

秉承“普及数据思维,传播数据文化,助⼒产业发展”的企业⽂化,我们专注于数据领域的资讯、案例、技术,形成了“媒体+教育+⼈才服务”的良性⽣态,致⼒于打造精准数据科学社区。

入门神经网络
2
相关数据
池化技术

池化(Pooling)是卷积神经网络中的一个重要的概念,它实际上是一种形式的降采样。有多种不同形式的非线性池化函数,而其中“最大池化(Max pooling)”是最为常见的。它是将输入的图像划分为若干个矩形区域,对每个子区域输出最大值。直觉上,这种机制能够有效的原因在于,在发现一个特征之后,它的精确位置远不及它和其他特征的相对位置的关系重要。池化层会不断地减小数据的空间大小,因此参数的数量和计算量也会下降,这在一定程度上也控制了过拟合。通常来说,CNN的卷积层之间都会周期性地插入池化层。

激活函数技术

在 计算网络中, 一个节点的激活函数定义了该节点在给定的输入或输入的集合下的输出。标准的计算机芯片电路可以看作是根据输入得到"开"(1)或"关"(0)输出的数字网络激活函数。这与神经网络中的线性感知机的行为类似。 一种函数(例如 ReLU 或 S 型函数),用于对上一层的所有输入求加权和,然后生成一个输出值(通常为非线性值),并将其传递给下一层。

权重技术

线性模型中特征的系数,或深度网络中的边。训练线性模型的目标是确定每个特征的理想权重。如果权重为 0,则相应的特征对模型来说没有任何贡献。

机器学习技术

机器学习是人工智能的一个分支,是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、计算复杂性理论等多门学科。机器学习理论主要是设计和分析一些让计算机可以自动“学习”的算法。因为学习算法中涉及了大量的统计学理论,机器学习与推断统计学联系尤为密切,也被称为统计学习理论。算法设计方面,机器学习理论关注可以实现的,行之有效的学习算法。

高斯分布技术

正态分布是一个非常常见的连续概率分布。由于中心极限定理(Central Limit Theorem)的广泛应用,正态分布在统计学上非常重要。中心极限定理表明,由一组独立同分布,并且具有有限的数学期望和方差的随机变量X1,X2,X3,...Xn构成的平均随机变量Y近似的服从正态分布当n趋近于无穷。另外众多物理计量是由许多独立随机过程的和构成,因而往往也具有正态分布。

收敛技术

在数学,计算机科学和逻辑学中,收敛指的是不同的变换序列在有限的时间内达到一个结论(变换终止),并且得出的结论是独立于达到它的路径(他们是融合的)。 通俗来说,收敛通常是指在训练期间达到的一种状态,即经过一定次数的迭代之后,训练损失和验证损失在每次迭代中的变化都非常小或根本没有变化。也就是说,如果采用当前数据进行额外的训练将无法改进模型,模型即达到收敛状态。在深度学习中,损失值有时会在最终下降之前的多次迭代中保持不变或几乎保持不变,暂时形成收敛的假象。

学习率技术

在使用不同优化器(例如随机梯度下降,Adam)神经网络相关训练中,学习速率作为一个超参数控制了权重更新的幅度,以及训练的速度和精度。学习速率太大容易导致目标(代价)函数波动较大从而难以找到最优,而弱学习速率设置太小,则会导致收敛过慢耗时太长

损失函数技术

在数学优化,统计学,计量经济学,决策理论,机器学习和计算神经科学等领域,损失函数或成本函数是将一或多个变量的一个事件或值映射为可以直观地表示某种与之相关“成本”的实数的函数。

TensorFlow技术

TensorFlow是一个开源软件库,用于各种感知和语言理解任务的机器学习。目前被50个团队用于研究和生产许多Google商业产品,如语音识别、Gmail、Google 相册和搜索,其中许多产品曾使用过其前任软件DistBelief。

张量技术

张量是一个可用来表示在一些矢量、标量和其他张量之间的线性关系的多线性函数,这些线性关系的基本例子有内积、外积、线性映射以及笛卡儿积。其坐标在 维空间内,有 个分量的一种量,其中每个分量都是坐标的函数,而在坐标变换时,这些分量也依照某些规则作线性变换。称为该张量的秩或阶(与矩阵的秩和阶均无关系)。 在数学里,张量是一种几何实体,或者说广义上的“数量”。张量概念包括标量、矢量和线性算子。张量可以用坐标系统来表达,记作标量的数组,但它是定义为“不依赖于参照系的选择的”。张量在物理和工程学中很重要。例如在扩散张量成像中,表达器官对于水的在各个方向的微分透性的张量可以用来产生大脑的扫描图。工程上最重要的例子可能就是应力张量和应变张量了,它们都是二阶张量,对于一般线性材料他们之间的关系由一个四阶弹性张量来决定。

神经网络技术

(人工)神经网络是一种起源于 20 世纪 50 年代的监督式机器学习模型,那时候研究者构想了「感知器(perceptron)」的想法。这一领域的研究者通常被称为「联结主义者(Connectionist)」,因为这种模型模拟了人脑的功能。神经网络模型通常是通过反向传播算法应用梯度下降训练的。目前神经网络有两大主要类型,它们都是前馈神经网络:卷积神经网络(CNN)和循环神经网络(RNN),其中 RNN 又包含长短期记忆(LSTM)、门控循环单元(GRU)等等。深度学习是一种主要应用于神经网络帮助其取得更好结果的技术。尽管神经网络主要用于监督学习,但也有一些为无监督学习设计的变体,比如自动编码器和生成对抗网络(GAN)。

梯度下降技术

梯度下降是用于查找函数最小值的一阶迭代优化算法。 要使用梯度下降找到函数的局部最小值,可以采用与当前点的函数梯度(或近似梯度)的负值成比例的步骤。 如果采取的步骤与梯度的正值成比例,则接近该函数的局部最大值,被称为梯度上升。

卷积神经网络技术

卷积神经网路(Convolutional Neural Network, CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现。卷积神经网路由一个或多个卷积层和顶端的全连通层(对应经典的神经网路)组成,同时也包括关联权重和池化层(pooling layer)。这一结构使得卷积神经网路能够利用输入数据的二维结构。与其他深度学习结构相比,卷积神经网路在图像和语音识别方面能够给出更好的结果。这一模型也可以使用反向传播算法进行训练。相比较其他深度、前馈神经网路,卷积神经网路需要考量的参数更少,使之成为一种颇具吸引力的深度学习结构。 卷积网络是一种专门用于处理具有已知的、网格状拓扑的数据的神经网络。例如时间序列数据,它可以被认为是以一定时间间隔采样的一维网格,又如图像数据,其可以被认为是二维像素网格。

映射技术

映射指的是具有某种特殊结构的函数,或泛指类函数思想的范畴论中的态射。 逻辑和图论中也有一些不太常规的用法。其数学定义为:两个非空集合A与B间存在着对应关系f,而且对于A中的每一个元素x,B中总有有唯一的一个元素y与它对应,就这种对应为从A到B的映射,记作f:A→B。其中,y称为元素x在映射f下的象,记作:y=f(x)。x称为y关于映射f的原象*。*集合A中所有元素的象的集合称为映射f的值域,记作f(A)。同样的,在机器学习中,映射就是输入与输出之间的对应关系。

噪音技术

噪音是一个随机误差或观测变量的方差。在拟合数据的过程中,我们常见的公式$y=f(x)+\epsilon$中$\epsilon$即为噪音。 数据通常包含噪音,错误,例外或不确定性,或者不完整。 错误和噪音可能会混淆数据挖掘过程,从而导致错误模式的衍生。去除噪音是数据挖掘(data mining)或知识发现(Knowledge Discovery in Database,KDD)的一个重要步骤。

OpenCV技术

OpenCV的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉库。OpenCV是由英特尔公司发起并参与开发,以BSD许可证授权发行,可以在商业和研究领域中免费使用。OpenCV可用于开发实时的图像处理、计算机视觉以及模式识别程序。

过拟合技术

过拟合是指为了得到一致假设而使假设变得过度严格。避免过拟合是分类器设计中的一个核心任务。通常采用增大数据量和测试样本集的方法对分类器性能进行评价。

Adam优化器技术

自适应矩估计(Adam)优化器是计算每个参数的自适应学习率的另一种方法。 除了存储像Adadelta和RMSprop之类的过去平方梯度vtvt的指数衰减平均数之外,Adam也保持了过去梯度mtmt的指数衰减平均值,类似于动量:

深度神经网络技术

深度神经网络(DNN)是深度学习的一种框架,它是一种具备至少一个隐层的神经网络。与浅层神经网络类似,深度神经网络也能够为复杂非线性系统提供建模,但多出的层次为模型提供了更高的抽象层次,因而提高了模型的能力。

优化器技术

优化器基类提供了计算梯度loss的方法,并可以将梯度应用于变量。优化器里包含了实现了经典的优化算法,如梯度下降和Adagrad。 优化器是提供了一个可以使用各种优化算法的接口,可以让用户直接调用一些经典的优化算法,如梯度下降法等等。优化器(optimizers)类的基类。这个类定义了在训练模型的时候添加一个操作的API。用户基本上不会直接使用这个类,但是你会用到他的子类比如GradientDescentOptimizer, AdagradOptimizer, MomentumOptimizer(tensorflow下的优化器包)等等这些算法。

推荐文章
暂无评论
暂无评论~